我正在尝试使用GUI制作这个简单的程序,一旦按下JButton就会创建一个圆圈。我一直在研究这个问题,并试图弄清楚为什么这对夫妻时间不起作用。我在stackoverflow上查看类似的代码与类似问题的人,但是,我仍然无法弄清楚这一点。有人可以告诉我哪里出错了,为什么我不对?谢谢。
public class ColorShape {
public static void main(String[] args) {
CreatePanel c = new CreatePanel();
c.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
c.setSize(300, 450);
c.setVisible(true);
}
}
public class CreatePanel extends JFrame {
private JButton DC;
private BorderLayout layout;
public CreatePanel() {
super("Color-Shape");
layout = new BorderLayout();
setLayout(layout);
DC = new JButton("Circle");
DC.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
DrawCirc circ = new DrawCirc();
add(circ);
repaint();
}
}
);
add(DC, BorderLayout.NORTH);
}
}
public class DrawCirc extends JPanel {
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.cyan);
g.fillOval(100, 100, 50, 50);
}
}
答案 0 :(得分:2)
嗯,你的第一个问题是,DrawCirc
没有提供大小调整提示,这意味着它的默认大小将是0x0
public class DrawCirc extends JPanel {
@Override
public Dimension getPreferredSize() {
return new Dimension(150, 150);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.cyan);
g.fillOval(100, 100, 50, 50);
}
}
另外,请记住,Graphics
上下文已翻译,因此0x0
是组件的左上角。
第二个问题是,Swing很懒。它允许您对UI进行一些更改,然后批量处理它们。这意味着当您完成UI的更新后,您必须同时调用revalidate
和repaint
来触发布局和绘制传递
DC.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent event) {
DrawCirc circ = new DrawCirc();
add(circ);
revalidate();
repaint();
}
});
这两个问题并不少见。您应该花更多时间了解布局管理系统,因为它会让您的生活更简单;)
答案 1 :(得分:1)
更改组件层次结构后,将repaint()
更改为revalidate()
。如果您调整窗口大小,您会注意到当前版本会绘制圆圈,因为这会重新验证布局。
来自文档:
将组件层次结构重新验证到最近的验证根。 此方法首先使组件层次结构无效 此组件最近的验证根。之后, 组件层次结构从最近的验证开始验证 根。这是一种有助于应用的便捷方法 开发人员避免手动查找验证根。基本上,它是 相当于首先在此组件上调用invalidate()方法, 然后在最近的验证根目录上调用validate()方法。