简体   繁体   English

如何在 Java (JavaFX) 中使用来自另一个 class 的 Label

[英]How to use a Label from another class in Java (JavaFX)

I need to use a Label that was created in another class in my JavaFx application我需要使用在我的 JavaFx 应用程序中的另一个 class 中创建的 Label

This is my code: Main Class这是我的代码:主要 Class

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Scanner;

public class Main extends Application {
    Stage window;
    Scene scene1, scene2, scene3;
    private Scanner x;
    @Override
    public void start(Stage primaryStage) throws Exception {
        readTutor r = new readTutor();
        window = primaryStage;
        window.setTitle("Tutor Finder");
        Label labelA1 = new Label("Welcome to the best online tutor\nproviding service in the world");
        Button buttonA2 = new Button("Find a tutor!");
        Button buttonA1 = new Button("Become a tutor!");
        Button buttonB1 = new Button("Click here to go back");
        Button buttonB2 = new Button("Submit");
        Button buttonC1 = new Button("Click here to go back");
        buttonB1.setOnAction(e -> window.setScene(scene1));
        buttonC1.setOnAction(e -> window.setScene(scene1));
        buttonA1.setOnAction(e -> window.setScene(scene2));
        buttonA2.setOnAction(e -> window.setScene(scene3));
        Label labelB1 = new Label("First Name:");
        TextField textB1 = new TextField();
        Label labelB2 = new Label("Last Name:");
        TextField textB2 = new TextField();
        Label labelB3 = new Label("Subject:");
        TextField textB3 = new TextField();
        Label labelB4 = new Label("Age:");
        TextField textB4 = new TextField();
        Label labelB5 = new Label("Contact No#:");
        TextField textB5 = new TextField();
        Label labelB6 = new Label("Country: ");
        TextField textB6 = new TextField();
        VBox layout = new VBox(20);
        layout.setAlignment(Pos.CENTER);
        layout.getChildren().addAll(labelA1, buttonA1, buttonA2);
        scene1 = new Scene(layout, 300, 300);
        VBox layout2 = new VBox(20);
        layout2.getChildren().addAll(labelB1, textB1, labelB2, textB2, labelB3,
                textB3, labelB4, textB4, labelB5, textB5, labelB6, textB6, buttonB2, buttonB1);
        buttonB2.setOnAction(l -> {
            try {
                BufferedWriter bw = new BufferedWriter(
                        new FileWriter("C:\\Users\\Salman\\Desktop\\Tutor Details\\output.txt", true));
                bw.write(textB1.getText()+" ");
                bw.write(textB2.getText()+" ");
                bw.write(textB3.getText()+" ");
                bw.write(textB4.getText()+" ");
                bw.write(textB5.getText()+" ");
                bw.write(textB6.getText()+" \n");
                bw.close();
                textB1.clear();
                textB2.clear();
                textB3.clear();
                textB4.clear();
                textB5.clear();
                textB6.clear();
            } catch (Exception e) {
                return;
            }
            r.openFile();
            r.readFile();
            r.closeFile();
        });
        scene2 = new Scene(layout2, 400, 600);
        VBox layout3 = new VBox(20);
        layout3.setAlignment(Pos.CENTER);
        layout3.getChildren().addAll(buttonC1);
        scene3 = new Scene(layout3, 300, 300);
        window.setScene(scene1);
        window.show();
    }
        public static void main (String[]args){
            launch(args);
        }
}

readTutor Class读导师 Class

import javafx.scene.control.Label;

import java.io.*;
import java.util.*;

public class readTutor {

    private Scanner x;
    public Label tutorLabel;

    public void openFile(){

        try {
            x = new Scanner(new File("C:\\Users\\Salman\\Desktop\\Tutor Details\\output.txt"));
        }
        catch(Exception e){
            System.out.println("couldn't find file");
        }
    }

