Java 如何从其他类获取对节点的引用?

Java 如何从其他类获取对节点的引用?,java,javafx,Java,Javafx,有没有简单的方法可以从其他类获取对stage控件的引用?除了Delphi之外,它似乎在每个基于GUI的框架中都是一个问题。如果只有Controller或Main类是静态的 这是我的密码: Controller.java: package sample; import javafx.fxml.*; import javafx.scene.control.Button; import javafx.scene.control.TextArea; public class Controller {

有没有简单的方法可以从其他类获取对stage控件的引用?除了Delphi之外,它似乎在每个基于GUI的框架中都是一个问题。如果只有
Controller
Main
类是静态的

这是我的密码:

Controller.java

package sample;

import javafx.fxml.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    private Button algorithms;

    @FXML
    private Button settings;

    @FXML
    private Button run;

    @FXML
    public TextArea console; // I want access that node from class named 'Utils'

    @FXML
    void initialize() { }

    public Controller () { }

    @FXML
    private void onRun() {
        Utility.get().runBench();
    }

    @FXML
    private void onSettings() {
        console.appendText("I am opening settings...");
    }

    @FXML
    private void onAlgorithm() {
        console.appendText("I am opening list of Algorithms...");
    }
}
package sample;

import sample.Algorithms.BubbleSort;

import java.util.*;


// Singleton
public class Utility {
    private static Utility ourInstance = new Utility();

    public static Utility get() {
        return ourInstance;
    }

    private Utility() {
        listOfAlgorithms.add(new BubbleSort(howManyN));
    }

    List<Algorithm> listOfAlgorithms = new LinkedList<>();
    Long howManyN = 999L;

    public void runBench() {
        for (Algorithm a: listOfAlgorithms) {
            double start = System.nanoTime();
            a.run();
            double end = System.nanoTime();
            double result = end - start;
            System.out.println(
//            console.appendText(  // Accessing like that would be ideal
                    "Algorithm: " + a.getClass().getName() + "\n" +
                    "For N = " + a.getN() + " time is: " + result
            );
        }
    }
}
package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {

    final String APP_NAME = "SortAll 2";
    final String RES_PATH = "../resources/scene.fxml";

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource(RES_PATH));
        primaryStage.setTitle(APP_NAME);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}
 public void runBench(TextArea console) {
    for (Algorithm a: listOfAlgorithms) {
        double start = System.nanoTime();
        a.run();
        double end = System.nanoTime();
        double result = end - start;
        System.out.println(
        console.appendText(
                "Algorithm: " + a.getClass().getName() + "\n" +
                "For N = " + a.getN() + " time is: " + result
        );
    }
}
@FXML
private void onRun() {
    Utility.get().runBench(console);
}
Utils.java

package sample;

import javafx.fxml.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    private Button algorithms;

    @FXML
    private Button settings;

    @FXML
    private Button run;

    @FXML
    public TextArea console; // I want access that node from class named 'Utils'

    @FXML
    void initialize() { }

    public Controller () { }

    @FXML
    private void onRun() {
        Utility.get().runBench();
    }

    @FXML
    private void onSettings() {
        console.appendText("I am opening settings...");
    }

    @FXML
    private void onAlgorithm() {
        console.appendText("I am opening list of Algorithms...");
    }
}
package sample;

import sample.Algorithms.BubbleSort;

import java.util.*;


// Singleton
public class Utility {
    private static Utility ourInstance = new Utility();

    public static Utility get() {
        return ourInstance;
    }

    private Utility() {
        listOfAlgorithms.add(new BubbleSort(howManyN));
    }

    List<Algorithm> listOfAlgorithms = new LinkedList<>();
    Long howManyN = 999L;

