JFrame或Jpanel中的repaint()方法?

时间:2016-04-02 02:24:48

标签: java swing jframe jpanel repaint

我是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的绘图组件。 我做了一些挖掘,看看MyDrawPanelJFrame是否共享相同的层次结构,这是我发现的:

JPanel - > object(有重绘方法) - > component(有paintcomponent方法) - >

container

所以我认为,由于 `jcomponent` --> `jpanel` `window` --> `frame` --> `jframe` JFrame都有JPanelpaintComponent方法,我可以扩展repaint来创建Jframe而不是MyDrawPanel,它应该工作正常。但事实并非如此。它编译良好但抛出运行时异常。

真的令人沮丧。可能是我没有获得GUI概念,或者我的基础知识仍然很薄弱。如果我在这里遗漏了一些非常愚蠢的东西,请告诉我。

1 个答案:

答案 0 :(得分:2)

让我们从paintComponent开始,在执行任何自定义绘画之前应该真正调用super.paintComponent

然后转到你身上真的应该阅读Painting in AWT and SwingPerforming Custom Painting,以便更好地理解绘画在Swing中的运作方式。 repaint未直接调用paintComponent,它要求RepaintManager在事件队列上安排paint事件,该事件在将来的某个时间点由事件调度线程,然后根据容器的需要处理paint事件

  

所以我认为,因为JFrame和JComponent都得到paintComponent

不,他们没有。 JFrame(和它的父类)没有paintComponent方法

  

可能是我可以扩展Jframe来创建MyDrawPanel而不是Jpanel,它应该可以正常工作“

不,你不应该,除了JFrame没有paintComponent之外,还有更多可能会干扰你可能尝试在{{1}上执行的任何自定义绘画并且你应该按照它的方式继续构建你的代码