因此,在过去的几天中,我尝试实现一种更简单的图形绘图仪版本。 我遇到的一个大问题是重新粉刷时发生的错误。 基本上,我已经在一个类中设计了程序,该类负责在另一个类中单击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}}
答案 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
的副本并在使用后进行处置。