Search code examples
javaswingjlabel

Change Label text from different class in java


I have a main gui class which has been made in the NetBeans gui builder. I am creating a mini game where the JLabel timer goes down. The JLabel is located in the main gui and the timer is located in a separate classes called timer for instance. When the loop for the timer is looping, I want the JLabel located in the main gui to change (Timer=10, Timer=9, ...etc).

Review the sample code below for a better understanding.

This is the class where the timer is located:

public class ShapeGame {

Timer timer;
int counter = 10;

ShapeGame() {

    ActionListener a = new ActionListener() {
        public void actionPerformed(ActionEvent e) {

            System.out.println("Counter = " + counter);
            labTimer.setText("Timer: " + counter);
            if (--counter < 0) {
                timer.stop();
                System.exit(0);
            }
        }
    };

    timer = new Timer(1000, a);
    timer.start();
    }
}

This is amended code for where the JLabel is located:

(NOTE: not all code has been added for the JLabel and JFrame just for reading purposes)

public class mainGui extends JFrame {

labTimer = new javax.swing.JLabel();

    private void gameStartStopActionPerformed(java.awt.event.ActionEvent evt) {                                              
        ShapeGame sg = new ShapeGame();
    }
}

I understand this is not the correct way to call the Label from a different class labTimer.setText("Timer: " + counter);. Hope I have provided enough information to help solve this problem.


Solution

  • One possible simple (but not clean) solution is to pass the JLabel into the ShapeGame class so that it can mutate its state directly.

    e.g.,

    public class ShapeGame {
        Timer timer;
        int counter = 10;
    
        // note change to constructor parameter
        public ShapeGame(final JLabel label) {
            ActionListener a = new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    System.out.println("Counter = " + counter);
    
                    // note changes
                    // labTimer.setText("Timer: " + counter);
                    label.setText("Timer: " + counter);
    
                    if (--counter < 0) {
                        timer.stop();
                        System.exit(0);
                    }
                }
            };
    
            timer = new Timer(1000, a);
            timer.start();
        }
    }
    

    Then when creating the ShapeGame class, pass the JLabel into its constructor call. Cleaner would be to structure your program a la MVC.