Why isn't this program repainting a certain part of an applet even when repaint() is called

72 views Asked by At

This is a simple rock, paper, scissors appelet. there are 3 variables keeping track of wins, losses, and ties. Then there is a label that is meant to display them. When I used the debugger the repaint method is being called so I don't understand why this portion of the applet isn't updating.

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

There are 1 answers

3
Hovercraft Full Of Eels On BEST ANSWER
  • Issue number 1: You never change the text in the tally JLabel, lblTally. In other words, for the text in this JLabel and similar components to change you must specifically call, lblTally.setText(someNewString);
  • Issue number 2: you're also shadowing the lblTally variable -- you're re-declaring and re-initializing the variable in the constructor, meaning that the JLabel object displayed in the GUI is not the same as the one that the class field refers to -- don't do this. Declare the variable and initialize it with a valid reference only once.

Other side issues (issues not directly related to your problem) are:

  • You're using a null layout. You will want to avoid use of null layout and use of setBounds(...) for component placement as this makes for very inflexible GUI's that while they might look good on one platform look terrible on most other platforms or screen resolutions and that are very difficult to update and maintain.
  • Your applet has no init() method, the method that should get the applet up and running.
  • There is no need to call revalidate() or repaint() after changing text in a JLabel.

In a nut shell, what you're doing is this:

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

When you should be doing this:

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

Also, you ask:

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.

Instead of setBounds(), use layout managers to handle all the layout heavy lifting for you. Google the Swing layout manager tutorial and have a look.