    public void readFile(){
        while(x.hasNext()){
            String a = x.next();
            String b = x.next();
            String c = x.next();
            String d = x.next();
            String e = x.next();
            String f = x.next();
            System.out.printf("%s %s %s %s %s %s\n", a, b, c, d, e, f);
            tutorLabel = new Label(a+b+c+d+e+f);
        }
    }


    public void closeFile(){
        x.close();
    }
}

What I want is to use the Label created in the readFile method in the readTutor Class, in scene3 and display that label there.我想要的是在scene3中使用在readTutor Class的readFile方法中创建的Label,并在那里显示label。 But I can't figure out how to use that label from the Main class.但我不知道如何使用主要 class 中的 label。

You should make an Object to store you're data or pass them to the target location.您应该制作一个 Object 来存储您的数据或将它们传递到目标位置。

There is much that is very, very wrong about the structure of code in the question.问题中的代码结构有很多非常非常错误的地方。 Mostly that it does all kinds of file handling and I/O on the FXAT, which will cause havoc with the GUI if there is any kind of lag with those operations.大多数情况下,它在 FXAT 上执行各种文件处理和 I/O,如果这些操作有任何延迟,这将对 GUI 造成严重破坏。

Also, the idea of having a file handling helper class with a JavaFX screen Node in it is really not a good design.此外,在其中包含文件处理助手 class 和 JavaFX 屏幕节点的想法确实不是一个好的设计。 @Kleopatra's comment about using a data model is totally on point. @Kleopatra 关于使用数据 model 的评论完全正确。

But in the spirit of answering the question about exposing the layout of a screen to other classes which have a legitimate reason to access it, I've made the required changes to the code so that it should work.但本着回答有关将屏幕布局暴露给有正当理由访问它的其他类的问题的精神,我对代码进行了必要的更改,以便它可以工作。

First, I've added a TextField and Label to the Main screen to show the results from the readTutor class.首先,我在主屏幕上添加了一个 TextField 和 Label 以显示来自 readTutor class 的结果。 Then I've passed the TextField to readTutor in it's constructor:然后我在它的构造函数中将 TextField 传递给 readTutor:

import javafx.application.Application;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Scanner;

public class LabelPasser extends Application {
    Stage window;
    Scene scene1, scene2, scene3;
    private Scanner x;

    @Override
    public void start(Stage primaryStage) throws Exception {
        window = primaryStage;
        window.setTitle("Tutor Finder");
        Label labelA1 = new Label("Welcome to the best online tutor\nproviding service in the world");
        Button buttonA2 = new Button("Find a tutor!");
        Button buttonA1 = new Button("Become a tutor!");
        Button buttonB1 = new Button("Click here to go back");
        Button buttonB2 = new Button("Submit");
        Button buttonC1 = new Button("Click here to go back");
        buttonB1.setOnAction(e -> window.setScene(scene1));
        buttonC1.setOnAction(e -> window.setScene(scene1));
        buttonA1.setOnAction(e -> window.setScene(scene2));
        buttonA2.setOnAction(e -> window.setScene(scene3));
        Label labelB1 = new Label("First Name:");
        TextField textB1 = new TextField();
        Label labelB2 = new Label("Last Name:");
        TextField textB2 = new TextField();
        Label labelB3 = new Label("Subject:");
        TextField textB3 = new TextField();
        Label labelB4 = new Label("Age:");
        TextField textB4 = new TextField();
        Label labelB5 = new Label("Contact No#:");
        TextField textB5 = new TextField();
        Label labelB6 = new Label("Country: ");
        TextField textB6 = new TextField();
        Label labelTutor = new Label("Tutor: ");
        TextField tutorTF = new TextField();
        VBox layout = new VBox(20);
        layout.setAlignment(Pos.CENTER);
        layout.getChildren().addAll(labelA1, buttonA1, buttonA2);
        readTutor r = new readTutor(tutorTF);
        scene1 = new Scene(layout, 300, 300);
        VBox layout2 = new VBox(20);
        layout2.getChildren()
               .addAll(labelB1,
                       textB1,
                       labelB2,
                       textB2,
                       labelB3,
                       textB3,
                       labelB4,
                       textB4,
                       labelB5,
                       textB5,
                       labelB6,
                       textB6,
                       labelTutor,
                       tutorTF,
                       buttonB2,
                       buttonB1);
        buttonB2.setOnAction(l -> {
            try {
                BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Salman\\Desktop\\Tutor Details\\output.txt", true));
                bw.write(textB1.getText() + " ");
                bw.write(textB2.getText() + " ");
                bw.write(textB3.getText() + " ");
                bw.write(textB4.getText() + " ");
                bw.write(textB5.getText() + " ");
                bw.write(textB6.getText() + " \n");
                bw.close();
                textB1.clear();
                textB2.clear();
                textB3.clear();
                textB4.clear();
                textB5.clear();
                textB6.clear();
            } catch (Exception e) {
                return;
            }
            r.openFile();
            r.readFile();
        });
        scene2 = new Scene(layout2, 400, 600);
        VBox layout3 = new VBox(20);
        layout3.setAlignment(Pos.CENTER);
        layout3.getChildren().addAll(buttonC1);
        scene3 = new Scene(layout3, 300, 300);
        window.setScene(scene1);
        window.show();
    }

