ez4nick
ez4nick

Reputation: 10199

repaint() method does not function as expected

I have 2 buttons, a reset button and a calculate button.
The only purpose of the reset button is to repaint a JPanel called p1.
The purpose of the calculate button is to make a calculation and update a JLabel.

The issue is that when the reset button is pressed, followed by the calculate button, the JPanel is repainted and it should not be (see code below where the repaint method is not present in the ActionListener() for calculateButton).

I am wondering why this is happening, and what I can do to stop the JPanel from being repainted when this button is pressed (the reset button's functions exactly as expected, by repainting the panel).

public class DrawCircles extends JFrame {


    //the following are x and y locations of the centers of the circles
    int center1X;
    int center1Y;
    int center2X;
    int center2Y;
    int center3X;
    int center3Y;

    public DrawCircles(){


        final CircleDraw c = new CircleDraw();   //create a circledraw object to get the area of the triangle between them

        final JPanel p1 = new JPanel();          //first panel to hold all other panels making the layout
        JPanel buttonPanel = new JPanel();

        p1.setLayout(new BorderLayout());  //set the layout of the panel to a border layout

        JButton areaTriangle = new JButton("Calculate area of triangle");
        JButton perimeterTriangle = new JButton("Calculate perimeter of triangle");
        JButton reset = new JButton("Reset");

        buttonPanel.setLayout(new BoxLayout(buttonPanel,0));
        buttonPanel.add(areaTriangle);
        buttonPanel.add(Box.createRigidArea(new Dimension(15,0)));
        buttonPanel.add(perimeterTriangle);
        buttonPanel.add(Box.createRigidArea(new Dimension(15,0)));
        buttonPanel.add(reset);      //add a button that says reset

        reset.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
               p1.repaint();  //redraw the circles and triangle
               areaLabel.setText(""); //clear the label

            }
        });


        calculateButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {

               areaLabel.setText("Area is "+ String.valueOf(2.0*c.getArea()));

            }
        });

        resetButton.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                areaLabel.setText("");  
            }
        });

        add(p1);                                      


    }


    public class CircleDraw extends JPanel {

    int radius;   
    double s;     
    double area;  

    public CircleDraw(){

    }

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


        Random rand = new Random(System.currentTimeMillis());
        center1X=rand.nextInt(507);
        center1Y=rand.nextInt(320);
        center2X=rand.nextInt(507);
        center2Y=rand.nextInt(320);
        center3X=rand.nextInt(507);
        center3Y=rand.nextInt(320);

        //draw the 3 circles
        g.drawOval(center1X, center1Y, 100,100);
        g.drawOval(center2X, center2Y,100,100);
        g.drawOval(center3X, center3Y, 100, 100);

        //connect the centers of the circles with lines
        g.drawLine(center1X+50, center1Y+50, center2X+50, center2Y+50);
        g.drawLine(center2X+50, center2Y+50, center3X+50, center3Y+50);
        g.drawLine(center3X+50, center3Y+50, center1X+50, center1Y+50);


    }


    }
    public static void main(String[] args)  {
    DrawCircles frame = new DrawCircles();
    frame.setSize(700,500);
    frame.setLocationRelativeTo(null);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setVisible(true);


    }


    }

Upvotes: 1

Views: 166

Answers (1)

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

You state:

The issue is that when the reset button is pressed, followed by the calculate button the panel is repainted and it should not be. (See code below where the repaint method is not present in the ActionListener() for calculateButton). I am wondering why this is happening, and what I can do to stop the panel from being repainted when this button is pressed. (The reset button functions exactly as expected, by repainting the panel).

It is impossible to guess what could be wrong based on the code you've posted so far. I urge you to consider creating and posting a minimal example program that allows us to see your problem for ourselves.

But having said that, I will add that you never have full control over when a component is painted or not, since many paintings are driven by the JVM responding to the operating system. This is one reason that program logic should never reside within a paint(Graphics g) or paintComponent(Graphics g) method override.

So your problem is really an XY Problem in disguise. You ask how to control the repainting of a component when you should instead be asking how to get your program logic out of one of the painting methods, and in fact this is my guess at the solution to your problem -- make sure that your painting method is used solely for painting and nothing else.


Edit
Yep, you have program logic within the paintComponent method, specifically this code:

Random rand = new Random(System.currentTimeMillis());
center1X=rand.nextInt(507);
center1Y=rand.nextInt(320);
center2X=rand.nextInt(507);
center2Y=rand.nextInt(320);
center3X=rand.nextInt(507);
center3Y=rand.nextInt(320);

Get it out of paintComponent and in its own method that will allow you to control when it is called.


Edit 2
For example, you could do this:

public class CircleDraw extends JPanel {
  private int radius;
  private double s;
  private double area;
  private Random rand = new Random(); // make this a field

  // call this when you want to change the random images
  public void randomizeDrawing() {
     center1X = rand.nextInt(507);
     center1Y = rand.nextInt(320);
     center2X = rand.nextInt(507);
     center2Y = rand.nextInt(320);
     center3X = rand.nextInt(507);
     center3Y = rand.nextInt(320);
     repaint();
  }

  // and only do painting in paintComponent
  @Override
  protected void paintComponent(Graphics g) {
     super.paintComponent(g);

     // draw the 3 circles
     g.drawOval(center1X, center1Y, 100, 100);
     g.drawOval(center2X, center2Y, 100, 100);
     g.drawOval(center3X, center3Y, 100, 100);

     // connect the centers of the circles with lines
     g.drawLine(center1X + 50, center1Y + 50, center2X + 50, center2Y + 50);
     g.drawLine(center2X + 50, center2Y + 50, center3X + 50, center3Y + 50);
     g.drawLine(center3X + 50, center3Y + 50, center1X + 50, center1Y + 50);
  }

Upvotes: 4

Related Questions