如何将图像添加到JPanel?
我有一个JPanel ,我想添加我在飞行中生成的JPEG和PNG图像。
我在Swing教程中看到的所有示例,特别是Swing示例中的示例都使用了ImageIcon
。
我生成这些图像作为字节数组,他们通常比他们在例子中使用的通用图标,在640×480。
- 在使用ImageIcon类来显示一个尺寸在JPanel中的图像时,是否有任何(性能或其他)问题?
- 通常的做法是什么?
- 如何在不使用ImageIcon类的情况下将图像添加到JPanel?
编辑 :对教程和API的更仔细的检查表明,您不能直接将ImageIcon添加到JPanel。 相反,他们通过将图像设置为JLabel的图标来达到相同的效果。 这只是感觉不对
以下是我如何做到这一点(有关如何加载图像的更多信息):
import java.awt.Graphics; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.logging.Level; import java.util.logging.Logger; import javax.imageio.ImageIO; import javax.swing.JPanel; public class ImagePanel extends JPanel{ private BufferedImage image; public ImagePanel() { try { image = ImageIO.read(new File("image name and path")); } catch (IOException ex) { // handle exception... } } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); g.drawImage(image, 0, 0, this); // see javadoc for more info on the parameters } }
如果您使用JPanel,那么可能与Swing合作。 尝试这个:
BufferedImage myPicture = ImageIO.read(new File("path-to-file")); JLabel picLabel = new JLabel(new ImageIcon(myPicture)); add(picLabel);
图像现在是一个摆动组件。 它像任何其他组件一样受制于布局条件。
我认为不需要任何东西的子类。 只需使用Jlabel。 您可以将图像设置为Jlabel。 所以,调整Jlabel的大小,然后用图像填充它。 没关系。 这是我的方式。
弗雷德·哈斯拉姆的方式正常工作。 虽然我有麻烦的文件path,因为我想引用我的jar中的图像。 为了做到这一点,我使用了:
BufferedImage wPic = ImageIO.read(this.getClass().getResource("snow.png")); JLabel wIcon = new JLabel(new ImageIcon(wPic));
由于我只需要使用这种方法加载的有限数量(大约10个)图像,所以它工作得很好。 它获取文件,而不必具有正确的相对文件path。
您可以通过使用免费的SwingX库中的JXImagePanel类来完全避免自己的Component子类的滚动。
下载
JLabel imgLabel = new JLabel(new ImageIcon("path_to_image.png"));
你可以创buildJPanel的子类 – 这里是我的ImagePanel的一个提取,它将图像放置在5个位置中的任何一个上面/左边,上面/右边,中间/中间,下面/左边或者下面/右边:
protected void paintComponent(Graphics gc) { super.paintComponent(gc); Dimension cs=getSize(); // component size gc=gc.create(); gc.clipRect(insets.left,insets.top,(cs.width-insets.left-insets.right),(cs.height-insets.top-insets.bottom)); if(mmImage!=null) { gc.drawImage(mmImage,(((cs.width-mmSize.width)/2) +mmHrzShift),(((cs.height-mmSize.height)/2) +mmVrtShift),null); } if(tlImage!=null) { gc.drawImage(tlImage,(insets.left +tlHrzShift),(insets.top +tlVrtShift),null); } if(trImage!=null) { gc.drawImage(trImage,(cs.width-insets.right-trSize.width+trHrzShift),(insets.top +trVrtShift),null); } if(blImage!=null) { gc.drawImage(blImage,(insets.left +blHrzShift),(cs.height-insets.bottom-blSize.height+blVrtShift),null); } if(brImage!=null) { gc.drawImage(brImage,(cs.width-insets.right-brSize.width+brHrzShift),(cs.height-insets.bottom-brSize.height+brVrtShift),null); } }
- 不应该有任何问题(除了任何一般的问题,你可能有非常大的图像)。
- 如果您正在讨论将多个图像添加到单个面板,我会使用
ImageIcon
。 对于单个图像,我会考虑制作一个JPanel
的自定义子类,并重写其paintComponent
方法来绘制图像。 - (见2)
JPanel
几乎总是子类的错误类。 为什么你不能JComponent
?
ImageIcon
有一个小问题,构造函数会阻止读取图像。 当从应用程序jar加载时,不是一个真正的问题,但也许如果你有可能通过networking连接阅读。 有很多使用MediaTracker
, ImageObserver
和朋友的AWT时代例子,即使在JDK演示中也是如此。
我正在做一个非常类似的事情,在我正在进行的一个私人项目中。 到目前为止,我已经生成的图像没有任何问题(内存除外),可以很快显示,没有任何性能问题。
覆盖JPanel子类的paint方法是矫枉过正的,需要做更多的工作。
我这样做的方式是:
Class MapIcon implements Icon {...}
要么
Class MapIcon extends ImageIcon {...}
你用来生成图像的代码将在这个类中。 我使用一个BufferedImage来绘制paintIcon()被调用时,使用g.drawImvge(bufferedImage); 这可以减less在生成图像时完成的闪烁量,并且可以对其进行编程。
接下来我扩展JLabel:
Class MapLabel extends Scrollable, MouseMotionListener {...}
这是因为我想把我的图像放在滚动窗格上,即显示图像的一部分,并让用户根据需要滚动。
那么我使用JScrollPane来保存仅包含MapIcon的MapLabel。
MapIcon map = new MapIcon (); MapLabel mapLabel = new MapLabel (map); JScrollPane scrollPane = new JScrollPane(); scrollPane.getViewport ().add (mapLabel);
但是对于你的场景(每次只显示整个图像)。 您需要将MapLabel添加到顶层JPanel,并确保将它们全部放大到图像的全部大小(通过重写GetPreferredSize())。
这个答案是@ shawalli的答案的补充…
我也想在我的jar中引用一个图片,但是我没有使用BufferedImage,而是简单地做了这个:
JPanel jPanel = new JPanel(); jPanel.add(new JLabel(new ImageIcon(getClass().getClassLoader().getResource("resourcehttp://img.dovov.compolygon.jpg"))));
在你的项目目录中创build一个源文件夹,在这种情况下,我把它叫做Images。
JFrame snakeFrame = new JFrame(); snakeFrame.setBounds(100, 200, 800, 800); snakeFrame.setVisible(true); snakeFrame.add(new JLabel(new ImageIcon("Images/Snake.png"))); snakeFrame.pack();