super.paintComponent(g)做了什么?

时间:2018-10-18 21:07:08

标签: java

因此,在过去的几天中,我尝试实现一种更简单的图形绘图仪版本。 我遇到的一个大问题是重新粉刷时发生的错误。 基本上,我已经在一个类中设计了程序,该类负责在另一个类中单击JButton之后绘制整个坐标系和给定的函数。另一个类包含被按下的JButton。按下JButton后,它将在坐标系类中调用一个函数以重画图片。这两个类都在扩展JPanel。

错误是,当我按下按钮进行重新绘制时,按钮是在坐标系上绘制的,而不是在其原始位置绘制的,换句话说,即使我没有更改任何内容,在另一个JPanel上也是如此关于展示位置和内容。这两个类都被添加到使用GridLayout的JFrame中。

谁能告诉我为什么super.paintComponent(g);解决了这个错误?

编辑:已添加代码

窗口类

public class Surface extends JPanel {

/**
 * 
 */
private static final long serialVersionUID = 1L;
boolean drawFunct;

public Surface(int x1, int y1, int coordLength) {
    setSize(x1,y1);
    drawFunct = false;

}

public void paintComponent(Graphics g) {
    super.paintComponent(g); // without this the jbutton occures on the left

    // create Graphics object to get more functions
    Graphics2D g2 = (Graphics2D) g;
    // draw Plotter
    drawFunction(g2);

    if (drawFunct)
        g2.drawLine(0, 0, 80, 80);
}

public void drawFunction(Graphics2D g) {
    g.drawRect(40, 40, 30, 30);
}

public void redraw() {
    drawFunct = true;
    repaint();
}
}

坐标系类:(为简单起见,将坐标系更改为矩形,仅在绘制矩形时仍会发生错误)

public class CommandDraw extends JPanel {
/**
 * 
 */
private static final long serialVersionUID = 1L;
JButton makeDraw;
JTextField inputPoly;
Surface surf;

public CommandDraw(int x, int y, Surface surf) {
    this.surf = surf;
    setSize(x,y);
    setLayout(new FlowLayout());


    makeDraw = new JButton("draw Function");
    makeDraw.setBackground(Color.LIGHT_GRAY);
    makeDraw.setFocusable(false);

    makeDraw.addActionListener( new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            surf.redraw();

        }

    });

    add(makeDraw);


    inputPoly = new JTextField("Input polynomial");
    inputPoly.setHorizontalAlignment(JTextField.CENTER);
    add(inputPoly);


}
}

带有JButton的类:

{{1}}

1 个答案:

答案 0 :(得分:0)

Can anyone tell me why super.paintComponent(g); solved that bug?

因为对超类(JPanel)的paintComponent(g)的调用将保证在进行绘制操作之前,将按预期方式渲染面板。您需要确保您的JPanel在“图形”透视图中的行为与其他任何JPanel一样。

用于自定义JPanel绘制的模板应该类似于:

import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JPanel;

public class MyDrawPanel extends JPanel {

    @Override
    protected void paintComponent( Graphics g ) {

        super.paintComponent( g );

        // create a new graphics context based on the original one
        Graphics2D g2d = (Graphics2D) g.create();

        // draw whatever you want...


        g2d.dispose();

    }

}

编辑

您需要调用super.paintComponent(g)来告知JPanel paintComponent(Graphics)版本应在开始查找自定义内容之前执行。这就像要求JPanel准备要使用的绘画功能一样。这些疑问的一个很好的起点是文档:https://docs.oracle.com/javase/10/docs/api/javax/swing/JComponent.html#paintComponent(java.awt.Graphics)

在原始dispose()的副本中正在调用Graphics方法。如果您处置传递给方法的Graphics,则可能也会遇到一些问题。您可以使用原始的Graphics来执行绘画操作,但是不应该这样做,因此,更好的做法是制作原始Graphics的副本并在使用后进行处置。

也在这里看看:How does paintComponent work?

相关问题