Window content disappears when minimized

I have a simple class that draws a line when you drag the mouse or point when you click (release) the mouse.

When I minimize the application and restore it, the contents of the window disappear, except for the last point (pixel). I understand that the super.paint(g) method replicates the background every time the window changes, but the result seems to be the same, regardless of whether I use it or not. The difference between the two is that when I do not use it, itโ€™s more than the pixel drawn in the window, but not all of my pictures. How can i fix this?

Here is the class.

 package painting; import java.awt.*; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.MouseMotionAdapter; import javax.swing.JFrame; import javax.swing.JPanel; class CustomCanvas extends Canvas{ Point oldLocation= new Point(10, 10); Point location= new Point(10, 10); Dimension dimension = new Dimension(2, 2); CustomCanvas(Dimension dimension){ this.dimension = dimension; this.init(); addListeners(); } private void init(){ oldLocation= new Point(0, 0); location= new Point(0, 0); } public void paintLine(){ if ((location.x!=oldLocation.x) || (location.y!=oldLocation.y)) { repaint(location.x,location.y,1,1); } } private void addListeners(){ addMouseListener(new MouseAdapter(){ @Override public void mousePressed(MouseEvent me){ oldLocation = location; location = new Point(me.getX(), me.getY()); paintLine(); } @Override public void mouseReleased(MouseEvent me){ oldLocation = location; location = new Point(me.getX(), me.getY()); paintLine(); } }); addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent me){ oldLocation = location; location = new Point(me.getX(), me.getY()); paintLine(); } }); } @Override public void paint(Graphics g){ super.paint(g); g.setColor(Color.red); g.drawLine(location.x, location.y, oldLocation.x, oldLocation.y); } @Override public Dimension getMinimumSize() { return dimension; } @Override public Dimension getPreferredSize() { return dimension; } } class CustomFrame extends JPanel { JPanel displayPanel = new JPanel(new BorderLayout()); CustomCanvas canvas = new CustomCanvas(new Dimension(200, 200)); public CustomFrame(String titlu) { canvas.setBackground(Color.white); displayPanel.add(canvas, BorderLayout.CENTER); this.add(displayPanel); } } public class CustomCanvasFrame { public static void main(String args[]) { CustomFrame panel = new CustomFrame("Test Paint"); JFrame f = new JFrame(); f.add(panel); f.pack(); SwingConsole.run(f, 700, 700); } } 
+6
source share
3 answers

You do not save the state of the points that you draw. When a panel is repainted, it only has information for the last point that it drew.


Reply to comment:

You will need to have a set of points, for example ArrayList<Point> location = new ArrayList<Point>();

Then in your listeners: location.add(new Point(me.getX(), me.getY()));

Finally, in paintLine ():

 for (Point location : locations) { repaint(location.x,location.y,1,1); } 

The locations collection is usually called a display list. Most graphics programs use them.


Reply to comment:

Yes, I expect. I just dropped the idea based on your code to give you a starting point. It is definitely a bad idea to do what I described.

+5
source

Does this mean that I will draw all the points (instead of one) every time I click or drag the mouse?

Yes, but @Dave's approach is quite satisfactory for thousands of nodes, which can be seen in GraphPanel . Also, consider the fly pattern , as used by JTable rendering and illustrated here .

Addition. By focusing on your AWTPainting , the option below can illustrate the difference between painting using your system and applications . When the mouse is dragged, repaint() calls update() , which calls paint() ; This application is starting. When the window is resized, only paint() is called (red numbers are not displayed); it is initiated by the system. Note that flickering appears when the mouse changes.

Flickering usually occurs when the entire background of the component is cleared and redrawn:

4. If the component did not override update() , the default implementation of update() clears the background of the component (if it is not a light component) and simply calls paint() .

