我正在尝试使用 JPanel 绘制一个矩形。问题是,当我点击一个菜单项时,它应该绘制一个新的矩形。但是,当我这样做时,只有一部分被涂上了。这就是我的意思:
rectangleMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
squares.addSquare(10, 10, 100, 100);
}
});
这样做:
但是当我将 squares.addSquare(...)
放在 ActionListener 的外部时,它给出了正确的形状(只是不是我想要的时候)
squares.addSquare(10, 10, 100, 100);
rectangleMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
//nothing on click...
}
});
这是正确的矩形:
知道为什么当我将它放入 ActionListener 时它无法正确绘制吗?谢谢。
完整代码
class UMLWindow extends JFrame {
Squares squares = new Squares();
private static final long serialVersionUID = 1L;
public UMLWindow() {
addMenus();
}
public void addMenus() {
getContentPane().add(squares);
//squares.addSquare(10, 10, 100, 100);
JMenuBar menubar = new JMenuBar();
JMenu file = new JMenu("File");
file.setMnemonic(KeyEvent.VK_F);
JMenu shapes = new JMenu("Shapes");
file.setMnemonic(KeyEvent.VK_F);
JMenuItem rectangleMenuItem = new JMenuItem("New Rectangle");
rectangleMenuItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent event) {
squares.addSquare(10, 10, 100, 100);
}
});
shapes.add(rectangleMenuItem);
menubar.add(shapes);
setJMenuBar(menubar);
setTitle("UML Editior");
setSize(300, 200);
setLocationRelativeTo(null);
}
}
class Squares extends JPanel {
private static final long serialVersionUID = 1L;
private List<Rectangle> squares = new ArrayList<Rectangle>();
public void addSquare(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(x, y, width, height);
squares.add(rect);
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
this.setOpaque(true);
this.setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rect : squares) {
g2.draw(rect);
}
}
}
最佳答案
Swing 使用被动渲染引擎,因此除非您告诉它,否则它不知道何时应该更新/重绘组件。
首先从您的 addSquare
方法中调用 repaint
...
public void addSquare(int x, int y, int width, int height) {
Rectangle rect = new Rectangle(x, y, width, height);
squares.add(rect);
repaint();
}
这将向重绘管理器发出请求,通知它当前组件需要重绘。
您还应该为组件提供大小调整提示,以便布局管理器将其大小设置为 0x0
。
考虑覆盖 Squares
类的 getPreferredSize
方法并返回适当的默认大小...
@Override
public Dimension getPreferredSize() {
return new Dimension(300, 200);
}
这也意味着您可以在主窗口上调用 pack
,它会围绕内容“打包”自己,非常整洁。
此外,不要调用会更改组件或其他组件状态或安排额外的 repaint
请求的方法,因为这可能会设置一个无限循环的重绘,这会耗尽您的 PC资源....
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// This is bad...
//this.setOpaque(true);
// This is bad...
//this.setBackground(Color.WHITE);
Graphics2D g2 = (Graphics2D) g;
for (Rectangle rect : squares) {
g2.draw(rect);
}
}
诸如不透明度和颜色之类的东西应该在绘制周期之外定义。此外,从 JPanel
扩展的组件在默认情况下是不透明的;)
关于java - 使用 JPanel 在单击按钮时绘制矩形,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26026024/