1

Hello I have an issue when I call for repaint that the buttons remain where they should be but they also gets copied and gets placed on the top left side of the screen.

This also happens with text I am using I know the issue actually.

The issue is that the frame/panel gets updated but it also is keeping the regular/old positions of the buttons and text, but it also adds new changes to the code causing them to collide.

So the question is how do I make it so things aren't moving around after repaint is called?

I re use the code from my previous question as you can see the issue when it's being run.

public class RockPaperScissors implements ActionListener {
 JButton rock =new JButton("Select rock");  
 JButton paper =new JButton("Select paper");  
 JButton scissors =new JButton("Select scissors");  
 Gui gui = new Gui();  


public void frame() {
     JFrame b = new JFrame("Rock paper scissors");
     rock.setBounds(150,100,120,30);  
     paper.setBounds(350,100,120,30);  
     scissors.setBounds(550,100,120,30);
     b.setSize(905,705);
     b.setLocation(300,60);
     b.setResizable(false);
     b.setVisible(true);
     b.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);        
     b.setResizable(false);
     b.setVisible(true);
     b.add(rock);
     b.add(paper);
     b.add(scissors);
     rock.addActionListener(this);
     paper.addActionListener(this);
     scissors.addActionListener(this);
     b.add(gui);

}

public static  void main(String[] args) {
    RockPaperScissors start = new RockPaperScissors();
    start.frame();



}

@Override
  public void actionPerformed(ActionEvent e) {
     
        if (e.getSource() == rock){
            gui.selector("rock");

        } else if (e.getSource() == paper) {
            gui.selector("paper");
        } else if (e.getSource() == scissors) {
            gui.selector("scissors");
}






public class Gui extends JPanel {

   private int y;
   public void paint(Graphics g) {
        g.setColor(Color.white);
        g.fillRect(50, 300, 300, 300);
        g.setColor(Color.white);
        g.fillRect(550, 300, 300, 300);
        


        
        if (y == 1) {
            g.setColor(Color.blue);
            g.fillRect(50, 300, 300, 300);
        }
        if (y == 2) {
            g.setColor(Color.black);
            g.fillRect(50, 300, 300, 300);
        }
        if (y == 3) {
            g.setColor(Color.yellow);
            g.fillRect(50, 300, 300, 300);

        }
        
       }
   

   public void selector(String x){
        if (x == "paper"){
            y = 1;
              repaint();

            System.out.println("paper" + y);

        } else if (x == "rock") {
            y = 2;
              repaint();

            System.out.println("rock" + y);

        } else if (x == "scissors") {
            y = 3;
              repaint();

            System.out.println("scissors" + y);

        }   
       
   }
}

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
jon doe
  • 37
  • 4
  • 2
    I don’t know yet if this is the cause of your stated problem, but I know it will be a problem: https://stackoverflow.com/questions/513832/how-do-i-compare-strings-in-java – VGR Jul 02 '21 at 11:34
  • @VGR nah dude it's not the cause of the issue, I stated what the issue is but I don't know how to fix it. – jon doe Jul 02 '21 at 11:53

2 Answers2

2

the buttons remain where they should be but they also gets copied and gets placed on the top left side of the screen.

You are doing painting incorrectly:

public void paint(Graphics g) 
{
     g.setColor(Color.white);

You are breaking the paint chain and the background is not cleared so you get painting artifacts.

Instead you should be using:

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

     g.setColor(Color.white);
     ...

Read the Swing tutorial on Custom Painting for more information and working examples.

Other issues with the code:

  1. Don't use "==" for String comparison. Instead you should be using the equals(...) method.

  2. Don't use a null layout and setBounds(...). Swing was designed to be used with layout managers.

  3. Components should be added to the frame BEFORE the frame is made visible.

  4. Usually a property of a class has "getter/setter" methods. Like JLabel has setText(...) and getText(). Your "selector(...)" method should be setSelector(...) so people know you are changing a property of the class that affects the way the component is painted.

camickr
  • 321,443
  • 19
  • 166
  • 288
-1

You can try to call the repaint on the getRootPane()

public void selector(String x){
    if ("paper".equals(x)){
        y = 1;
        System.out.println("paper" + y);
    } else if ("rock".equals(x)) {
        y = 2;
        System.out.println("rock" + y);
    } else if ("scissors".equals(x)) {
        y = 3;
        System.out.println("scissors" + y);
    }
    getRootPane().repaint();
}
Butiri Dan
  • 1,759
  • 5
  • 12
  • 18
  • Ah yes, thank you works completely fine, also thank you introduciing something new to me. – jon doe Jul 02 '21 at 12:48
  • 1
    (1-) You do NOT need to invoke repaint() on the root pane. This issue is that the custom painting is done incorrectly. 1) Custom painting is done by overriding `paintComponent(...)`, not paint(). 2) the first statement will then be `super.paintCompnent(...)` to make sure the background is cleared before you do the custom painting. Read the Swing tutorial on [Custom Painting](https://docs.oracle.com/javase/tutorial/uiswing/painting/index.html) for more information and working examples. – camickr Jul 02 '21 at 13:50