【问题标题】:paintComponent clears the JPanel when paint an imagepaintComponent 在绘制图像时清除 JPanel
【发布时间】:2016-12-19 19:12:55
【问题描述】:

我有这个代码:

package game;

import java.awt.Graphics;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;

public class Draw {

Object block;

public Draw(JFrame frame, Object object) {
    this.block = object;

    JPanel pane = new JPanel() {
        private static final long serialVersionUID = 3869097656854760151L;

        @Override
        protected void paintComponent(Graphics g) {
            super.paintComponent(g);
            try {
                g.drawImage(ImageIO.read(new File(object.getTexture())), object.getX(), object.getY(), object.getWidth(),
                        object.getHeight(), null);
            } catch (IOException e) {
                System.err.println("Image '" + object.getTexture() + "' could not be found!");
            }
        }
    };

    frame.add(pane);
}
}

我在这里给班级打电话:

package game;

import javax.swing.JFrame;

public class Frame {

private final int X_SIZE = new vena.util.Computer().screenWidth();
private final int Y_SIZE = new vena.util.Computer().screenHeight();

public Frame() {
    JFrame f = new vena.util.Frame().frame("2D Game", X_SIZE - X_SIZE   /   5,  Y_SIZE - Y_SIZE / 5, true, false, false,
            "res/icon.png");

    new Draw(f, new Object(0, 0, 100, 100, "grass"));
    new Draw(f, new Object(100, 0, 100, 100, "grass"));

    f.setVisible(true);
}

public static void main(String[] args) {
    new Frame();
}
}

当我调用图像时它会呈现

new Draw(f, new Object(0, 0, 100, 100, "grass"));

但是当我再次调用图像时,在它旁边

new Draw(f, new Object(100, 0, 100, 100, "grass"));

它只渲染第二个图像,并删除第一个。我注意到当我在 paintComponent 方法中调用 g.drawImage() 两次时,不会发生这种情况。有没有办法让我可以在不清除 JPanel 的情况下多次调用 Draw 类?

【问题讨论】:

  • 您似乎从未为您的框架设置layout。这意味着第二个面板在添加时将简单地替换第一个面板。使用适当的布局来根据需要放置两个面板。
  • 另外,你不应该在你的paint方法中调用ImageIO.read。这将有可怕的表现。在创建对象时读取图像,然后在每次调用 paintComponent 时重复使用相同的实例。

标签: java swing jframe jpanel paintcomponent


【解决方案1】:

框架内容窗格的默认布局管理器是 BorderLayout。当您将组件添加到 BorderLayout 并且您未指定约束时,组件将转到 CENTER。 CENTER 中只能显示最后添加的组件。

如果您希望框架上有多个组件,则可以更改布局管理器。试试

f.setLayout( new FlowLayout() );

看看有什么不同。

我注意到,当我在 paintComponent 方法中调用 g.drawImage() 两次时,不会发生这种情况。

是的,如果您尝试在框架上的特定位置绘制图像,那么您真的应该重写 paintComponent() 来绘制每个图像。

【讨论】:

  • 我这样做了,现在它只是在框架的中心顶部绘制了一个小黑框。知道为什么吗?
  • @Vena FlowLayout 尊重面板的首选大小(基本上是 10x10,因为您没有向面板添加任何组件)。所以需要覆盖面板的getPreferredSize()才能返回图片的大小。或者更简单的解决方案是仅使用带有 ImageIcon 的 JLabel 来显示您的图像。不需要自定义面板。我真的不知道你的要求是什么。
  • 我应该把覆盖的 getPreferredSize 放在哪里?另外,您的意思是我应该创建一个 ImageIcon,将该 ImageIcon 设置为 JLabel,将 JLabel 放在 JPanel 上,然后将 JPanel 放在 JFrame 上?这不是更难更费时间吗?
  • @Vena,是的,这就是我的意思。不,这并不难,因为您使用的是 JDK 的类,而不是通过尝试在面板上绘制图像来重新发明轮子。阅读 How to Use Icons 上的 Swing 教程部分,了解更多信息和工作示例。
  • 嗯。我用 ImageIcon 作为参数创建了一个新的 JLabel。然后我将它的大小设置为传递的对象的大小,以及位置。之后我做了'new Frame().p.add(label);',但它不起作用。 (p 是一个带有 FlowLayout 的 JPanel)。框架没有出现,除非我注释掉'new Frame().p.add(label);'。知道为什么吗?
猜你喜欢
  • 2021-04-14
  • 1970-01-01
  • 1970-01-01
  • 2014-10-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-10-17
  • 2017-03-10
相关资源
最近更新 更多