Java 为什么不是';t此程序即使在调用repaint()时也会重新绘制小程序的特定部分

Java 为什么不是';t此程序即使在调用repaint()时也会重新绘制小程序的特定部分,java,swing,applet,label,repaint,Java,Swing,Applet,Label,Repaint,这是一个简单的石头,布,剪刀。有3个变量跟踪赢、输和平局。然后是一个用来显示它们的标签。当我使用调试器时,正在调用repaint方法,因此我不理解小程序的这一部分为什么没有更新 import java.awt.Font; import java.awt.Graphics; import javax.swing.JApplet; import javax.swing.JLabel; import javax.swing.JButton; import java.awt.event.Action

这是一个简单的石头,布,剪刀。有3个变量跟踪赢、输和平局。然后是一个用来显示它们的标签。当我使用调试器时,正在调用repaint方法,因此我不理解小程序的这一部分为什么没有更新

import java.awt.Font;
import java.awt.Graphics;

import javax.swing.JApplet;
import javax.swing.JLabel;
import javax.swing.JButton;

import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Random;

public class JRockPaperScissors extends JApplet {
    JLabel lblDescision = new JLabel("descision");
    JLabel lblWinner = new JLabel("winner");
    JLabel lblTally = new JLabel("tally");
    int tally_user = 0;
    int tally_comp = 0;
    int tally_ties = 0;



/**
 * Create the applet.
 */
public JRockPaperScissors() {
        setSize(500,500);
        getContentPane().setLayout(null);



    JLabel lblRockPaperScissors = new JLabel("Rock, Paper, Scissors");
    lblRockPaperScissors.setBounds(95, 50, 280, 48);
    getContentPane().add(lblRockPaperScissors);
    Font arial_1 = new Font("Arial", Font.BOLD, 25);
    lblRockPaperScissors.setFont(arial_1);

    JLabel lblChooseOneButton = new JLabel("Choose one button");
    lblChooseOneButton.setBounds(10, 93, 146, 25);
    getContentPane().add(lblChooseOneButton);
    Font arial_2 = new Font("Arial", Font.BOLD, 15);
    lblChooseOneButton.setFont(arial_2);

    JButton btnRock = new JButton("Rock");
    btnRock.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            determine_winner(0);
            repaint();
        }
    });
    btnRock.setBounds(166, 95, 89, 23);
    getContentPane().add(btnRock);

    JButton btnPaper = new JButton("Paper");
    btnPaper.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            determine_winner(1);
        }
    });
    btnPaper.setBounds(265, 95, 89, 23);
    getContentPane().add(btnPaper);

    JButton btnScissors = new JButton("Scissors");
    btnScissors.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            determine_winner(2);
        }
    });
    btnScissors.setBounds(361, 95, 89, 23);
    getContentPane().add(btnScissors);

    JLabel lblresults = new JLabel("------Results------");
    lblresults.setBounds(20, 114, 126, 25);
    getContentPane().add(lblresults);
    Font arial_3 = new Font("Arial", Font.BOLD, 15);
    lblresults.setFont(arial_3);

    lblDescision.setBounds(30, 150, 311, 14);
    getContentPane().add(lblDescision);

    lblWinner.setBounds(20, 175, 146, 14);
    getContentPane().add(lblWinner);

    JLabel lblTally = new JLabel("You:" + tally_user + "    Computer:" + tally_comp + 
            "    Ties:"+ tally_ties);
    lblTally.setBounds(20, 214, 201, 30);
    getContentPane().add(lblTally);


}

public void determine_winner(int user_choice){
    Random random = new Random();
    int computer_choice = random.nextInt(3);
    if(user_choice == 0 ){
        if(computer_choice ==0){
            lblDescision.setText("You picked Rock --- Computer picked Rock");
            lblWinner.setText("Winner: Tie");
            tally_ties +=1;
        }
        else if(computer_choice ==1){
            lblDescision.setText("You picked Rock --- Computer picked Paper");
            lblWinner.setText("Winner: Computer");
            tally_comp +=1;

        }
        else if(computer_choice ==2){
            lblDescision.setText("You picked Rock --- Computer picked Scissors");
            lblWinner.setText("Winner: You");
            tally_user +=1;

        }
    }
    else if(user_choice == 1){
        if(computer_choice ==0){
            lblDescision.setText("You picked Paper --- Computer picked Rock");
            lblWinner.setText("Winner: You");
            tally_user +=1;
        }
        else if(computer_choice ==1){
            lblDescision.setText("You picked Paper --- Computer picked Paper");
            lblWinner.setText("Winner: Tie");
            tally_ties +=1;
        }
        else if(computer_choice ==2){
            lblDescision.setText("You picked Paper --- Computer picked Scissors");
            lblWinner.setText("Winner: Computer");
            tally_comp +=1;
        }
    }
    else if(user_choice == 2){
        if(computer_choice ==0){
            lblDescision.setText("You picked Scissors --- Computer picked Rock");
            lblWinner.setText("Winner: Computer");
            tally_comp +=1;
        }
        else if(computer_choice ==1){
            lblDescision.setText("You picked Scissors --- Computer picked Paper");
            lblWinner.setText("Winner: You");
            tally_user +=1;
        }
        else if(computer_choice ==2){
            lblDescision.setText("You picked Scissors --- Computer picked Scissors");
            lblWinner.setText("Winner: Tie");
            tally_ties +=1;
        }
    }
revalidate();
repaint();
}

}
  • 问题1:你永远不会改变标签上的文字。换句话说,对于要更改的JLabel和类似组件中的文本,必须专门调用,
    lblTally.setText(someNewString)
  • 问题2:您还隐藏了lblTally变量——您在构造函数中声明并重新初始化该变量,这意味着GUI中显示的JLabel对象与类字段引用的对象不同——不要这样做。声明变量并仅用有效引用初始化它一次
