Java 油漆或使用JLabel更好吗

Java 油漆或使用JLabel更好吗,java,performance,swing,paint,Java,Performance,Swing,Paint,我正在开发一个Swing应用程序,它的背景中会有一些图像。我想知道以下哪种方法更有效(或更好),或者您是否有其他建议: getGraphics().drawImage(t.getImage().getImage(),i*16,j*16,this) 或 编辑: 这就是事情发生的地方: for (int j = 0; j < 3; j++) { for (int i = 0; i < 3; i++) { Tile t = map.g

我正在开发一个Swing应用程序,它的背景中会有一些图像。我想知道以下哪种方法更有效(或更好),或者您是否有其他建议:

getGraphics().drawImage(t.getImage().getImage(),i*16,j*16,this)

编辑:

这就是事情发生的地方:

for (int j = 0; j < 3; j++) {
            for (int i = 0; i < 3; i++) {
                Tile t = map.getTiles()[j][i];
                if (t != null) {
                    // Draw it somehow.
                }
            }
        }
for(int j=0;j<3;j++){
对于(int i=0;i<3;i++){
Tile t=map.getTiles()[j][i];
如果(t!=null){
//不知怎么画出来的。
}
}
}

使用JLabel将占用容器中的空间

而在容器上绘图不会占用容器的空间。

关于:

getGraphics().drawImage(t.getImage().getImage(), i * 16, j * 16, this);
JLabel tile = new JLabel(t.getImage());
tile.setBounds(i * 16, j * 16, t.getImage().getIconWidth(), t.getImage().getIconHeight());
add(tile);
切勿使用通过在组件上调用
getGraphics()
获得的图形对象进行绘制,因为这样获得的图形对象将是短暂的,并且图形可能会变得不稳定。要了解我的意思,请尝试使用您的技术,然后在创建GUI之后,最小化并恢复它,您可能会看到部分或全部图像消失。相反,您应该使用给定的图形对象在JPanel(或其他JComponent派生类)的
paintComponent(…)
方法中绘制

另外,不要在每次绘制图像时都读取图像,因为这样做会导致程序不必要的速度减慢。相反,如果图像不是很大,则在程序启动时立即读取它们,将它们放入BuffereImage或ImageIcon变量中(取决于需要),并在应用程序中需要时和需要时使用它们


关于:

getGraphics().drawImage(t.getImage().getImage(), i * 16, j * 16, this);
JLabel tile = new JLabel(t.getImage());
tile.setBounds(i * 16, j * 16, t.getImage().getIconWidth(), t.getImage().getIconHeight());
add(tile);
这很好,除了
setBounds(…)
部分表明程序没有正确使用布局管理器。让JLabel及其ImageIcon设置自己的首选大小,并让布局管理器在设置组件和调整GUI大小时使用此设置

请注意,您可以将JLabel的布局管理器提供给它们,并向它们添加组件,就像它们是JPanel一样。主要区别在于jlabel在默认情况下不是不透明的


关于哪一个更好,使用JLabel将图像或图形保存在
paintComponent(…)
中:通常取决于图像是否必须调整大小以适应组件。如果是这样,请绘制JPanel的
paintComponent(…)
。否则,请使用JLabel


编辑
根据您的评论:


关于第二部分,我没有使用布局管理器

这样,您的GUI就有可能在不同的操作系统上变得丑陋,并且有可能无法很好地扩展。布局管理器是Swing编程最强大的方面之一,如果您使用它们,您的GUI将更易于编码、更新、增强,并在其他系统上工作良好

关于第二部分,我要传递给paintComponent()的图形对象是什么

您不会将任何图形对象传递到JPanel的
paintComponent(Graphics g)
。这是JVM的重绘管理器根据您的建议(通过调用
repaint()
)或操作系统的建议调用的方法

最后,你是说我使用两种选择中的哪一种并不重要吗

不,我没那么说。请重新阅读我的建议就在这个编辑上面


编辑2
关键环节:

  • :用于螺母和螺栓
  • :了解血淋淋的细节

编辑3
对于平铺贴图,我会将图像图标用于平铺图像,然后将它们显示在一个jlabel网格中。这样,交换磁贴就像在感兴趣的JLabel上调用
setIcon(nextIcon)
一样简单

例如,请查看垃圾神和我对这个问题的回答:

关于:

getGraphics().drawImage(t.getImage().getImage(), i * 16, j * 16, this);
JLabel tile = new JLabel(t.getImage());
tile.setBounds(i * 16, j * 16, t.getImage().getIconWidth(), t.getImage().getIconHeight());
add(tile);

至于布局经理,我有一个很好的理由。我用布局管理器制作了许多GUI,但这一个很特别;)

这样做的风险由你自己承担,我敢打赌你的推理是错误的


编辑4

我之所以不使用布局管理器,是因为我试图在Swing中制作一个小型RPG游戏

然后,最好将平铺保存在使用GridLayout的容器中,并且该容器可能保存在JScrollPane中,以便您可以向任何方向滚动。然后,您可以让精灵位于JLabel中(通过为它们提供适当的布局),或者使用JLayeredPane位于顶部

我不希望任何评论告诉我我不能或不应该,因为如果这是不可能的,我会自己去发现

  • 当然,我们不是来告诉你你不能做任何事情,但是你不能规定我们应该或不应该告诉你什么。你们来这里征求我们的意见,我们有义务告诉你们我们认为最有效的方法。你有权听从我们的建议,因为这是你的节目,但同样,你不能规定我们能告诉你什么或不能告诉你什么,除了你不应该容忍或允许粗鲁或无礼的言论(如果你看到这一点,请标记主持人,他们会处理)

我认为(不确定)使用
JLable
更安全,因为它将使用已初始化的线程绘制图像
JLable
@user251414:不,这两种技术都没有任何线程安全问题。然而,每当要绘制图像时,总是在中重新读取图像是错误的,但这不是一个线程安全问题,而是一个降低程序速度的问题。@HovercraftFullOfEels关于重新绘制图像的
的观点很好,所以我错了。谢谢,伙计:)你确定不能将组件放在JLabel上吗?即使您给它一个像样的布局管理器,您也可以将兄弟组件放在JLabel之上,但许多布局管理器会限制这一点!现在不要