我需要操纵Controller类中的元素。但是,我设法找到的每个示例都通过扩展Application的类来进行此操作。
我需要在类Main中的VBoxSampleController中操作TextField inputText。
操纵如下:
inputText.setText(“TEST”);
期望的结果是一旦启动FXML应用程序,inputText TextField就预先填充了文本“TEST”。
我的困惑源于如何在任何地方操纵这个领域,但是:
设置VBoxsampleController静态的行为,以便我可以使用类名访问它:
UIManager.vbsc.inputText.setText("TEST");
什么都不做。启动的FXML窗口中的元素不会更改。它仍然是空的。
此项目取自https://examples.javacodegeeks.com/desktop-java/javafx/javafx-applications-efxclipse/,因为我目前无法创建新的FXML应用程序。
感谢。
完整代码:
/* Main */
public class Main {
public static void main(String[] args) {
UIManager.main(args);
// Does nothing
// UIManager.vbsc.inputText.setText("TEST");
// I want to change inputText here
}
}
/* UIManager */
import javafx.application.Application;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.fxml.FXMLLoader;
public class UIManager extends Application {
public static VBoxSampleController vbsc;
public FXMLLoader loader;
@Override
public void start(Stage primaryStage) {
try {
loader = new FXMLLoader();
loader.setLocation(Main.class.getResource("VBoxSample.fxml"));
VBox root = loader.load();
Scene scene = new Scene(root, 400, 400);
primaryStage.setScene(scene);
primaryStage.show();
vbsc = loader.getController();
} catch (Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
/* VBoxController */
import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.control.TabPane;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
public class VBoxSampleController {
@FXML
// The reference of inputText will be injected by the FXML loader
public TextField inputText;
// The reference of outputText will be injected by the FXML loader
@FXML
private TextArea outputText;
// location and resources will be automatically injected by the FXML loader
@FXML
private URL location;
@FXML
private TabPane mainPane;
@FXML
private ResourceBundle resources;
// Add a public no-args constructor
public VBoxSampleController() {
}
@FXML
private void initialize() {
}
@FXML
private void printOutput() {
outputText.setText(inputText.getText());
}
}
<!-- FXML -->
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.TextArea?>
<VBox xmlns:fx="http://javafx.com/fxml/1" fx:controller="VBoxSampleController">
<children>
<Label alignment="CENTER_LEFT" cache="true" cacheHint="SCALE" prefHeight="30.0" prefWidth="200.0" text="Please insert Your Input here:" textAlignment="LEFT" />
<TextField fx:id="inputText" prefWidth="100.0" />
<Button alignment="CENTER_RIGHT" contentDisplay="CENTER" mnemonicParsing="false" onAction="#printOutput" text="OK" textAlignment="CENTER" />
<Label alignment="CENTER_LEFT" cache="true" cacheHint="SCALE" prefHeight="30.0" prefWidth="200.0" text="Your Input:" textAlignment="LEFT" />
<TextArea fx:id="outputText" prefHeight="100.0" prefWidth="200.0" wrapText="true" />
</children>
</VBox>
答案 0 :(得分:1)
我认为这是因为您试图从非静态方法修改静态变量:
@Override
public void start (Stage primaryStage) { // non-static method
vbsc = loader.getController(); // vbsc is a static variable
}
如果我猜对了,您正在尝试在应用程序启动时动态更新 FXML 字段。所以你可以简单地通过使用控制器的 initialize() 方法来实现:
public class VBoxSampleController {
@FXML // I suggest you to always keep class variable
private TextField inputText; // field private or non-public to prevent
// unauthorized modifications
...
@FXML
public void initialize() {
String text = "TEST"; // or any other at-runtime generated string
inputText.setText(text);
}
...
}
答案 1 :(得分:0)
public class Main extends Application {
//controllers
static HomeController homeController;
static StageController stageController;
//...
}
在HomeControllers类的初始化方法中写:
homeController = this;
并在StageController类的initialize方法中写:
StageController = this;
答案 2 :(得分:0)
您的问题似乎源于您在主线程而不是平台线程上进行更新。这里有两个问题。
UIManager.vbsc.inputText.setText("TEST");
。试试。
Platform.runLater( () -> UIManager.vbsc.inputText.setText("TEST") );