Java clears the screen when calling the drawing method - how to avoid this?

I am trying to draw two lines in Canvas in Java by calling two methods separately, but when I draw the second line, the first one disappears (Java clears the screen). How can i avoid this? I want to see two lines. I saw drawing tutorials (how to make a program like Paint on Windows), where the user uses the mouse to draw lines, and when one line is drawn, the other does not disappear. They simply call the drawing method, and it does not clear the screen.

I would be grateful if anyone could help me. Thanks.

View class

import java.awt.BorderLayout; import java.awt.Canvas; import java.awt.Color; import java.awt.Graphics; import javax.swing.JFrame; public class CircuitTracePlotView extends JFrame { private CircuitTracePlot circuitTracePlot; public CircuitTracePlotView() { this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); this.getContentPane().add(circuitTracePlot = new CircuitTracePlot(), BorderLayout.CENTER); this.pack(); this.setSize(250,250); this.setLocationRelativeTo(null); this.setVisible(true); circuitTracePlot.drawLine(); circuitTracePlot.drawOval(); } } class CircuitTracePlot extends Canvas { private final static short LINE = 1; private final static short OVAL = 2; private int paintType; private int x1; private int y1; private int x2; private int y2; public CircuitTracePlot() { this.setSize(250,250); this.setBackground(Color.WHITE); } private void setPaintType(int paintType) { this.paintType = paintType; } private int getPaintType() { return this.paintType; } public void drawLine() { this.setPaintType(LINE); this.paint(this.getGraphics()); } public void drawOval() { this.setPaintType(OVAL); this.paint(this.getGraphics()); } public void repaint() { this.update(this.getGraphics()); } public void update(Graphics g) { this.paint(g); } public void paint(Graphics g) { switch (paintType) { case LINE: this.getGraphics().drawLine(10, 10, 30, 30); case OVAL: this.getGraphics().drawLine(10, 20, 30, 30); } } } 

Main class

 import javax.swing.SwingUtilities; import view.CircuitTracePlotView; public class Main { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { CircuitTracePlotView cr = new CircuitTracePlotView(); } }); } } 
+4
source share
2 answers
  • You should almost never call paint(...) directly. I can calculate the time I need for this, on the one hand.
  • Do not get the Graphics object by calling getGraphics() on the component, as it will return an illiterate Graphics object. Instead, either draw a BufferedImage, or show that in the draw method or draw in the draw method (if AWT).
  • Since this is a Swing GUI, do not use the AWT component for drawing. Use JPanel and override the paintComponent(...) method, not the paint(...) method. Otherwise, you will lose all the benefits of Swing graphics, including automatic double buffering.
  • The super.paintComponent(g) method must be called in an override of paintComponent(Graphics g) , often as the first method call inside this method. This allows the component to complete its own home picture, including deleting the pictures that need to be removed.
  • Read the Swing graphic tutorials as most of them are well explained here. For example, please see here:

Edit

  • To save your images, I suggest you draw on a BufferedImage, and then display that image in the JPanel method of paintComponent(...) .
  • Or another option is to create Collection of Shape objects, possibly ArrayList<Shape> and fill it with the shapes you want to draw, and then in the paintComponent(...) method apply the Graphics object to the Graphics2D object and iterate through the Shape collection, drawing each shape using g2d.draw(shape) when repeating.

Since Trash published its code, ...

 import java.awt.Dimension; import java.awt.Graphics; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; public class CircuitTracePlot2 extends JPanel { private static final int PREF_W = 250; private static final int PREF_H = PREF_W; private int drawWidth = 160; private int drawHeight = drawWidth; private int drawX = 10; private int drawY = 10; private PaintType paintType = PaintType.LINE; public CircuitTracePlot2() { } @Override public Dimension getPreferredSize() { return new Dimension(PREF_W, PREF_H); } public void setPaintType(PaintType paintType) { this.paintType = paintType; repaint(); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (paintType == null) { return; } switch (paintType) { case LINE: g.drawLine(drawX, drawY, drawWidth, drawHeight); break; case OVAL: g.drawOval(drawX, drawY, drawWidth, drawHeight); break; case SQUARE: g.drawRect(drawX, drawY, drawWidth, drawHeight); default: break; } } private static void createAndShowGui() { final CircuitTracePlot2 circuitTracePlot = new CircuitTracePlot2(); JFrame frame = new JFrame("CircuitTracePlot2"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.getContentPane().add(circuitTracePlot); frame.pack(); frame.setLocationByPlatform(true); frame.setVisible(true); int timerDelay = 2 * 1000; new Timer(timerDelay , new ActionListener() { private int paintTypeIndex = 0; @Override public void actionPerformed(ActionEvent arg0) { paintTypeIndex++; paintTypeIndex %= PaintType.values().length; circuitTracePlot.setPaintType(PaintType.values()[paintTypeIndex]); } }).start(); } public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { createAndShowGui(); } }); } } enum PaintType { LINE, OVAL, SQUARE; } 
+4
source

Here's a variation of your program that implements most of @Hovercraft's helpful tip. Try commenting out the setPaintType() call to see the effect.

 import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.Graphics; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.SwingUtilities; /** @see http://stackoverflow.com/a/15854246/230513 */ public class Main { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { @Override public void run() { CircuitTracePlotView cr = new CircuitTracePlotView(); } }); } private static class CircuitTracePlotView extends JFrame { private CircuitTracePlot plot = new CircuitTracePlot(); public CircuitTracePlotView() { this.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); plot.setPaintType(CircuitTracePlot.OVAL); this.add(plot, BorderLayout.CENTER); this.pack(); this.setLocationRelativeTo(null); this.setVisible(true); } } private static class CircuitTracePlot extends JPanel { public final static short LINE = 1; public final static short OVAL = 2; private int paintType; public CircuitTracePlot() { this.setBackground(Color.WHITE); } public void setPaintType(int paintType) { this.paintType = paintType; } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); switch (paintType) { case LINE: g.drawLine(10, 10, 30, 30); case OVAL: g.drawOval(10, 20, 30, 30); default: g.drawString("Huh?", 5, 16); } } @Override public Dimension getPreferredSize() { return new Dimension(250, 250); } } } 
+2
source

All Articles