Java Jpanels 按钮在调用重绘后移动到屏幕的左上角。我如何同时重新修复 Jpanel 以使其保持正常?

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?

你好,当我要求重新绘制按钮时,我遇到了一个问题,按钮保留在它们应该在的位置,但它们也被复制并放置在屏幕的左上角。

我正在使用的文本也会发生这种情况我实际上知道这个问题。

问题是 frame/panel 得到了更新,但它也保留了按钮和文本的 regular/old 位置,但它也对代码添加了新的更改,导致它们发生冲突。

所以问题是我如何做到这一点,以便在调用重绘后东西不会四处移动?

我重新使用我之前问题中的代码,因为您可以在 运行.

中看到问题
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);

        }   
       
   }
}

您可以尝试在 getRootPane()

上调用 repaint
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 buttons remain where they should be but they also gets copied and gets placed on the top left side of the screen.

你画错了:

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

你打破了绘画链,背景没有被清除,所以你得到了绘画工件。

您应该使用:

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

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

阅读 Custom Painting 上的 Swing 教程以获取更多信息和工作示例。

代码的其他问题:

  1. 不要使用“==”进行字符串比较。相反,您应该使用 equals(...) 方法。

  2. 不要使用空布局和 setBounds(...)。 Swing 旨在与布局管理器一起使用。

  3. 应在框架可见之前将组件添加到框架。

  4. 通常 class 的 属性 有“getter/setter”方法。就像 JLabel 有 setText(...) 和 getText()。您的“selector(...)”方法应该是 setSelector(...) 以便人们知道您正在更改影响组件绘制方式的 class 的 属性。