AWTPainting

 import java.awt.Canvas; import java.awt.Color; import java.awt.Dimension; import java.awt.Frame; import java.awt.Graphics; import java.awt.Panel; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.util.ArrayList; import java.util.List; public class AWTPainting { public static void main(String args[]) { CustomPanel panel = new CustomPanel(); Frame f = new Frame(); f.addWindowListener(new WindowAdapter() { @Override public void windowClosing(WindowEvent e) { System.exit(0); } }); f.add(panel); f.pack(); f.setVisible(true); } } class CustomPanel extends Panel { public CustomPanel() { this.add(new CustomCanvas(new Dimension(320, 240))); } } class CustomCanvas extends Canvas { private MouseAdapter handler = new MouseHandler(); private List<Point> locations = new ArrayList<Point>(); private Point sentinel = new Point(); private Dimension dimension; CustomCanvas(Dimension dimension) { this.dimension = dimension; this.setBackground(Color.white); this.addMouseListener(handler); this.addMouseMotionListener(handler); this.locations.add(sentinel); } @Override public void paint(Graphics g) { g.setColor(Color.blue); Point p1 = locations.get(0); for (Point p2 : locations.subList(1, locations.size())) { g.drawLine(p1.x, p1.y, p2.x, p2.y); p1 = p2; } } @Override public void update(Graphics g) { paint(g); g.clearRect(0, getHeight() - 24, 50, 20); // to background g.setColor(Color.red); g.drawString(String.valueOf(locations.size()), 8, getHeight() - 8); } private class MouseHandler extends MouseAdapter { @Override public void mousePressed(MouseEvent e) { if (locations.get(0) == sentinel) { // reference identity locations.set(0, new Point(e.getX(), e.getY())); } } @Override public void mouseDragged(MouseEvent e) { locations.add(new Point(e.getX(), e.getY())); repaint(); } } @Override public Dimension getPreferredSize() { return dimension; } } 
+5
source

@Andrew, @Dave, @trashgod Hi, I did some research on this and finally, this is what I have. Please correct me if I am wrong. You cannot override paint (), so you call repaint () every time you need to paint using an application. Repaint () calls update (), which by default calls paint (). update () is used for incremental painting; which explains the flickering screen when the paint () did all the work, which practically means that at every step she paints the whole image. However, my question is if I add โ€œlocationsAdded = 0โ€ in the update method, which means that every time I drag the mouse, I draw the whole image (for example, in paint), so why doesn't it blink , like before? I also read something about painting in a swing, and I did not understand why update () was never called for a swing. Can you explain to me why?

 import java.awt.*; import java.awt.event.*; import java.util.ArrayList; class CustomCanvas extends Canvas{ ArrayList<Point> locations; int locationsAdded; Point oldLocation; Point location; Dimension dimension; CustomCanvas(Dimension dimension){ locations = new ArrayList<>(); this.dimension = dimension; this.init(); addListeners(); } private void init(){ oldLocation= new Point(0, 0); location= new Point(0, 0); } public void paintLine(Graphics g, int x){ Point p1 = (Point)locations.get(x); Point p2 = (Point)locations.get(x+1); g.drawLine(p1.x, p1.y, p2.x, p2.y); locationsAdded++; } @Override public void paint(Graphics g){ locationsAdded = 0; g.setColor(Color.red); for(int i = locationsAdded; i < locations.size()-1; i++){ paintLine(g, i); } } public void update(Graphics g) { //locationsAdded = 0; for (int i = locationsAdded; i < locations.size()-1; i++) { paintLine(g, i); } } private void addListeners(){ addMouseMotionListener(new MouseMotionAdapter() { @Override public void mouseDragged(MouseEvent me){ oldLocation = location; location = new Point(me.getX(), me.getY()); locations.add(location); repaint(); } }); } @Override public Dimension getMinimumSize() { return dimension; } @Override public Dimension getPreferredSize() { return dimension; } } class CustomFrame extends Panel { Panel displayPanel = new Panel(new BorderLayout()); CustomCanvas canvas = new CustomCanvas(new Dimension(700, 700)); public CustomFrame(String titlu) { canvas.setBackground(Color.white); displayPanel.add(canvas, BorderLayout.CENTER); this.add(displayPanel); } } public class AWTPainting { public static void main(String args[]) { CustomFrame panel = new CustomFrame("Test Paint"); Frame f = new Frame(); f.add(panel); f.pack(); f.setSize(700,700); f.show(); } } 
+2
source

Source: https://habr.com/ru/post/912956/


All Articles