    public static void main(String[] args) {
        launch(args);
    }
}

Then I've modified readTutor such that it no longer creates a Label, but instead updates the Text property of the TextField that it received in its constructor:然后我修改了 readTutor,使它不再创建 Label,而是更新它在构造函数中收到的 TextField 的 Text 属性:

import javafx.scene.control.Label;
import javafx.scene.control.TextField;

import java.io.File;
import java.util.Scanner;

public class readTutor {

    private Scanner x;
    public Label tutorLabel;
    TextField tutorTF;

    public readTutor(TextField tutorTF) {
        this.tutorTF = tutorTF;
    }

    public void openFile() {

        try {
            x = new Scanner(new File("C:\\Users\\Salman\\Desktop\\Tutor Details\\output.txt"));
        } catch (Exception e) {
            System.out.println("couldn't find file");
        }
    }

    public void readFile() {
        while (x.hasNext()) {
            String a = x.next();
            String b = x.next();
            String c = x.next();
            String d = x.next();
            String e = x.next();
            String f = x.next();
            System.out.printf("%s %s %s %s %s %s\n", a, b, c, d, e, f);
            tutorTF.setText(a + b + c + d + e + f);
        }
    }
}

It turns out that if you program the file handling the way you should, with a Task, then most of the issues about the label passing become moot.事实证明,如果您使用任务以应有的方式处理文件,那么有关 label 传递的大多数问题都会变得没有意义。 I've cleaned up the code a bit to make it easier to read, then split the file handling out into a Task:我对代码进行了一些清理以使其更易于阅读,然后将文件处理拆分为一个任务:

import javafx.application.Application;
import javafx.concurrent.Task;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.TextField;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

import java.io.BufferedWriter;
import java.io.FileWriter;
import java.util.Scanner;

public class LabelPasser extends Application {
    Stage window;
    Scene scene1, scene2, scene3;
    private Scanner x;
    private TextField textB1 = new TextField();
    private TextField textB2 = new TextField();
    private TextField textB3 = new TextField();
    private TextField textB4 = new TextField();
    private TextField textB5 = new TextField();
    private TextField textB6 = new TextField();
    private TextField tutorTF = new TextField();

