我正在开发一个Swing应用程序,它将在后台显示一些图像。我想知道以下哪种方式更有效(或更好),或者如果你有另一种方法建议:
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);
修改
这就是事情发生的地方:
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.
}
}
}
答案 0 :(得分:6)
关于:
getGraphics().drawImage(t.getImage().getImage(), i * 16, j * 16, this);
您永远不应该使用通过在组件上调用getGraphics()
获得的Graphics对象进行绘制,因为这样获得的Graphics对象将是短暂的,并且您的绘图可能会变得不稳定。要了解我的意思,请尝试使用您的技术,然后在创建GUI后,最小化并恢复它,您可能会看到部分或全部图像消失。相反,您应该使用给定的Graphics对象在JPanel(或其他JComponent派生类)的paintComponent(...)
方法内部绘制。
每次想要绘制时都不要读取图像,因为这样做会导致程序不必要的减慢。相反,如果图像不是很大,请在程序启动时一次性读取它们,将它们放入BufferedImage或ImageIcon变量(根据需要),并在应用程序需要的时间和地点使用它们。
关于:
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将更容易编码,更新,增强,并在其他系统上运行良好。
关于第二部分,我将什么Graphics对象传递给paintComponent()?
您不会将任何Graphics对象传递到JPanel的paintComponent(Graphics g)
。这是JVM重绘管理器在您的建议(通过调用repaint()
)或操作系统的建议时调用的方法。
最后,你是说我使用的两个选项中的哪一个并不重要?
不,我没有这么说。请在此编辑上方重新阅读我的建议。
编辑2
主要链接:
编辑3
对于平铺贴图,我将使用ImageIcons作为我的平铺图像,然后将它们显示在JLabel的网格中。这样,交换切片与在感兴趣的JLabel上调用setIcon(nextIcon)
一样简单。
例如,请参阅TrashGod以及我对此问题的回答:jlabel images array。
关于:
就布局经理而言,我有充分的理由。我已经使用布局管理器制作了许多GUI,但这个是特殊的;)。
这样做需要您自担风险,并且我愿意下赌啤酒,因为您的推理不正确。
编辑4
我没有使用布局管理器的原因是因为我想在Swing中制作一个小型RPG游戏。
然后,tile最好保存在使用GridLayout的容器中,并且该容器可能保存在JScrollPane中,以便您可以向任何方向滚动。然后,您可以让您的精灵坐在JLabel中(通过给它们一个合适的布局),或者使用JLayeredPane。
我不希望任何评论告诉我,我不能或不应该,因为如果不可能,我会自己找到。
答案 1 :(得分:0)
使用JLabel会占用容器中的空间。
虽然在容器上绘图不会占用容器的空间。