其他附带问题(与您的问题不直接相关的问题)包括:

  • 您正在使用
    null
    布局。您将希望避免在组件放置中使用空布局和
    setBounds(…)
    ,因为这会导致非常不灵活的GUI,虽然它们在一个平台上看起来不错,但在大多数其他平台或屏幕分辨率上看起来很差,并且很难更新和维护
  • 您的小程序没有
    init()
    方法,该方法应该使小程序启动并运行
  • 更改JLabel中的文本后,无需调用
    revalidate()
    repaint()

在坚果壳中,您要做的是:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class JRockPaperEtc extends JApplet {
   private static final String FORMAT_TXT = "Tally: %03d";
   private int tally = 0;
   private JLabel lblTally = new JLabel(String.format(FORMAT_TXT, tally));

   @Override
   public void init() {
      JPanel mainPanel = new JPanel();

      // *** Variable Shadowing here
      JLabel lblTally = new JLabel("Tally: 000");
      mainPanel.add(lblTally);

      JButton button = new JButton(new AbstractAction("Push") {

         @Override
         public void actionPerformed(ActionEvent e) {
            tally++;
            // *** lblTally's text is never changed
         }
      });
      mainPanel.add(button);

      add(mainPanel);
   }
}
当您应该这样做时:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class JRockPaperEtc2 extends JApplet {
   private static final String FORMAT_TXT = "Tally: %03d";
   private int tally = 0;
   private JLabel lblTally = new JLabel(String.format(FORMAT_TXT, tally));

   @Override
   public void init() {
      JPanel mainPanel = new JPanel();

      // lblTally = new JLabel("Tally: 000"); // *** no shadowing
      mainPanel.add(lblTally);

      JButton button = new JButton(new AbstractAction("Push") {

         @Override
         public void actionPerformed(ActionEvent e) {
            tally++;
            lblTally.setText(String.format(FORMAT_TXT, tally));
            // *** lblTally's text is now changed
         }
      });
      mainPanel.add(button);

      add(mainPanel);
   }
}
还有,你问:


那么你会怎么做而不是设定界限呢?我刚刚开始学习gui应用程序,如果这是一个非常深入的问题,请原谅

使用版面管理器代替
setBounds()
,为您处理所有版面繁重的工作。用谷歌搜索Swing布局管理器教程并看一看。

  • 问题1:你永远不会改变标签上的文字。换句话说,对于要更改的JLabel和类似组件中的文本,必须专门调用,
    lblTally.setText(someNewString)
  • 问题2:您还隐藏了lblTally变量——您在构造函数中声明并重新初始化该变量,这意味着GUI中显示的JLabel对象与类字段引用的对象不同——不要这样做。声明变量并仅用有效引用初始化它一次
其他附带问题(与您的问题不直接相关的问题)包括:

  • 您正在使用
    null
    布局。您将希望避免在组件放置中使用空布局和
    setBounds(…)
    ,因为这会导致非常不灵活的GUI,虽然它们在一个平台上看起来不错,但在大多数其他平台或屏幕分辨率上看起来很差,并且很难更新和维护
  • 您的小程序没有
    init()
    方法,该方法应该使小程序启动并运行
  • 更改JLabel中的文本后,无需调用
    revalidate()
    repaint()