    public void runBench() {
        for (Algorithm a: listOfAlgorithms) {
            double start = System.nanoTime();
            a.run();
            double end = System.nanoTime();
            double result = end - start;
            System.out.println(
//            console.appendText(  // Accessing like that would be ideal
                    "Algorithm: " + a.getClass().getName() + "\n" +
                    "For N = " + a.getN() + " time is: " + result
            );
        }
    }
}
package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {

    final String APP_NAME = "SortAll 2";
    final String RES_PATH = "../resources/scene.fxml";

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource(RES_PATH));
        primaryStage.setTitle(APP_NAME);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}
 public void runBench(TextArea console) {
    for (Algorithm a: listOfAlgorithms) {
        double start = System.nanoTime();
        a.run();
        double end = System.nanoTime();
        double result = end - start;
        System.out.println(
        console.appendText(
                "Algorithm: " + a.getClass().getName() + "\n" +
                "For N = " + a.getN() + " time is: " + result
        );
    }
}
@FXML
private void onRun() {
    Utility.get().runBench(console);
}

嗯,您不能将console作为runBench()参数传递吗

Utility.java

package sample;

import javafx.fxml.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    private Button algorithms;

    @FXML
    private Button settings;

    @FXML
    private Button run;

    @FXML
    public TextArea console; // I want access that node from class named 'Utils'

    @FXML
    void initialize() { }

    public Controller () { }

    @FXML
    private void onRun() {
        Utility.get().runBench();
    }

    @FXML
    private void onSettings() {
        console.appendText("I am opening settings...");
    }

    @FXML
    private void onAlgorithm() {
        console.appendText("I am opening list of Algorithms...");
    }
}
package sample;

import sample.Algorithms.BubbleSort;

import java.util.*;


// Singleton
public class Utility {
    private static Utility ourInstance = new Utility();

    public static Utility get() {
        return ourInstance;
    }

    private Utility() {
        listOfAlgorithms.add(new BubbleSort(howManyN));
    }

    List<Algorithm> listOfAlgorithms = new LinkedList<>();
    Long howManyN = 999L;

    public void runBench() {
        for (Algorithm a: listOfAlgorithms) {
            double start = System.nanoTime();
            a.run();
            double end = System.nanoTime();
            double result = end - start;
            System.out.println(
//            console.appendText(  // Accessing like that would be ideal
                    "Algorithm: " + a.getClass().getName() + "\n" +
                    "For N = " + a.getN() + " time is: " + result
            );
        }
    }
}
package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {

    final String APP_NAME = "SortAll 2";
    final String RES_PATH = "../resources/scene.fxml";

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource(RES_PATH));
        primaryStage.setTitle(APP_NAME);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}
 public void runBench(TextArea console) {
    for (Algorithm a: listOfAlgorithms) {
        double start = System.nanoTime();
        a.run();
        double end = System.nanoTime();
        double result = end - start;
        System.out.println(
        console.appendText(
                "Algorithm: " + a.getClass().getName() + "\n" +
                "For N = " + a.getN() + " time is: " + result
        );
    }
}
@FXML
private void onRun() {
    Utility.get().runBench(console);
}

Controller.java

package sample;

import javafx.fxml.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    private Button algorithms;

    @FXML
    private Button settings;

    @FXML
    private Button run;

    @FXML
    public TextArea console; // I want access that node from class named 'Utils'

    @FXML
    void initialize() { }

    public Controller () { }

    @FXML
    private void onRun() {
        Utility.get().runBench();
    }

    @FXML
    private void onSettings() {
        console.appendText("I am opening settings...");
    }

    @FXML
    private void onAlgorithm() {
        console.appendText("I am opening list of Algorithms...");
    }
}
package sample;

import sample.Algorithms.BubbleSort;

import java.util.*;


// Singleton
public class Utility {
    private static Utility ourInstance = new Utility();

    public static Utility get() {
        return ourInstance;
    }

    private Utility() {
        listOfAlgorithms.add(new BubbleSort(howManyN));
    }

    List<Algorithm> listOfAlgorithms = new LinkedList<>();
    Long howManyN = 999L;

    public void runBench() {
        for (Algorithm a: listOfAlgorithms) {
            double start = System.nanoTime();
            a.run();
            double end = System.nanoTime();
            double result = end - start;
            System.out.println(
//            console.appendText(  // Accessing like that would be ideal
                    "Algorithm: " + a.getClass().getName() + "\n" +
                    "For N = " + a.getN() + " time is: " + result
            );
        }
    }
}
package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {

    final String APP_NAME = "SortAll 2";
    final String RES_PATH = "../resources/scene.fxml";

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource(RES_PATH));
        primaryStage.setTitle(APP_NAME);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}
 public void runBench(TextArea console) {
    for (Algorithm a: listOfAlgorithms) {
        double start = System.nanoTime();
        a.run();
        double end = System.nanoTime();
        double result = end - start;
        System.out.println(
        console.appendText(
                "Algorithm: " + a.getClass().getName() + "\n" +
                "For N = " + a.getN() + " time is: " + result
        );
    }
}
@FXML
private void onRun() {
    Utility.get().runBench(console);
}

嗯,您不能将console作为runBench()参数传递吗

Utility.java

package sample;

import javafx.fxml.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    private Button algorithms;

    @FXML
    private Button settings;

    @FXML
    private Button run;

    @FXML
    public TextArea console; // I want access that node from class named 'Utils'

    @FXML
    void initialize() { }

    public Controller () { }

    @FXML
    private void onRun() {
        Utility.get().runBench();
    }

    @FXML
    private void onSettings() {
        console.appendText("I am opening settings...");
    }

    @FXML
    private void onAlgorithm() {
        console.appendText("I am opening list of Algorithms...");
    }
}
package sample;

import sample.Algorithms.BubbleSort;

import java.util.*;


// Singleton
public class Utility {
    private static Utility ourInstance = new Utility();

    public static Utility get() {
        return ourInstance;
    }

    private Utility() {
        listOfAlgorithms.add(new BubbleSort(howManyN));
    }

    List<Algorithm> listOfAlgorithms = new LinkedList<>();
    Long howManyN = 999L;

    public void runBench() {
        for (Algorithm a: listOfAlgorithms) {
            double start = System.nanoTime();
            a.run();
            double end = System.nanoTime();
            double result = end - start;
            System.out.println(
//            console.appendText(  // Accessing like that would be ideal
                    "Algorithm: " + a.getClass().getName() + "\n" +
                    "For N = " + a.getN() + " time is: " + result
            );
        }
    }
}
package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {

    final String APP_NAME = "SortAll 2";
    final String RES_PATH = "../resources/scene.fxml";

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource(RES_PATH));
        primaryStage.setTitle(APP_NAME);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}
 public void runBench(TextArea console) {
    for (Algorithm a: listOfAlgorithms) {
        double start = System.nanoTime();
        a.run();
        double end = System.nanoTime();
        double result = end - start;
        System.out.println(
        console.appendText(
                "Algorithm: " + a.getClass().getName() + "\n" +
                "For N = " + a.getN() + " time is: " + result
        );
    }
}
@FXML
private void onRun() {
    Utility.get().runBench(console);
}

Controller.java

package sample;

import javafx.fxml.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextArea;

public class Controller {

    @FXML
    private Button algorithms;

    @FXML
    private Button settings;

    @FXML
    private Button run;

    @FXML
    public TextArea console; // I want access that node from class named 'Utils'

    @FXML
    void initialize() { }

    public Controller () { }

    @FXML
    private void onRun() {
        Utility.get().runBench();
    }

    @FXML
    private void onSettings() {
        console.appendText("I am opening settings...");
    }

    @FXML
    private void onAlgorithm() {
        console.appendText("I am opening list of Algorithms...");
    }
}
package sample;

import sample.Algorithms.BubbleSort;

import java.util.*;


// Singleton
public class Utility {
    private static Utility ourInstance = new Utility();

    public static Utility get() {
        return ourInstance;
    }

    private Utility() {
        listOfAlgorithms.add(new BubbleSort(howManyN));
    }

    List<Algorithm> listOfAlgorithms = new LinkedList<>();
    Long howManyN = 999L;

    public void runBench() {
        for (Algorithm a: listOfAlgorithms) {
            double start = System.nanoTime();
            a.run();
            double end = System.nanoTime();
            double result = end - start;
            System.out.println(
//            console.appendText(  // Accessing like that would be ideal
                    "Algorithm: " + a.getClass().getName() + "\n" +
                    "For N = " + a.getN() + " time is: " + result
            );
        }
    }
}
package sample;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;


public class Main extends Application {

    final String APP_NAME = "SortAll 2";
    final String RES_PATH = "../resources/scene.fxml";

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

    @Override
    public void start(Stage primaryStage) throws Exception{
        Parent root = FXMLLoader.load(getClass().getResource(RES_PATH));
        primaryStage.setTitle(APP_NAME);
        primaryStage.setScene(new Scene(root));
        primaryStage.show();
    }
}
 public void runBench(TextArea console) {
    for (Algorithm a: listOfAlgorithms) {
        double start = System.nanoTime();
        a.run();
        double end = System.nanoTime();
        double result = end - start;
        System.out.println(
        console.appendText(
                "Algorithm: " + a.getClass().getName() + "\n" +
                "For N = " + a.getN() + " time is: " + result
        );
    }
}
@FXML
private void onRun() {
    Utility.get().runBench(console);
}

将对象传递给
runBench()
方法,该方法描述了要对结果执行的操作。由于将结果封装为
字符串
,因此可以使用:


这与您发布的问题无关,但您几乎肯定需要在后台线程中执行
runBench()
方法,因为执行该方法显然需要一些时间。如果这样做,则需要确保仅在FX应用程序线程上访问控制台。上述解决方案很容易修改以实现这一点(您的
runBench(…)
方法根本不需要更改):


将对象传递给
runBench()
方法,该方法描述了要对结果执行的操作。由于将结果封装为
字符串
,因此可以使用:


这与您发布的问题无关,但您几乎肯定需要在后台线程中执行
runBench()
方法,因为执行该方法显然需要一些时间。如果这样做,则需要确保仅在FX应用程序线程上访问控制台。上述解决方案很容易修改以实现这一点(您的
runBench(…)
方法根本不需要更改):


基本上不应该这样做:它违反了封装。控制器应该是唯一“了解”控件的对象。控制器是静态的没有任何意义,因为无法两次加载同一个FXML文件(两组UI控件只能有一个控制器)。如果确实要这样做,请将变量传递给util方法。基本上不应该这样做:这违反了封装。控制器应该是唯一“了解”控件的对象。控制器是静态的没有任何意义,因为无法两次加载同一个FXML文件(两组UI控件只能有一个控制器)。如果确实要这样做,请将变量传递给util方法。更好的方法是:传递
使用者
,以避免暴露UI控件(并保持灵活性等)。或者,您可以在runBench()中构建并返回文本字符串,并将其直接附加到控制器方法中以实现更好的封装。编辑:您有更好的想法,先生:)我可以,但这不是正确的解决方案。也许我会在1000个类中有1000个方法。每次我都应该传递那个参数?如果我的阶段中有20个节点,我想访问它们。然后呢?@Barburka我在上面的评论中提出的建议有什么问题?我不能对直接回答(这里是newb)发表评论,但我可以在这里发表评论。非常基本的说法:Consumer是一个通用的函数接口,它允许您将方法作为参数传递,并在内部使用指定的类型参数执行。更好的做法是:传递
Consumer
,以避免暴露UI控件(并保持灵活性等)。或者您可以在runBench()中构建并返回文本字符串并将其直接附加到控制器方法中,以实现更好的封装。编辑:你有更好的主意,先生:)我可以,但它不可能是正确的解决方案。也许我会在1000个类中有1000个方法。每次我都应该传递那个参数?如果我的阶段中有20个节点,我想访问它们。然后呢?@Barburka我在上面的评论中提出的建议有什么问题?我不能对直接回答(这里是newb)发表评论,但我可以在这里发表评论。非常基本的说法:Consumer是一个通用函数接口,它允许您将一个方法作为参数传递,并使用指定的类型参数在内部执行。@Barburka
Consumer
是一个具有单个抽象方法的接口,
public void accept(String value)
。方法引用
console::appendText
(实际上,它不是这样工作的)创建了一个对象,该对象实现了与
public void accept(String value){console.appendText(value);}
的接口。现在我真正明白了,我做错了什么——类之间不应该相互了解。这是个好把戏consumer@Barburka
使用者
是一个具有单个抽象方法的接口,
公共void accept(字符串值)
。方法引用
console::appendText
(实际上,它不是这样工作的)创建了一个对象,该对象实现了与
public void accept(String value){console.appendText(value);}
的接口。现在我真正明白了,我做错了什么——类之间不应该相互了解。这个消费者玩得很好