【问题标题】:How to paint a JFrame at creation?如何在创建时绘制 JFrame?
【发布时间】:2014-09-04 14:49:16
【问题描述】:

我正在尝试将背景图像绘制到 JFrame 上,以用于我正在制作的生活模拟游戏。这是我的代码:

public class MainFrame extends JFrame  {
 //creates image variables
Image background;

 public MainFrame(int w, int h) {
    //creates new JFrame and sets some other properties
    super("Life Simulation");
    setLayout(new FlowLayout());
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setSize(new Dimension(w,h));
    //creates images
    background = Toolkit.getDefaultToolkit().createImage("img/default.jpg");
    this.repaint();
    setVisible(true);
}
 @Override
 public void paint(Graphics g) {
         super.paint(g);
         Graphics2D g2d = (Graphics2D) g;
         g.drawImage(background,0,0,null);
     }
}

我尝试在将其设置为可见之前重新绘制它,但没有。当我从 main 方法启动程序时,JFrame 只是空白。但是,如果我稍微调整它的大小,就会调用paint方法并绘制背景图像。

这是我的主要方法:

public class Main {

public static void main(String[] args) {
    MainFrame frame = new MainFrame(1080,720);
    frame.repaint(); //tried invoking paint() here as well but again to no avail
}

}

编辑:我相信还值得一提的是,我事先几乎没有使用 paint() 或其任何变体的经验,只知道它应该如何实现及其功能。

【问题讨论】:

  • 尝试覆盖paintComponent 而不仅仅是paint。让我知道会发生什么。
  • 看看第二个答案。看看是否有帮助。 stackoverflow.com/questions/1097366/…
  • @Takendarkk paintComponentJFrame 的未定义方法,根据我在尝试覆盖此类方法时遇到的错误。而@imtheman,这个结果也无济于事,因为我没有删除任何组件。
  • 组件显示前无需调用repaint()。简单地显示它(使用setVisible(true))将导致它被绘制。我相信@Takendarkk 关于您需要做出的改变是正确的(如果是这样的话,应该将该评论作为答案)。
  • 啊,我认为您需要在 rootPane 或 contentPane 上执行此操作,可能是 contentPane。

标签: java jframe paint


【解决方案1】:

哦,我想强调在调用drawImage 方法时提供适当的ImageObserver 对象的重要性。我建议不要通过null,而是通过this

g.drawImage(background, 0, 0, this);

您可以通过Toolkit.createImage 异步加载图像时了解importance of specifying an ImageObserver

旁白:虽然没有为 JFrame 定义 paintComponent,但我建议避免覆盖 JFrame 的 paint 方法。相反,您可以创建一个可重用的 ImagePanel 类,或者只使用一个匿名类,然后使用它来设置 JFrame 的内容窗格。

这是一个 ImagePanel 类的示例:

class ImagePanel extends JPanel {
    private Image image;

    public ImagePanel(Image image) {
        this.image = image;
    }

    @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, this);
    }
}

或者如果您更喜欢匿名类:

setContentPane(new JPanel() {
    @Override protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, 0, 0, this);
    }
});

【讨论】:

  • 如果我不能直接将图像绘制到 JFrame 上,我也在考虑将其作为备用选项。好消息是现在绘画是自动发生的,但整个图像不会绘画,只有一个像素。任何想法为什么?
  • 图片使用Toolkit.createImage异步加载。很可能图像还没有完全加载。您是否尝试在您的paint 方法中调用g.drawImage 时指定this 代替null?或者,您可以使用ImageIO.read 同步加载图像。
  • 是的,我确实将this 更改为null。事实上,这似乎是首先自动调用paintComponent的原因,就像在此之前我一直遇到我原来的问题一样。
  • 编辑:奇怪的是,它适用于匿名类,但不是相反,哈哈!我在我原来的 JFrame 构造函数内部设置了这个匿名类,它工作正常。我很想知道为什么它特别像这样工作而不是任何其他方式虽然@sbat
  • 旁白:我肯定会 +1,但你需要 15 个代表才能做到这一点。该死的:/
猜你喜欢
  • 2012-04-17
  • 1970-01-01
  • 2020-09-02
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 2017-10-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多