这是我的问题:
我制作了一个程序,可以在随机位置绘制正方形,它有点粗糙,但它有效。 然而问题是它不会正确重新绘制,我不知道代码中的哪个位置我犯了错误。
这会导致以下情况发生:我告诉应用程序绘制5个方格,但是当我告诉它绘制6时它会绘制前5 + 6。
下面列出了代码,分为两部分:RandomSquares和DrawField:
public class RandomSquares extends JPanel {
private static JFrame frame = new JFrame("Random Squares");
private static DrawField f;
private static JButton button = new JButton("Make squares");
private static final JTextField field = new JTextField(10);
private static int amount = 0;
private static void prepareFrame() {
//knoppen
button.addActionListener(new ActionListener()
{
@Override
public void actionPerformed(ActionEvent e)
{
System.out.println(amount);
amount = Integer.parseInt(field.getText());
f = new DrawField(amount);
frame.add(f, BorderLayout.CENTER);
frame.repaint();
}
});
frame.add(button, BorderLayout.NORTH);
frame.add(field, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
Listener l = new Listener();
frame.addKeyListener(l);
frame.setSize(640, 480);
}
public static class Listener implements KeyListener {
@Override
public void keyTyped(KeyEvent ke) {
//unused
}
@Override
public void keyPressed(KeyEvent ke) {
if (ke.getKeyCode() == KeyEvent.VK_R) {
System.out.println("woot!");
}
}
@Override
public void keyReleased(KeyEvent ke) {
//unused
}
}
public static void run() {
f = new DrawField(amount);
prepareFrame();
frame.setVisible(true);
}
}
公共类DrawField扩展了JComponent {
private int amount;
public int getAmount() {
return amount;
}
public void setAmount(int amount) {
this.amount = amount;
}
public DrawField(int amount) {
this.amount = amount;
this.setSize(540, 380);
this.setBackground(Color.GREEN);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Random r = new Random();
for (int i = 0; i < amount; i++) {
g.fillRect(r.nextInt(getWidth()), r.nextInt(getHeight()),
20, 20);
}
}
}
答案 0 :(得分:0)
我告诉应用程序绘制5个方格,但是当我告诉它绘制6时它将绘制前5 + 6。
组件未被清除任何先前的绘制调用 - 请务必始终调用父绘制方法以清除任何先前的绘制。例如:
@Override
protected void paintComponent(Graphics g){
super.paintComponent(g);
//custom painting here.
}
答案 1 :(得分:0)
绘画方法只能用于绘画,而不能用于设置类的属性。
g.fillRect(r.nextInt(getWidth()), r.nextInt(getHeight()), 20, 20);
例如,如果您调整框架的大小,则会在新的随机位置绘制一组全新的矩形。
当您调用super.paintComponent()时,旧图形将丢失,并且将创建新的随机矩形。
相反,您的绘画代码应该基于类的属性。也就是说,一旦你创建了它们应该被修复的对象,所以除非你改变属性,否则重新绘制组件不会改变绘画。
有关如何使用随机数量的对象绘制的示例,请参阅Custom Painting Approaches:
在您的情况下,您将为要绘制的指定数量的矩形调用addRectangles(...)
方法。然后绘画代码将完成剩下的工作。
编辑:
回答您的基本问题。通常,在进行组件的自定义绘制之前,需要调用super.paintComponent()
来清除组件的背景。
问题是您正在展开JComponent
,它没有任何默认的绘画代码,因此背景不会被清除。两种解决方案:
类似的东西:
g.setColor( getBackground() );
f.fillRect(0, 0, getWidth(), getHeight());
// paint rectangle here