我是Java新手,刚开始学习GUI组件。所以,我正在阅读Headfirst Java,这段代码解释了paintcomponent
JPanel
方法。只要用户点击“更改颜色”按钮,就可以改变椭圆的颜色。 -
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class SimpleGui3C implements ActionListener {
JFrame frame;
public static void main(String[] args) {
SimpleGui3C gui = new SimpleGui3C();
gui.go();
}
public void go() {
frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JButton button = new JButton("Change colors");
button.addActionListener(this);
MyDrawPanel drawPanel = new MyDrawPanel();
frame.getContentPane().add(BorderLayout.SOUTH, button);
frame.getContentPane().add(BorderLayout.CENTER, drawPanel);
frame.setSize(500,500);
frame.setVisible(true);
}
public void actionPerformed(ActionEvent event) {
frame.repaint();
}
}
MyDrawPanel类 -
import javax.swing.*;
import java.awt.*;
class MyDrawPanel extends JPanel {
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
// GradientPaint gradient = new GradientPaint(70,70,Color.blue,150,150,Color.orange);
int red = (int) (Math.random() * 255);
int green = (int) (Math.random() * 255);
int blue = (int) (Math.random() * 255);
Color startColor = new Color(red, green, blue);
red = (int) (Math.random() * 255);
green = (int) (Math.random() * 255);
blue = (int) (Math.random() * 255);
Color endColor = new Color(red, green, blue);
GradientPaint gradient = new GradientPaint(70,70,startColor,150,150,endColor);
g2d.setPaint(gradient);
g2d.fillOval(70,70,100,100);
}
}
除了我们称之为repaint()
方法的部分外,我从这个例子中得到了所有内容。
在本书中,有人提到只需覆盖paintcomponent
的{{1}}方法,当您致电JPanel
时,它会调用repaint()
来呈现内容(因为我们不直接致电paintcomponent
。
现在,我通过扩展paintcomponent
并覆盖其MyDrawPanel
方法创建了JPanel
类。现在,当我们将paintComponent
小部件置于框架上然后单击鼠标时,将调用drawPanel
方法。但是使用repint()
- repaint()
的对象调用此frame
方法。根据我的基本java理解,如果我使用对象调用方法,那么该方法必须在该类或某些超类中。我看不到在JFrame
上调用repaint()
将如何触发frame
的绘图组件。
我做了一些挖掘,看看MyDrawPanel
和JFrame
是否共享相同的层次结构,这是我发现的:
JPanel
- >
object
(有重绘方法) - >
component
(有paintcomponent方法) - >
container
所以我认为,由于 `jcomponent` --> `jpanel`
`window` --> `frame` --> `jframe`
和JFrame
都有JPanel
和paintComponent
方法,我可以扩展repaint
来创建Jframe
而不是MyDrawPanel
,它应该工作正常。但事实并非如此。它编译良好但抛出运行时异常。
真的令人沮丧。可能是我没有获得GUI概念,或者我的基础知识仍然很薄弱。如果我在这里遗漏了一些非常愚蠢的东西,请告诉我。
答案 0 :(得分:2)
让我们从paintComponent
开始,在执行任何自定义绘画之前应该真正调用super.paintComponent
然后转到你身上真的应该阅读Painting in AWT and Swing和Performing Custom Painting,以便更好地理解绘画在Swing中的运作方式。 repaint
未直接调用paintComponent
,它要求RepaintManager
在事件队列上安排paint
事件,该事件在将来的某个时间点由事件调度线程,然后根据容器的需要处理paint
事件
所以我认为,因为JFrame和JComponent都得到paintComponent
不,他们没有。 JFrame
(和它的父类)没有paintComponent
方法
可能是我可以扩展Jframe来创建MyDrawPanel而不是Jpanel,它应该可以正常工作“
不,你不应该,除了JFrame
没有paintComponent
之外,还有更多可能会干扰你可能尝试在{{1}上执行的任何自定义绘画并且你应该按照它的方式继续构建你的代码