按钮触发 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 确定应重新绘制面板时,都会生成随机颜色。
相反,您需要:
- 在您的 class.
中添加 "randomizer" 作为实例变量
- 添加类似
generateRandomColor()
的方法来设置此变量的值,您可以在 class 的构造函数中调用,或者在创建自定义面板后调用。
- 更改绘制逻辑以引用此 "randomizer" 变量。
我刚开始学习 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 确定应重新绘制面板时,都会生成随机颜色。
相反,您需要:
- 在您的 class. 中添加 "randomizer" 作为实例变量
- 添加类似
generateRandomColor()
的方法来设置此变量的值,您可以在 class 的构造函数中调用,或者在创建自定义面板后调用。 - 更改绘制逻辑以引用此 "randomizer" 变量。