在坚果壳中,您要做的是:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class JRockPaperEtc extends JApplet {
   private static final String FORMAT_TXT = "Tally: %03d";
   private int tally = 0;
   private JLabel lblTally = new JLabel(String.format(FORMAT_TXT, tally));

   @Override
   public void init() {
      JPanel mainPanel = new JPanel();

      // *** Variable Shadowing here
      JLabel lblTally = new JLabel("Tally: 000");
      mainPanel.add(lblTally);

      JButton button = new JButton(new AbstractAction("Push") {

         @Override
         public void actionPerformed(ActionEvent e) {
            tally++;
            // *** lblTally's text is never changed
         }
      });
      mainPanel.add(button);

      add(mainPanel);
   }
}
当您应该这样做时:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class JRockPaperEtc2 extends JApplet {
   private static final String FORMAT_TXT = "Tally: %03d";
   private int tally = 0;
   private JLabel lblTally = new JLabel(String.format(FORMAT_TXT, tally));

   @Override
   public void init() {
      JPanel mainPanel = new JPanel();

      // lblTally = new JLabel("Tally: 000"); // *** no shadowing
      mainPanel.add(lblTally);

      JButton button = new JButton(new AbstractAction("Push") {

         @Override
         public void actionPerformed(ActionEvent e) {
            tally++;
            lblTally.setText(String.format(FORMAT_TXT, tally));
            // *** lblTally's text is now changed
         }
      });
      mainPanel.add(button);

      add(mainPanel);
   }
}
还有,你问:


那么你会怎么做而不是设定界限呢?我刚刚开始学习gui应用程序,如果这是一个非常深入的问题,请原谅

使用版面管理器代替
setBounds()
,为您处理所有版面繁重的工作。用谷歌搜索Swing布局管理器教程并看一看。

  • 问题1:你永远不会改变标签上的文字。换句话说,对于要更改的JLabel和类似组件中的文本,必须专门调用,
    lblTally.setText(someNewString)
  • 问题2:您还隐藏了lblTally变量——您在构造函数中声明并重新初始化该变量,这意味着GUI中显示的JLabel对象与类字段引用的对象不同——不要这样做。声明变量并仅用有效引用初始化它一次
其他附带问题(与您的问题不直接相关的问题)包括:

  • 您正在使用
    null
    布局。您将希望避免在组件放置中使用空布局和
    setBounds(…)
    ,因为这会导致非常不灵活的GUI,虽然它们在一个平台上看起来不错,但在大多数其他平台或屏幕分辨率上看起来很差,并且很难更新和维护
  • 您的小程序没有
    init()
    方法,该方法应该使小程序启动并运行
  • 更改JLabel中的文本后,无需调用
    revalidate()
    repaint()

在坚果壳中,您要做的是:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class JRockPaperEtc extends JApplet {
   private static final String FORMAT_TXT = "Tally: %03d";
   private int tally = 0;
   private JLabel lblTally = new JLabel(String.format(FORMAT_TXT, tally));

   @Override
   public void init() {
      JPanel mainPanel = new JPanel();

      // *** Variable Shadowing here
      JLabel lblTally = new JLabel("Tally: 000");
      mainPanel.add(lblTally);

      JButton button = new JButton(new AbstractAction("Push") {

         @Override
         public void actionPerformed(ActionEvent e) {
            tally++;
            // *** lblTally's text is never changed
         }
      });
      mainPanel.add(button);

      add(mainPanel);
   }
}
当您应该这样做时:

import java.awt.event.ActionEvent;
import javax.swing.*;

public class JRockPaperEtc2 extends JApplet {
   private static final String FORMAT_TXT = "Tally: %03d";
   private int tally = 0;
   private JLabel lblTally = new JLabel(String.format(FORMAT_TXT, tally));

   @Override
   public void init() {
      JPanel mainPanel = new JPanel();

      // lblTally = new JLabel("Tally: 000"); // *** no shadowing
      mainPanel.add(lblTally);

      JButton button = new JButton(new AbstractAction("Push") {

         @Override
         public void actionPerformed(ActionEvent e) {
            tally++;
            lblTally.setText(String.format(FORMAT_TXT, tally));
            // *** lblTally's text is now changed
         }
      });
      mainPanel.add(button);

      add(mainPanel);
   }
}
还有,你问:


那么你会怎么做而不是设定界限呢?我刚刚开始学习gui应用程序,如果这是一个非常深入的问题,请原谅

使用版面管理器代替
setBounds()
,为您处理所有版面繁重的工作。用谷歌搜索Swing布局管理器教程并看一看。

  • 问题1:你永远不会改变标签上的文字。换句话说,对于要更改的JLabel和类似组件中的文本,必须专门调用,
    lblTally.setText(someNewString)
  • 问题2:您还隐藏了lblTally变量——您在构造函数中声明并重新初始化该变量,这意味着GUI中显示的JLabel对象与类字段引用的对象不同——不要这样做。声明变量并用