关于:
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 一样。主要区别在于 JLabels 默认情况下不是不透明的。
关于哪个更好,使用 JLabel 保存图像或在paintComponent(...)
: 中绘制通常取决于图像是否必须调整大小以适合组件。如果是这样,请绘制 JPanel 的paintComponent(...)
. 否则使用 JLabel。
编辑
根据您的评论:
关于第二部分,我没有使用布局管理器。
那么您的 GUI 在不同的操作系统上可能会变得丑陋,并且可能无法很好地扩展。布局管理器是 Swing 编程最强大的方面之一,如果您使用它们,您的 GUI 将更容易编码、更新、增强并在其他系统上运行良好。
关于第二部分,我将什么 Graphics 对象传递给 paintComponent()?
您不会将任何 Graphics 对象传递给 JPanel 的paintComponent(Graphics g)
. 这是 JVM 的重绘管理器根据您的建议(通过调用repaint()
)或操作系统的建议调用的方法。
最后,您是说我使用这两个选项中的哪一个并不重要?
不,我没有那样说。请重新阅读我在此编辑上方的建议。
编辑 2 个
关键链接:
编辑 3
对于瓦片地图,我将 ImageIcons 用于瓦片图像,然后将它们显示在 JLabels 网格中。这样,交换图块就像调用setIcon(nextIcon)
感兴趣的 JLabel 一样简单。
例如,请参阅 TrashGod 和我对这个问题的回答:jlabel images array。
关于:
至于布局管理器,我有充分的理由。我用布局管理器制作了许多 GUI,但这个很特别;)。
这样做需要您自担风险,我愿意打赌您对此的推理是不正确的。
编辑 4
我不使用布局管理器的原因是因为我试图在 Swing 中制作一个小型 RPG 游戏。
然后,这些图块最好保存在使用 GridLayout 的容器中,并且该容器可能保存在 JScrollPane 中,以便您可以向任何方向滚动。然后,您可以让您的精灵位于 JLabels 中(通过为它们提供适当的布局),或者通过使用 JLayeredPane 在顶部。
我不希望任何评论告诉我我不能或我不应该,因为如果不可能,我会自己找出来。
- 当然,我们不是来告诉你你不能做任何事情,但否则你不能规定我们应该或不应该告诉你什么。您来这里寻求我们的建议,我们有义务告诉您我们认为最有效的方法。你有权听从我们的建议,因为这是你的节目,但同样,你不能规定我们可以或不能告诉你什么,除了你不应该容忍或允许粗鲁或冒犯性的陈述(标记版主如果你看到这个,他们会处理的)。