I'm trying to create a paint software, but have ended up with the issue of dissappearing graphics.
My class is as following:
public class CanvasFrame extends JPanel {
private Point lastMousePoint;
ArrayList location = new ArrayList();
public CanvasFrame() {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
lastMousePoint = new Point (e.getX(), e.getY());
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
Graphics g = getGraphics();
g.drawLine(lastMousePoint.x, lastMousePoint.y, e.getX(), e.getY());
lastMousePoint = new Point(e.getX(), e.getY());
g.dispose();
}
});
}
public static void main(String[] args) {
JFrame frame = new JFrame("Drawing with friends");
frame.getContentPane().add(new CanvasFrame(), BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(800, 600);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
frame.setVisible(true);
}
}
The drawing portion of the software is working fine, but as the issue informs, the drawing dissappears on minimizing.
I've tried working around with overriding Graphics g, as well as saving all the mouse points in an Array, but without luck. Searching around I was unable to find a solution to my exact project, so I hope you guys can help.
解决方案
I fixed up your code so that you draw a line as long as you're dragging the mouse. You draw a new line when you release and press the left mouse button again.
Here are the changes I made to the code.
I wrapped the JFrame code in a Runnable, and invoked the Swing GUI with a call to the SwingUtilities invokeLater method. The invokeLater method puts the creation and updating of the Swing GUI components on the Event Dispatch thread. Oracle and I demand that everyone starts their Swing application on the Event Dispatch thread.
I added the paintComponent method to paint the Points in the location List.
I modified the mouse methods to add points to the location List.
I moved the size information from the JFrame to the JPanel. We don't care about the size of the JFrame. We do care about the size of the drawing panel.
Here's the code:
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class CanvasFrame extends JPanel {
private static final long serialVersionUID = -2454929744982913302L;
private List location = new ArrayList();
public CanvasFrame() {
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
location.clear();
location.add(e.getPoint());
}
});
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
location.add(e.getPoint());
repaint();
}
});
setPreferredSize(new Dimension(800, 600));
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (location.size() <= 0) {
return;
}
Point p = location.get(0);
for (int i = 1; i < location.size(); i++) {
Point q = location.get(i);
g.drawLine(p.x, p.y, q.x, q.y);
p = q;
}
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
@Override
public void run() {
JFrame frame = new JFrame("Drawing with friends");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new CanvasFrame(), BorderLayout.CENTER);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
};
SwingUtilities.invokeLater(runnable);
}
}