Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I assume you are drawing to the <code>JPanel</code> by using <code>getGraphics()</code> and rendering your out put to it.</p> <p>You have now seen why you shouldn't do this. When the component is repainted, anything previously painted to is wiped cleaned and you are expected to repaint the contents.</p> <p>Start by overriding <code>paintComponent</code> and updating all the lines within this method (don't forget to call <code>super.paintComponent</code></p> <p>See <a href="http://docs.oracle.com/javase/tutorial/uiswing/painting/" rel="nofollow noreferrer">Performing Custom Painting</a> and <a href="http://www.oracle.com/technetwork/java/painting-140037.html" rel="nofollow noreferrer">Painting in AWT and Swing</a> for more details</p> <p>For example..</p> <ul> <li><a href="https://stackoverflow.com/questions/12683533/drawing-a-rectangle-that-wont-disappear-in-next-paint/12683601#12683601">Drawing a rectangle that won&#39;t disappear in next paint</a></li> <li><a href="https://stackoverflow.com/questions/14764157/mouseevent-is-not-registering-a-release-when-i-release-the-mouse-button/14764264#14764264">MouseEvent is not registering a release when I release the mouse button</a></li> </ul> <p><strong>Updated with example</strong></p> <p>This is a modified version of the answer to <a href="https://stackoverflow.com/questions/14764157/mouseevent-is-not-registering-a-release-when-i-release-the-mouse-button/14764264#14764264">MouseEvent is not registering a release when I release the mouse button</a> which includes a scroll pane...</p> <p><img src="https://i.stack.imgur.com/SWjSJ.png" alt="enter image description here"></p> <pre><code>import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Point; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.UIManager; public class MouseDraggedTest { public static void main(String[] args) { new MouseDraggedTest(); } public MouseDraggedTest() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (Exception ex) { } JFrame frame = new JFrame("Test"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.add(new JScrollPane(new TestPane())); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class TestPane extends JPanel { private Map&lt;Point, List&lt;Point&gt;&gt; mapPoints; private Point currentPoint; public TestPane() { mapPoints = new HashMap&lt;&gt;(25); MouseAdapter mouseListener = new MouseAdapter() { @Override public void mousePressed(MouseEvent e) { currentPoint = e.getPoint(); mapPoints.put(currentPoint, new ArrayList&lt;Point&gt;(25)); } @Override public void mouseReleased(MouseEvent e) { List&lt;Point&gt; points = mapPoints.get(currentPoint); if (points.isEmpty()) { mapPoints.remove(currentPoint); } currentPoint = null; } @Override public void mouseDragged(MouseEvent me) { List&lt;Point&gt; points = mapPoints.get(currentPoint); points.add(me.getPoint()); repaint(); } }; addMouseListener(mouseListener); addMouseMotionListener(mouseListener); } @Override public Dimension getPreferredSize() { return new Dimension(200, 800); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); for (Point startPoint : mapPoints.keySet()) { List&lt;Point&gt; points = mapPoints.get(startPoint); for (Point p : points) { if (startPoint != null) { g.drawLine(startPoint.x, startPoint.y, p.x, p.y); } startPoint = p; } } } } } </code></pre> <p><strong>Updated with a BufferedImage example</strong></p> <p>Because you need to supply more operations than just drawing, you may find it easier to use <code>BufferedImage</code> as your primary drawing surface and render this to your <code>DrawingPanel</code></p> <p><img src="https://i.stack.imgur.com/JL7vO.png" alt="enter image description here"></p> <pre><code>import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.Point; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.awt.geom.Ellipse2D; import java.awt.geom.Line2D; import java.awt.image.BufferedImage; import javax.swing.ButtonGroup; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToggleButton; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; public class MyPicture { public static void main(String[] args) { new MyPicture(); } public MyPicture() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { } JFrame frame = new JFrame("Testing"); frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); frame.setLayout(new BorderLayout()); frame.add(new TestPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public enum DrawOperation { Draw, Erase } public class TestPane extends JPanel { private DrawOperation op; private JToggleButton pencil; private JToggleButton eraser; private DrawPane drawPane; public TestPane() { setLayout(new BorderLayout()); drawPane = new DrawPane(); MouseAdapter adapter = new MouseAdapter() { private Point startPoint; @Override public void mouseEntered(MouseEvent e) { drawPane.updateDrawCursor(e.getPoint(), op); } @Override public void mouseExited(MouseEvent e) { drawPane.removeDrawCursor(); } @Override public void mousePressed(MouseEvent e) { startPoint = e.getPoint(); } @Override public void mouseReleased(MouseEvent e) { startPoint = null; } @Override public void mouseDragged(MouseEvent e) { drawPane.applyOperation(startPoint, e.getPoint(), op); drawPane.updateDrawCursor(e.getPoint(), op); startPoint = e.getPoint(); } @Override public void mouseMoved(MouseEvent e) { drawPane.updateDrawCursor(e.getPoint(), op); } }; drawPane.addMouseListener(adapter); drawPane.addMouseMotionListener(adapter); JPanel operations = new JPanel(new GridBagLayout()); GridBagConstraints gbc = new GridBagConstraints(); gbc.gridwidth = GridBagConstraints.REMAINDER; pencil = new JToggleButton("Draw"); eraser = new JToggleButton("Erase"); ButtonGroup bgOps = new ButtonGroup(); bgOps.add(pencil); bgOps.add(eraser); operations.add(pencil, gbc); operations.add(eraser, gbc); pencil.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { op = DrawOperation.Draw; } }); eraser.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { op = DrawOperation.Erase; } }); add(operations, BorderLayout.WEST); add(new JScrollPane(drawPane)); } } public class DrawPane extends JPanel { private BufferedImage image; private Shape drawCursor; private Point cursorPoint; private int eraseSize = 20; public DrawPane() { image = new BufferedImage(400, 400, BufferedImage.TYPE_INT_RGB); Graphics2D g2d = image.createGraphics(); g2d.setBackground(Color.WHITE); g2d.fillRect(0, 0, 400, 400); g2d.dispose(); } @Override public Dimension getPreferredSize() { return new Dimension(400, 400); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); Graphics2D g2d = (Graphics2D) g.create(); if (image != null) { g2d.drawImage(image, 0, 0, this); } if (drawCursor != null &amp;&amp; cursorPoint != null) { int x = (cursorPoint.x - (drawCursor.getBounds().width) / 2); int y = (cursorPoint.y - (drawCursor.getBounds().height) / 2); g2d.translate(x, y); g2d.draw(drawCursor); g2d.translate(-x, -y); } g2d.dispose(); } public void updateDrawCursor(Point point, DrawOperation op) { cursorPoint = point; if (op != null) { switch (op) { case Draw: drawCursor = new Ellipse2D.Float(0, 0, 4, 4); break; case Erase: drawCursor = new Ellipse2D.Float(0, 0, eraseSize, eraseSize); break; } } else { drawCursor = null; } repaint(); } protected void removeDrawCursor() { drawCursor = null; repaint(); } protected void applyOperation(Point fromPoint, Point toPoint, DrawOperation op) { if (image != null) { if (op != null) { Graphics2D g2d = image.createGraphics(); switch (op) { case Draw: g2d.setColor(Color.BLACK); g2d.draw(new Line2D.Float(fromPoint, toPoint)); break; case Erase: g2d.setColor(Color.WHITE); g2d.setStroke(new BasicStroke(eraseSize)); g2d.draw(new Line2D.Float(fromPoint, toPoint)); break; } g2d.dispose(); } } repaint(); } } } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload