【问题标题】:What did super.paintComponent(g) do?super.paintComponent(g) 做了什么?
【发布时间】:2018-10-18 21:07:07
【问题描述】:

所以在过去的几天里,我试图实现一个更简单的绘图仪版本。 我遇到的一个大问题是重绘时出现的错误。 基本上,我在一个类中设计了我的程序,该类负责在单击另一个类中的 JButton 后绘制整个坐标系和给定函数。另一个类包含按下的 JButton。按下 JButton 后,它会调用坐标系类中的一个函数来重新绘制图片。这两个类都在扩展 JPanel。

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

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

编辑:添加代码

窗口类

public class main {

public static void main(String[] args) throws SemanticFailureException {

    int x = 800;
    int y = 600;


    JFrame frame = new JFrame();
    frame.setLayout(new GridLayout());
    frame.setTitle("Function plotter");
    frame.setSize(2*x, 2*y);

    Surface test = new Surface(x, y, 10);
    CommandDraw test1 = new CommandDraw(x/2,y,test);


    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setLocationRelativeTo(null);
    frame.add(test);
    frame.add(test1);


    frame.setVisible(true);

}
}

坐标系类:(为简单起见将坐标系绘制为矩形,仅绘制矩形仍然存在错误)

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();
}
}

带有 JButton 的类:

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);


}
}

【问题讨论】:

  • 如果没有看到你的代码,很难理解你到底做错了什么。您的图形故障可能有多种原因。在挥杆中进行自定义绘画时,人为错误的机会很多。
  • @DudeDoesThings 不,不是他的情况。这种“行为”完全是意料之中的。

标签: java


【解决方案1】:

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?

【讨论】:

  • 你能再解释一下为什么它会以如此不同和奇怪的方式表现吗?应该与其他jpanel无关的jpanel如何能够在那里绘制jbutton?如果这变得太复杂,我真的很感激一个链接或我可以阅读更多的东西。不过非常感谢!我什至不知道我应该使用 .dispose() 但我也会阅读它!
  • @Pgrav 我补充了我的答案。看一看。如果我的分析器解决了您的问题,请考虑将其标记为已解决。
猜你喜欢
  • 2015-04-27
  • 2015-05-09
  • 2011-09-07
  • 2015-02-17
  • 1970-01-01
  • 2012-06-05
  • 1970-01-01
  • 1970-01-01
  • 2012-10-18
相关资源
最近更新 更多