简体   繁体   中英

Changing label text from another class JavaFX

I am trying to make a test program that has a button in one tab and a label in another. I want the button to add one to the label when pushed. The problem I'm having is that the label does not change when the button is pushed. How to I change label text from another class?

Here's the code:

Base

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Tab;
import javafx.scene.control.TabPane;
import javafx.stage.Stage;
import javafx.scene.control.TabPane.TabClosingPolicy;

public class Base extends Application {
    
    // Create tabs and the tab pane
    private TabPane tabPane;
    private Tab testTab1;
    private Tab testTab2;
    
    // Create menus
    private Test1 test1 = new Test1();
    private Test2 test2 = new Test2();
    
    //Constructor
    public Base() {
        
        // Instantiate tabs
        testTab1 = new Tab();
        testTab2 = new Tab();
        
        // Instantiate tab pane
        tabPane = new TabPane();
    
        // Add the panes to the TabPane
        testTab1.setText("Button");
        testTab2.setText("Label");
        tabPane.getTabs().addAll(testTab1, testTab2);
        
        tabPane.setTabClosingPolicy(TabClosingPolicy.UNAVAILABLE);
        
    }
    
    @Override
    public void start(Stage primaryStage) throws Exception {
        
        Scene scene = new Scene(tabPane, 700, 500);
        testTab1.setContent(test1);
        testTab2.setContent(test2);
        
        primaryStage.setScene(scene);
        primaryStage.setTitle("Test program");
        primaryStage.setResizable(false);
        
        primaryStage.show();
        
    }
    
    public static void main(String[] args) {
        launch(args);
    }
}

Test1

import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.scene.control.Button;
import javafx.scene.layout.Pane;

public class Test1 extends Pane {
    
    Test2 test2 = new Test2();
    
    Button testBt = new Button();
    
    public Test1() {
        testBt = new Button("Change label");
        testBt.setLayoutX(50);
        testBt.setLayoutY(50);
        
        getChildren().add(testBt);
        
        testBt.setOnAction (new EventHandler<ActionEvent>(){
            @Override
            public void handle ( ActionEvent e) {
                int newTest = test2.getTest() + 1;
                test2.setTest(newTest);
                test2.setLabel(test2.getTest());
            }
        });
    }
}

Test2

import javafx.scene.control.Label;
import javafx.scene.layout.Pane;
import javafx.scene.text.Font;

public class Test2 extends Pane {
    
    int test = 0;
    
    Label label = new Label("");
    
    public Test2() {
        
        label.setText("" + test);
        label.setFont(new Font("Arial Rounded MT Bold", 30));
        label.setLayoutX(50);
        label.setLayoutY(50);
        
        getChildren().add(label);
        
    }
    
    public int getTest() {
        return test;
    }
    
    public void setTest(int newTest) {
        test = newTest;
    }
    
    public void setLabel(int newLabel) {
        label.setText("" + newLabel);
    }
}

You are creating a two separate instances of Test2 , one in your Base class and the other in your Test1 class.

The one in your Base class is the real one because that is the one that has been added to your testTab like so testTab2.setContent(test2); .

The first order of business is to remove this line Test2 test2 = new Test2(); from the Test1 class, because it only confuses the situation and does nothing.

The next order of business is to work out how to pass the current/correct instance of the Test2 into the Test1 class. There are lots of ways to do that, but here is one solution that edits the Test1 class to include a createEvent method that lets us pass the correct reference of Test2 into the method:

public class Test1 extends Pane {
    
    //Delete or comment out the below line
    //Test2 test2 = new Test2();
    
    Button testBt = new Button();
    
    public Test1() {
        testBt = new Button("Change label");
        testBt.setLayoutX(50);
        testBt.setLayoutY(50);
        
        getChildren().add(testBt);
    }
    //New method
    public void createEvent(Test2 pane){
        testBt.setOnAction (new EventHandler<ActionEvent>(){
            @Override
            public void handle ( ActionEvent e) {
                //Here we can reference the pane object that was passed to the method
                int newTest = pane.getTest() + 1;
                pane.setTest(newTest);
                pane.setLabel(pane.getTest());
            }
        });
    }
}

Then in the Base constructor we can simply use the following line to create the event:

//Constructor
public Base() {
    //Insert this new line that calls the `createEvent` method and passes the correct test2 object
    test1.createEvent(test2);

Now it should all work as intended, with the value of the label incrementing by 1 each time the button in Test1 is clicked

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM