简体   繁体   中英

Java Jpanels button move to the top left side of screen after repaint is called. How do I also repain Jpanel at the same time so it remains normal?

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);

        }   
       
   }
}

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.

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();
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM