按钮触发 frame.repaint() 即使我没有告诉它。我做错了什么?

button triggers frame.repaint() even when I did not tell it to. What did I do wrong?

我刚开始学习 java 4 天前,正在阅读 Head First Java,第 12 章进展缓慢。 即使我没有告诉它,我的 JButton eastb 也会触发 frame.repaint() 。我只告诉它在按下时触发 setText() 。为什么会这样?我错过了什么?

还有什么是@Override?不是方法中的术语 'override',而是术语“@Override”本身。

\\

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class Exp {
     JFrame frame;
     JLabel label;
     JButton eastb;
     JButton southb;

     public static void main(String[] args) {
      Exp a = new Exp();
      a.start();
     }

     public void start() {
      frame = new JFrame();
      frame.setSize(700,700);
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

      label = new JLabel("I'm stored text only");
      frame.getContentPane().add(BorderLayout.WEST, label);

      eastb = new JButton("Don't click me");
      frame.getContentPane().add(BorderLayout.EAST, eastb);
      eastb.addActionListener(new EastButton());

      southb = new JButton("Change color");
      frame.getContentPane().add(BorderLayout.SOUTH, southb);
      southb.addActionListener(new SouthButton());

      frame.add(new DrawPanel());

      frame.setVisible(true);
     }

     class EastButton implements ActionListener {
      public void actionPerformed(ActionEvent event1) {  
       eastb.setText("Ouch!");
      }
     }

     class SouthButton implements ActionListener {
      public void actionPerformed(ActionEvent event2) {
       frame.repaint();
      }
     }

    }

    class DrawPanel extends JPanel {
     public void paintComponent(Graphics g) {

      int red = (int) (Math.random()*255);
      int green = (int) (Math.random()*255);
      int blue = (int) (Math.random()*255); 

      Color randomizer = new Color(red, green, blue);
      g.setColor(randomizer);

      int x = getWidth()/2;
      int y = getHeight()/2;
      int r = x/2;
      int d = 2*r;

      g.fillOval(x-r, y-r, d, d);
     }
    }

\\

I only told it to trigger setText() when pressed.

当您更改组件的 属性 时,组件的大小可能会发生变化。如果尺寸发生变化,可能会影响所有组件的布局,因此调用布局管理器。调用布局管理器后,所有组件都可能会进行 size/location 调整,以便重新绘制面板上的所有组件。

这个过程是自动的,这会导致您的代码出现问题。

一种绘画方法应该是绘画专用的。你不应该在绘画方法中改变你的属性class。

  int red = (int) (Math.random()*255);
  int green = (int) (Math.random()*255);
  int blue = (int) (Math.random()*255); 

  Color randomizer = new Color(red, green, blue);

以上代码不应该出现在你的绘画方法中。同样,您无法控制何时调用 paintComponent() 方法。因此,每次 Swing 确定应重新绘制面板时,都会生成随机颜色。

相反,您需要:

  1. 在您的 class.
  2. 中添加 "randomizer" 作为实例变量
  3. 添加类似 generateRandomColor() 的方法来设置此变量的值,您可以在 class 的构造函数中调用,或者在创建自定义面板后调用。
  4. 更改绘制逻辑以引用此 "randomizer" 变量。