如何在 JPanel 中使用 paint 方法

How to use paint method in a JPanel

我正在 Java 中的老虎机上工作,到目前为止,我创建了一个可以随机生成两张图片的按钮。我的代码可以编译,但是当我 运行 它时,我放入 paint 方法中的所有内容都没有显示出来。我有什么想念的吗?感谢您的帮助,这是我的一些代码。

    public void paint(Graphics g) {
        super.paintComponents(g);
        g.drawString("Int 1 is" + int1,30,30);
        g.drawString("Int 2 is" + int2,30,80);
        switch (int1) {
            case 0:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img, 300, 500, this);
                break;
            case 1:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img2,300,500,this);
                break;
            case 2:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img3,300,500,this);
                break;
            case 3:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img4,300,500,this);
                break;
            case 4:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img5,300,500,this);
                break;
            case 5:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img6,300,500,this);
                break;
            case 6:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img7,300,500,this);
                break;
            case 7:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img8,300,500,this);
                break;
            case 8:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img9,300,500,this);
                break;
            case 9:
                g.setColor(Color.white);
                g.fillRect(300,300,300,500);
                g.drawImage(img10,300,500,this);
                break;
        }
        switch (int2) {
            case 0:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img, 800, 500, this);
                break;
            case 1:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img2,800,500,this);
                break;
            case 2:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img3,800,500,this);
                break;
            case 3:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img4,800,500,this);
                break;
            case 4:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img5,800,500,this);
                break;
            case 5:
\               g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img6,800,500,this);
                break;
            case 6:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img7,800,500,this);
                break;
            case 7:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img8,800,500,this);
                break;
            case 8:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img9,800,500,this);
                break;
            case 9:
                g.setColor(Color.white);
                g.fillRect(300,300,800,500);
                g.drawImage(img10,800,500,this);
                break;
        }
        this.setVisible(true);
    }

问题:

  • 您正在直接在 JFrame 中绘图 -- 不要这样做,因为您可能会弄乱 JFrame 图形。
  • 你重写了 paint 方法并调用了 super.paintComponents(...) 方法,这又是一件危险的事情,而且是永远不应该做的事情。

相反,您可以在 JPanel 的 paintComponent(...) 方法中绘制并在其中调用正确的 super.paintComponent(...) 方法,如Swing painting tutorials,但何必呢。创建一个 ImageIcons 数组并在随机 select 从数组或 ArrayList 中随机 selecting 一个 Icon 后简单地调用 setIcon(...) on 3(或者你需要的任何数量)JLabel 会容易得多。

此外,永远不要这样做:

try {

  // .... some code here

} catch (IOException e) {

}

至少打印出 catch 块中的堆栈跟踪,以便您可以在发生任何 IO 异常时识别它们:

try {

  // .... some code here

} catch (IOException e) {
  e.printStackTrace(); // ****** added ********    
}

例如,以下代码将生成此 GUI:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import javax.imageio.ImageIO;
import javax.swing.*;

@SuppressWarnings("serial")
// extend JPanel, not JFrame as it gives the class more flexibility as to where to use
public class ShowRandomImages extends JPanel {
   // images from Andrew Thompson's example image page,
   // 
   private static final String IMAGE_SHEET_PATH = "http://i.stack.imgur.com/memI0.png";
   // how many JLabels to show in a row
   private static final int LABEL_COUNT = 3;
   // need to get subimages from image sheet. There are 6 columns in the sheet
   private static final int IMAGE_COLUMNS = 6;
   // array of JLabel
   private JLabel[] labels = new JLabel[LABEL_COUNT];
   // hold all the images as ImageIcons read in
   private List<Icon> imageIconList = new ArrayList<>();
   // to randomize the images
   private Random random = new Random();

   // pass the ImageIcon List into this class
   public ShowRandomImages(List<Icon> iconList) {
      this.imageIconList = iconList;
      // jpanel hold row of image-displaying JLabels
      JPanel labelHolderPanel = new JPanel(new GridLayout(1, 0, 5, 0));
      for (int i = 0; i < labels.length; i++) { // create all JLabels in array
         labels[i] = new JLabel();
         labels[i].setBorder(BorderFactory.createLineBorder(Color.DARK_GRAY));
         labels[i].setHorizontalAlignment(SwingConstants.CENTER); // center the icon
         labels[i].setIcon(getRandomIcon()); // initialize with a random image
         labelHolderPanel.add(labels[i]); // add to holder JPanel
      }

      // panel to hold button at bottom
      JPanel bottomPanel = new JPanel();
      // button uses an AbstractAction rather than an ActionListener
      bottomPanel.add(new JButton(new ShowRandomIconAction("Show Random Image")));

      setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
      setLayout(new BorderLayout());
      add(labelHolderPanel, BorderLayout.CENTER);
      add(bottomPanel, BorderLayout.PAGE_END);
   }

   private Icon getRandomIcon() {
      int randomIndex = random.nextInt(imageIconList.size());
      return imageIconList.get(randomIndex);
   }

   private class ShowRandomIconAction extends AbstractAction {
      public ShowRandomIconAction(String name) {
         super(name);
         int mnemonic = (int) name.charAt(0);
         putValue(MNEMONIC_KEY, mnemonic);
      }

      @Override
      public void actionPerformed(ActionEvent e) {
         for (JLabel jLabel : labels) {
            jLabel.setIcon(getRandomIcon());
         }
      }
   }

   private static void createAndShowGui(List<Icon> imageIconList) {
      ShowRandomImages mainPanel = new ShowRandomImages(imageIconList);

      JFrame frame = new JFrame("ShowRandomImages");
      frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      try {
         final List<Icon> iconList = getImages();
         SwingUtilities.invokeLater(new Runnable() {
            public void run() {
               createAndShowGui(iconList);
            }
         });
      } catch (IOException e) {
         e.printStackTrace();
         System.exit(-1);
      }
   }

   // read in image sheet and extract sub-images from it
   private static List<Icon> getImages() throws IOException {
      List<Icon> iconList = new ArrayList<>();
      URL imageUrl = new URL(IMAGE_SHEET_PATH);
      BufferedImage imageSheet = ImageIO.read(imageUrl);
      for (int i = 0; i < IMAGE_COLUMNS; i++) {
         int x = (int) ((double) i * imageSheet.getWidth() / IMAGE_COLUMNS);
         int y = 0;
         int w = imageSheet.getWidth() / IMAGE_COLUMNS;
         int h = imageSheet.getHeight() / 2;

         BufferedImage subImage = imageSheet.getSubimage(x, y, w, h);
         iconList.add(new ImageIcon(subImage));
      }
      return iconList;
   }
}

否则如果你一定要用画图的方式展示图片,我推荐:

  • 创建一个扩展 class 的 JPanel,它只显示一个图像,比如名为 ImageDisplayPanel。如果您需要显示 2 张图片,您将提供 class 其中 2 张。
  • 传入一个List<BufferedImage>
  • 给它一个displayRandomImage()方法
  • 在此方法中,select 从列表中随机选择一张图像,并为该图像设置一个 BufferedImage 字段,然后调用 repaint()。
  • 如果不为空,DrawImagePanel 的 paintComponent 方法将绘制该字段持有的图像。
  • 在主 GUI 中,根据需要在 2 或 3 个图像 JPanel 上调用此方法。