0

I am using JButton's Action listener to draw different shapes. It is working fine but how to keep previously drawn shapes on panel all time? Because when another button pressed previous shapes has gone.

jButton1.setText("Button1");
    jButton1.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton1ActionPerformed(evt);
        }
    });

jButton2.setText("Button2");
    jButton2.addActionListener(new java.awt.event.ActionListener() {
        public void actionPerformed(java.awt.event.ActionEvent evt) {
            jButton2ActionPerformed(evt);
        }
    });


private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
    // TODO add your handling code here:
    s = evt.getActionCommand();
    repaint();

}
private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
    s = evt.getActionCommand();
    repaint();

}

....... and paintComponent method is

 protected void paintComponent(Graphics g) {
        super.paintComponent(g);


        System.out.println("====>>> " + s);
        switch (s) {

            case "Button1":
                g.drawRoundRect(20,20,40,40,100,200);
                break;

            case "Button2":
                g.drawRect(0, 0, 200, 200);
                break;

            default:
                g.drawOval(40, 40, 100, 100);

Here String s contain pressed buttons caption.

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
iostream007
  • 107
  • 1
  • 10
  • The basic problem is, on each paint cycle, you will need to restore the graphics to what ever state you need it to be. That is, you will need to repaint anything your had previously painted (and want to keep) – MadProgrammer Apr 30 '13 at 07:38

3 Answers3

6

You could simply draw to a buffered image and display that image.

Demo code:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.image.BufferedImage;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

class TestPaint {

    private BufferedImage image;
    private JLabel drawing;

    private int x = 0;
    private int y = 0;

    protected void initUI() {
        JFrame jFrame = new JFrame();
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JButton jButton1 = new JButton();
        JButton jButton2 = new JButton();
        jButton1.setText("Button1");
        jButton1.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton1ActionPerformed(evt);
            }
        });

        jButton2.setText("Button2");
        jButton2.addActionListener(new java.awt.event.ActionListener() {
            @Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jButton2ActionPerformed(evt);
            }
        });

        image = new BufferedImage(500, 300, BufferedImage.TYPE_INT_RGB);
        image.getGraphics().setColor(Color.WHITE);
        image.getGraphics().fillRect(0, 0, image.getWidth(), image.getHeight());
        drawing = new JLabel(new ImageIcon(image));
        JPanel bottomPanel = new JPanel(new FlowLayout());
        JPanel buttonPanel = new JPanel(new GridLayout(1, 0));
        buttonPanel.add(jButton1);
        buttonPanel.add(jButton2);
        bottomPanel.add(buttonPanel);
        jFrame.add(drawing);
        jFrame.add(bottomPanel, BorderLayout.SOUTH);
        jFrame.pack();
        jFrame.setVisible(true);
    }

    private Graphics getImageGraphics() {
        return image.getGraphics();
    }

    private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
        Graphics g = getImageGraphics();
        g.setColor(Color.GREEN);
        g.drawRoundRect(x, y, 40, 40, 100, 200);
        drawing.repaint();
        x += 5;
        y += 5;
    }

    private void jButton2ActionPerformed(java.awt.event.ActionEvent evt) {
        Graphics g = getImageGraphics();
        g.setColor(Color.BLUE);
        g.drawRect(x, y, 200, 200);
        drawing.repaint();
        x += 5;
        y += 5;
    }

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestPaint().initUI();
            }

        });
    }
}
Guillaume Polet
  • 47,259
  • 4
  • 83
  • 117
5

Either of these should do:

  • Store all the drawing operations in a list and on paint, iterate the list and paint them all.

  • Draw the shapes to a BufferedImage and display the image in a label. E.G. As seen in this answer:

Community
  • 1
  • 1
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
  • your first alternative "Store all the drawing operations in a list and on paint, iterate the list and paint them all." How i'll do it please explain – iostream007 Apr 30 '13 at 08:48
  • Give it a try, post come code, and ask a more specific question. I am not about to spoon-feed an example to you. – Andrew Thompson Apr 30 '13 at 08:50
3

Custom Painting Approaches shows the two common approaches:

  1. paint the Objects contained in a List
  2. paint a BufferedImage containing all the objects.
camickr
  • 321,443
  • 19
  • 166
  • 288