为什么即使在调用 repaint() 时,该程序也不重绘小程序的特定部分
Why isn't this program repainting a certain part of an applet even when repaint() is called
这是一个简单的剪刀石头布小程序。有 3 个变量跟踪获胜、失败和平局。然后有一个标签用于显示它们。当我使用调试器时,重绘方法被调用,所以我不明白为什么这部分小程序没有更新。
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 中的文本。换句话说,要更改此 JLabel 和类似组件中的文本,您必须专门调用
lblTally.setText(someNewString);
- 问题 2:您还隐藏了 lblTally 变量——您在构造函数中重新声明并重新初始化该变量,这意味着 GUI 中显示的 JLabel 对象与class 字段引用的一个——不要这样做。声明变量并仅使用有效引用对其进行初始化一次。
其他附带问题(与您的问题没有直接关系的问题)是:
- 您正在使用
null
布局。您将希望避免使用空布局和使用 setBounds(...)
来放置组件,因为这会导致 GUI 非常不灵活,虽然它们在一个平台上看起来不错,但在大多数其他平台或屏幕分辨率上看起来很糟糕,而且非常困难更新和维护。
- 你的小程序没有
init()
方法,应该让小程序起来的方法和运行.
- 在 JLabel 中更改文本后无需调用
revalidate()
或 repaint()
。
简而言之shell,你正在做的是:
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);
}
}
另外,你问:
so what would you do instead of set bounds? I'm just starting to learn gui apps so excuse me if this is a very in depth question.
而不是 setBounds()
,使用布局管理器为您处理所有繁重的布局工作。 Google Swing 布局管理器教程,看看。
这是一个简单的剪刀石头布小程序。有 3 个变量跟踪获胜、失败和平局。然后有一个标签用于显示它们。当我使用调试器时,重绘方法被调用,所以我不明白为什么这部分小程序没有更新。
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 中的文本。换句话说,要更改此 JLabel 和类似组件中的文本,您必须专门调用
lblTally.setText(someNewString);
- 问题 2:您还隐藏了 lblTally 变量——您在构造函数中重新声明并重新初始化该变量,这意味着 GUI 中显示的 JLabel 对象与class 字段引用的一个——不要这样做。声明变量并仅使用有效引用对其进行初始化一次。
其他附带问题(与您的问题没有直接关系的问题)是:
- 您正在使用
null
布局。您将希望避免使用空布局和使用setBounds(...)
来放置组件,因为这会导致 GUI 非常不灵活,虽然它们在一个平台上看起来不错,但在大多数其他平台或屏幕分辨率上看起来很糟糕,而且非常困难更新和维护。 - 你的小程序没有
init()
方法,应该让小程序起来的方法和运行. - 在 JLabel 中更改文本后无需调用
revalidate()
或repaint()
。
简而言之shell,你正在做的是:
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);
}
}
另外,你问:
so what would you do instead of set bounds? I'm just starting to learn gui apps so excuse me if this is a very in depth question.
而不是 setBounds()
,使用布局管理器为您处理所有繁重的布局工作。 Google Swing 布局管理器教程,看看。