我有一个JFrame。它使用JPanel作为其内容窗格,并且JPanel使用GridBagLayout作为其布局管理器。 JPanel包含两个项目:一个按钮和另一个JPanel。在程序启动时,使用ImageIO.read(...)将图像从文件加载到最低级JPanel中作为BufferedImage。这里是一切都会发生的地方。GridBagLayout不调整图像加载大小
图像加载正确,我可以在屏幕上看到它的一个小角落(调试器中指定的14px方块)。我无法弄清楚这将导致布局增长,并将整个图像放在屏幕上最低级别的JPanel上。调试器中的图像显示500px的正确大小。 CardImagePanel的首选大小与图像大小相同。但是除非我使用setSize(...)手动设置CardImagePanel大小,否则布局将不会考虑首选大小,我相当肯定这对GBL不应该是必需的。
我曾尝试在整个程序中对每个JFrame,JPanel,布局,网格包,图像等进行revalidate()和repaint()调用,并且找不到正确的位置或时间来调用它们让这件事情起作用。目前我一直试图让图像加载不正确,并使用按钮强制重新验证和重绘,但即使这个显式调用也没有做任何事情。
我正在失去理智,我会尽一切努力让这件事情起作用。
这里是我的整个愚蠢的事情的所有代码(减去进口和包装规格
P1s1.java:
public class P1s1 {
public static void main(String[] args) {
// TODO code application logic here
build();
}
public static void build()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(new Dimension(640, 480));
frame.setContentPane(new GuiPanel(frame));
frame.setVisible(true);
}
}
GuiPanel.java:
public class GuiPanel extends JPanel {
JFrame parentFrame;
JButton imageLoaderButton;
CardImagePanel cardImagePanel;
LayoutManager layout;
GridBagLayout gridBagLayout;
GridBagConstraints constraints;
public GuiPanel(JFrame frame)
{
parentFrame = frame;
constraints = new GridBagConstraints();
gridBagLayout = new GridBagLayout();
layout = gridBagLayout;
this.setLayout(layout);
this.setBorder(BorderFactory.createLineBorder(Color.black));
setupImageLoaderButton(imageLoaderButton);
cardImagePanel = new CardImagePanel();
this.add(cardImagePanel);
}
private void setupImageLoaderButton(JButton button)
{
button = new JButton("Click to load image!");
ActionListener imageLoaderListener;
imageLoaderListener = new ActionListener() {
@Override
public void actionPerformed(ActionEvent ae) {
System.out.println("Button clicked.");
cardImagePanel.revalidate();
cardImagePanel.repaint();
GuiPanel.this.revalidate();
GuiPanel.this.repaint();
parentFrame.revalidate();
parentFrame.repaint();
}
};
button.addActionListener(imageLoaderListener);
this.add(button);
}
}
CardImagePanel.java :
public class CardImagePanel extends JPanel {
BufferedImage cardImage;
public CardImagePanel()
{
this.setBorder(BorderFactory.createLineBorder(Color.black));
try {
cardImage = ImageIO.read(new File("c:\\dev\\cards\\2_of_clubs.png"));
this.setPreferredSize(new Dimension(cardImage.getWidth(), cardImage.getHeight()));
} catch (IOException ex) {
System.out.println("Exception trying to load image file.");
}
}
// The getPreferredSize() override was suggested by MadProgrammer.
// It did not solve the issue, but see MadProgrammer's updated,
// accepted answer below for the correct solution. The rest of the
// code reflects my original attempt to solve the issue.
@Override
public Dimension getPreferredSize()
{
return cardImage != null ? new Dimension(cardImage.getWidth(), cardImage.getHeight()) : super.getPreferredImage();
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(cardImage, 0, 0, this);
}
}
我尝试了您的踢腿建议,但它没有效果。正如我在文章中所解释的,首选大小已经返回了预期的尺寸。我会花一些时间阅读您链接的文章以获得更多提示。 – Steverino
您的代码对我来说工作正常,如果在图像对于容器的可用空间较大时发生什么情况,这可能会引起关注,这意味着它会采取最小尺寸。我还建议将'frame.setSize(new Dimension(640,480));'更改为'frame.pack()' – MadProgrammer
在这种情况下,将最小尺寸手动设置为图像大小?编辑:对不起,只是看到你的代码更新。那看起来很有希望 – Steverino