0

My problem is, when I press a button paintComponent should be called then a figure should be drawn on the JPanel, Unfortunately paintComponent draws the figure when the program is loaded, in that case the button is useless.

I made a small version of my program, to make it easy and fast to read and detect the problem. This code here is not the original one but it demonstrates the same problem.

import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JPanel;

public class TestPaint extends JPanel implements ActionListener {

    private JButton button_1 = new JButton( "Draw Oval" );

    public TestPaint() {

        add(button_1);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if ( e.getSource() == button_1 )
            repaint();
    }

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        g.drawOval(10, 10, 100, 100);
    }
}

To run the program

import javax.swing.JFrame;

public class RunPaint {

    public static void main(String[] args) {

        TestPaint paint_g = new TestPaint();

        JFrame frame = new JFrame("Testing");
        frame.add(paint_g);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(300, 300);
        frame.setVisible(true);
    }
}
  • 1
    *"My problem is,.."* OK, but what is your actual question? For example, if the question is *"Why does the GUI paint before I call `repaint()` in the code?"*, it seems to me that neither answer directly addresses that, at least not before links are followed.. But again, ..what is *your* question? – Andrew Thompson Jan 06 '15 at 07:08
  • Mr Andrew Thompson, I wish you spent more time reading my post than you do writing your comment, maybe then you will figure out what is my question. –  Jan 07 '15 at 14:37
  • *"..maybe then you will figure out what is my question."* Why should I bother trying? After all, there are plenty of people asking questions for whom we don't have to think even for a moment what their question is, because they took care to form and ask a specific question. Good luck with this.. – Andrew Thompson Jan 09 '15 at 07:53

2 Answers2

6

As a simple solution you can create an instance variable for your class:

private Boolean buttonPressed = false;

Then in your actionListener you set the value to true.

and in your paintComponent() method you add code like:

if (buttonPressed)
    g.drawOval(...);

A better (and more complicated solution) is to keep a List of objects to paint. Initially the List will be empty, and when you press the button you add an object to the List. Then the painting code just iterates through the List to paint the objects.

Check out Custom Painting Approaches for more ideas. The example code doesn't do exactly this, but it does show how to paint from a List.

camickr
  • 321,443
  • 19
  • 166
  • 288
  • I did try using a Boolean variable, but nothing is drawn when the button is pressed, no shape is displayed at all. –  Jan 07 '15 at 14:26
  • The simplest solution I found is, to use anonymous inner class instead and add a boolean instance variable to control when and what paintComponent should draw. What I really want to understand is why the original version didn't work, and why this version works. As for me, making something work is "good", but understanding how it works is "great". –  Jan 07 '15 at 14:27
  • @BilalKorir, well you still don't understand how it works. There is no need to create an anonymous inner class. All the painting logic should be contained in the `TestPaint` class as I suggested. If it didn't work, then you implemented the suggestion incorrectly. – camickr Jan 07 '15 at 15:39
  • I believe I did implement using instance boolean variable correctly. even though I finished my task I still want to understand WHY. programming is all about logic, eventually the problem will be detected. Thank you for your comments, appreciated. –  Jan 08 '15 at 02:04
  • @BilalKorir `I believe I did implement using instance boolean variable correctly.` - it didn't work so how can it be implemented correctly??? `I finished my task` - with an overly complicated solution, so I would say the task is not finished. – camickr Jan 08 '15 at 02:47
3

Let your actionPerformed() implementation add the desired geometric figure to a List<Shape> and have paintComponent() iterate through the list to render the shapes. A complete example is seen here.

Community
  • 1
  • 1
trashgod
  • 203,806
  • 29
  • 246
  • 1,045