[英]can't draw on a JPanel after repaint method
I'm experimenting on a GUI that I programmed and I don't understand how I can fix my problem: My GUI contains a jPanel that on receiving a mouseclick, paints a point with filloval command. 我正在尝试对自己编写的GUI进行实验,但我不知道如何解决该问题:我的GUI包含一个jPanel,该jPanel会在接收到鼠标单击时使用filloval命令绘制一个点。
private void myPnlMousePressed(java.awt.event.MouseEvent evt) {
changed = true;
p.x = evt.getX();
p.y = evt.getY();
drewPoints(p.x, p.y);
}
private void drewPoints (int x, int y) {
if (gf == null) {
gf = (Graphics)myPnl.getGraphics();
}
myPointsList.add(new Point(x, y));
gf.fillOval(x, y, 5, 5);
xVal.setText("X = " + x);
yVal.setText("Y = " + y);
}
everything works fine but when I want to open an XML file that I created to save all the points it doesn't work. 一切正常,但是当我想打开为保存所有要点而创建的XML文件时,它不起作用。 The problem is that when I use the repaint method on the jPanel after choosing a file, all the points loads fine but the panel can't draw the points.
问题是,当我选择文件后在jPanel上使用repaint方法时,所有点均加载良好,但面板无法绘制这些点。 If I put the repaint method in the open button listener (before the choosing file) it works, but then if the user cancels the open option so the panel stays blank and I don't want to draw the points again.
如果我将重绘方法放在打开按钮侦听器中(在选择文件之前),则可以,但是如果用户取消了打开选项,则面板保持空白,并且我不想再次绘制点。 I think it happens because the repaint process is not finished.
我认为发生这种情况是因为重新粉刷过程尚未完成。 All the points added to a private List.
所有点都添加到私有列表中。
private void OpenFile() {
try {
File thisFile;
JFileChooser of = new JFileChooser();
int option = of.showOpenDialog(of);
if (option == JFileChooser.APPROVE_OPTION){
thisFileName = of.getSelectedFile().getPath();
thisFile = new File(thisFileName);
if (!of.getSelectedFile().getName().endsWith(".xml")) {
String error = "Error, You didn't select XML file";
JOptionPane.showMessageDialog(this, error, "Wrong type of file", JOptionPane.INFORMATION_MESSAGE);
return;
}
myPnl.repaint();
myPointsList.clear();
....
....
....
for (int i = 0; i < pointsList.getLength(); i++) {
Element point = (Element) pointsList.item(i);
p.x = Integer.parseInt(point.getElementsByTagName("X").item(0).getTextContent());
p.y = Integer.parseInt(point.getElementsByTagName("Y").item(0).getTextContent());
drewPoints(p.x, p.y);
}
....
how can I make it work?? 我如何使它工作?
Don't use gf = (Graphics)myPnl.getGraphics();
不要使用
gf = (Graphics)myPnl.getGraphics();
, this is not how painting in Swing works. ,这不是Swing中的绘画工作原理。 The
getGraphics
method can return null
and is nothing more then a snap shot of the last paint cycle, any thing you paint to it will be erased on the next paint cycle (repaint). getGraphics
方法可以返回null
,仅是最后一个绘制周期的快照,您对其绘制的任何内容都将在下一个绘制周期(重新绘制)中删除。
Instead, override the JPanel
s paintComponent
and put all you painting logic there. 而是重写
JPanel
的paintComponent
并将所有绘画逻辑放在此处。 There is an expectation that when called, you are expected to fully re-paint the current state of the component. 期望在被调用时,您应该完全重新绘制组件的当前状态。
See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing 有关绘画如何在Swing中工作的更多详细信息,请参见AWT中的绘画和Swing和执行自定义绘画 。
You have to use the repaint()
and override the paint()
method: 您必须使用
repaint()
并重写paint()
方法:
class MyPanel extends JPanel implements MouseListener
{
private int x;
private int y;
public MyPanel() {
super();
addMouseListener(this);
}
@Override public void mouseEntered(MouseEvent e) { }
@Override public void mouseExited(MouseEvent e) { }
@Override public void mouseClicked(MouseEvent e) { }
@Override public void mousePressed(MouseEvent e) { }
@Override public void mouseReleased(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
@Override public void paint(Graphics g) {
super.paint(g);
g.fillOval(x, y, 10, 10);
}
}
If you want to draw all points, don't use x
and y
but a list of points
: 如果要绘制所有点,请不要使用
x
和y
而要使用list of points
:
class MyPanel extends JPanel implements MouseListener
{
private ArrayList<Point> points = new ArrayList<>();
public MyPanel() {
super();
addMouseListener(this);
}
@Override public void mouseEntered(MouseEvent e) { }
@Override public void mouseExited(MouseEvent e) { }
@Override public void mouseClicked(MouseEvent e) { }
@Override public void mousePressed(MouseEvent e) { }
@Override public void mouseReleased(MouseEvent e) {
points.add(new Point(e.getX(), e.getY()));
repaint();
}
@Override public void paint(Graphics g) {
super.paint(g);
for (Point p : points)
g.fillOval(p.getX(), p.getY(), 10, 10);
}
}
where: 哪里:
class Point
{
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
Then use it: 然后使用它:
public static void main(String[] args) {
JFrame frame = new JFrame("Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setLocationRelativeTo(null);
MyPanel myPanel = new MyPanel();
frame.add(myPanel);
frame.setVisible(true);
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.