    @Override
    public void start(Stage primaryStage) throws Exception {
        window = primaryStage;
        window.setTitle("Tutor Finder");
        Button buttonA2 = new Button("Find a tutor!");
        Button buttonA1 = new Button("Become a tutor!");
        Button buttonB1 = new Button("Click here to go back");
        Button buttonB2 = new Button("Submit");
        Button buttonC1 = new Button("Click here to go back");
        buttonB1.setOnAction(e -> window.setScene(scene1));
        buttonC1.setOnAction(e -> window.setScene(scene1));
        buttonA1.setOnAction(e -> window.setScene(scene2));
        buttonA2.setOnAction(e -> window.setScene(scene3));
        VBox layout = new VBox(20, new Label("Welcome to the best online tutor\nproviding service in the world"), buttonA1, buttonA2);
        layout.setAlignment(Pos.CENTER);
        scene1 = new Scene(layout, 300, 300);
        VBox layout2 = new VBox(20);
        layout2.getChildren()
               .addAll(new Label("First Name:"),
                       textB1,
                       new Label("Last Name:"),
                       textB2,
                       new Label("Subject:"),
                       textB3,
                       new Label("Age:"),
                       textB4,
                       new Label("Contact No#:"),
                       textB5,
                       new Label("Country: "),
                       textB6,
                       new Label("Tutor: "),
                       tutorTF,
                       buttonB2,
                       buttonB1);
        buttonB2.setOnAction(evt -> buttonAction());
        scene2 = new Scene(layout2, 400, 600);
        VBox layout3 = new VBox(20);
        layout3.setAlignment(Pos.CENTER);
        layout3.getChildren().addAll(buttonC1);
        scene3 = new Scene(layout3, 300, 300);
        window.setScene(scene1);
        window.show();
    }

    private void buttonAction() {
        Task<String> fileTask = new Task<String>() {
            @Override
            protected String call() throws Exception {
                try {
                    BufferedWriter bw = new BufferedWriter(new FileWriter("C:\\Users\\Salman\\Desktop\\Tutor Details\\output.txt", true));
                    bw.write(textB1.getText() + " ");
                    bw.write(textB2.getText() + " ");
                    bw.write(textB3.getText() + " ");
                    bw.write(textB4.getText() + " ");
                    bw.write(textB5.getText() + " ");
                    bw.write(textB6.getText() + " \n");
                    bw.close();
                    textB1.clear();
                    textB2.clear();
                    textB3.clear();
                    textB4.clear();
                    textB5.clear();
                    textB6.clear();
                } catch (Exception e) {
                    return "";
                }
                ReadTutor readTutor = new ReadTutor();
                readTutor.openFile();
                return readTutor.readFile();
            }
        };
        fileTask.setOnSucceeded(evt -> tutorTF.setText(fileTask.getValue()));
        Thread fileThread = new Thread(fileTask);
        fileThread.start();
    }


    public static void main(String[] args) {
        launch(args);
    }
}

The readFile() method in ReadTutor was strange, and it looked like it was trying to create Labels in a loop, so the file reading is weird. ReadTutor 中的 readFile() 方法很奇怪,看起来像是在循环创建 Labels,所以文件读取很奇怪。 I modified it just so that it would compile:我对其进行了修改,以便它可以编译:

import java.io.File;
import java.util.Scanner;

public class ReadTutor {

    private Scanner x;

    public void openFile() {

        try {
            x = new Scanner(new File("C:\\Users\\Salman\\Desktop\\Tutor Details\\output.txt"));
        } catch (Exception e) {
            System.out.println("couldn't find file");
        }
    }

    public String readFile() {
        String results = "";
        while (x.hasNext()) {
            String a = x.next();
            String b = x.next();
            String c = x.next();
            String d = x.next();
            String e = x.next();
            String f = x.next();
            System.out.printf("%s %s %s %s %s %s\n", a, b, c, d, e, f);
            results = a + b + c + d + e + f;
        }
        return results;
    }
}

So now you can see that ReadTutor is just a file handler, and it returns a plain old Java String as a result and doesn't know anything about JavaFX at all.所以现在你可以看到 ReadTutor 只是一个文件处理程序,它返回一个普通的旧 Java 字符串作为结果,并且对 JavaFX 一无所知。 The Task handles the activity on a background thread and returns the String value from the read operation.任务处理后台线程上的活动并从读取操作返回字符串值。 When the Task completes, it will trigger the OnSucceeded event, which will update the value in the tutorTF TextField on the FXAT.当任务完成时,它将触发 OnSucceeded 事件,该事件将更新 FXAT 上的utorTF TextField 中的值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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