设置JFrame背景,为什么这不起作用?



我想为我的jFrame设置一个背景,我使用下面的代码:

import java.awt.Graphics;
import java.awt.Image;
import java.awt.MediaTracker;
import java.awt.Toolkit;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class DemoBackgroundSwing extends JPanel {
  private Image img;
  public DemoBackgroundSwing() {
      System.out.println("done");
    img = Toolkit.getDefaultToolkit().createImage("red.png");
    System.out.println("done");
    loadImage(img);
    System.out.println("done");
  }
  private void loadImage(Image img) {
    try {
      MediaTracker track = new MediaTracker(this);
      track.addImage(img, 0);
      track.waitForID(0);
    } catch (InterruptedException e) {
      e.printStackTrace();
    }
  }
  protected void paintComponent(Graphics g) {
    setOpaque(false);
    System.out.println("done");
    g.drawImage(img, 0, 0, null);
    super.paintComponent(g);
  }
  public static void main(String... argv) {
    JFrame frame = new JFrame("Demo Background Image");
    DemoBackgroundSwing back = new DemoBackgroundSwing();
    System.out.println("done");
    frame.getContentPane().add(back);
    frame.setSize(400, 287);
    frame.setVisible(true);
  }
}

当我执行它时,在系统输出中我有5个"完成"。这意味着所有的任务都被执行了。我不明白哪里出错了。请救救我!

打印已加载图像的宽度,如果为-1则表示图像未正确加载。

img = Toolkit.getDefaultToolkit().createImage("red.png");
System.out.println(img.getWidth(null)); // check what it prints

值得一读Java教程使用getResource加载图像


您可以根据图像位置尝试任何一个。

// Read from same package 
ImageIO.read(getClass().getResourceAsStream("c.png"));
// Read from images folder parallel to src in your project
ImageIO.read(new File("images/c.jpg"));
// Read from src/images folder
ImageIO.read(getClass().getResource("/images/c.png"))
// Read from src/images folder
ImageIO.read(getClass().getResourceAsStream("/images/c.png"))

阅读更多…


几点:

  • 在重写paintComponent()方法的第一行调用super.paintComponent(g);

  • 使用ImageIO代替Toolkit加载图像

  • 使用frame.pack()代替frame.setSize(),根据组件的首选尺寸适合组件

  • 重写getPreferredSize()以设置自定义绘画时JPanel的首选大小。

  • 使用swingutility . invokelater()或EventQueue.invokeLater()来确保EDT被正确初始化。

    阅读更多

    • 为什么要使用swingutility。invokeLater in main method?

    • SwingUtilities.invokeLater

    • 我们应该使用EventQueue吗?invokeLater用于Java桌面应用程序中的任何GUI更新?

最新更新