【发布时间】:2015-09-21 05:15:03
【问题描述】:
我有一个 JFrame。它使用 JPanel 作为其内容窗格,并且该 JPanel 使用 GridBagLayout 作为其 LayoutManager。该 JPanel 包含另外两个项目:一个按钮和另一个 JPanel。在程序启动时,使用 ImageIO.read(...) 将图像作为 BufferedImage 从文件加载到最低级别的 JPanel。一切都在这里化为泡影。
图像加载正确,我可以在屏幕上看到它的一个小角(调试器中指定的 14px 正方形)。我无法弄清楚会导致布局增长并将整个图像放在屏幕上最低级别的 JPanel 中。调试器中的图像显示正确大小为 500 像素。 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);
}
}
【问题讨论】:
标签: java swing layout-manager bufferedimage gridbaglayout