gpt4 book ai didi

JavaFX Controller 类不工作

转载 作者:行者123 更新时间:2023-11-30 06:58:58 25 4
gpt4 key购买 nike

我真的很难理解 JavaFX Controller ,我的目标是写入 TextArea 以充当日志。

我的代码在下面,但我希望能够从另一个我可以在需要时调用的类中更改值 ETC。我试图创建一个扩展 Initializable 的 Controller 类,但我无法让它工作。有人可以引导我朝着正确的方向前进吗?

我想将底部的@FXML 代码移动到另一个类并更新场景。

package application;
import javafx.event.ActionEvent;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;

import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Parent;
import javafx.scene.Scene;


public class Main extends Application {
@Override
public void start(Stage primaryStage) {
try {
Parent root = FXMLLoader.load(getClass().getResource("Root.fxml"));
Scene scene = new Scene(root,504,325);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}

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

public Thread thread = new Thread(new webimporter());

@FXML
public Label runningLabel;

@FXML
public TextArea txtArea;

@FXML
void runClick(ActionEvent event) throws IOException{
changeLabelValue("Importer running...");
thread.start();

}

@FXML
protected void stopClick(ActionEvent event){
changeLabelValue("Importer stopped...");
thread.interrupt();
}

@FXML
void changeLabelValue(String newText){
runningLabel.setText(newText);
}

void changeTextAreaValue(String newText1){
txtArea.setText(newText1);
}
}

最佳答案

不要让 Application 类成为 Controller 。这是一种罪过。还有其他问题和答案可以解决这个问题,但我的搜索技能目前无法找到它们。

它是罪的原因是:

  1. 您应该只有一个 Application 实例,默认情况下,加载程序将创建一个新实例,因此您最终会得到两个应用程序对象。
  2. 引用成员对象是令人困惑的,因为最初启动的应用程序没有@FXML 注入(inject)字段,但加载器创建的应用程序实例确实有@FXML 注入(inject)字段。

另外,不相关的建议:在您的应用程序至少能够显示您的 UI 之前,不要开始尝试编写多线程代码。

JavaFX 的多线程记录器在对 Most efficient way to log messages to JavaFX TextArea via threads with simple custom logging frameworks 的回答中,但不幸的是,它的实现并不直接,而且几乎没有文档。


sample output

textlogger/Root.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import javafx.geometry.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>

<VBox maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefWidth="400.0" spacing="10.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="textlogger.ImportController">
<children>
<HBox alignment="BASELINE_LEFT" minHeight="-Infinity" minWidth="-Infinity" spacing="10.0">
<children>
<Button mnemonicParsing="false" onAction="#run" text="Run" />
<Button mnemonicParsing="false" onAction="#stop" text="Stop" />
<Label fx:id="runningLabel" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</HBox>
<TextArea fx:id="textArea" editable="false" prefHeight="200.0" prefWidth="200.0" />
</children>
<padding>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</padding>
</VBox>

textlogger.ImportController.java

package textlogger;

import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;

import java.io.IOException;

public class ImportController {
@FXML
private Label runningLabel;

@FXML
private TextArea textArea;

private WebImporter importer;

@FXML
void run(ActionEvent event) throws IOException {
changeLabelValue("Importer running...");

if (importer == null) {
importer = new WebImporter(textArea);
Thread thread = new Thread(
importer
);
thread.setDaemon(true);
thread.start();
}
}

@FXML
void stop(ActionEvent event){
changeLabelValue("Importer stopped...");
if (importer != null) {
importer.cancel();
importer = null;
}
}

private void changeLabelValue(String newText){
runningLabel.setText(newText);
}

}

textlogger.WebImporter.java

import javafx.application.Platform;
import javafx.concurrent.Task;
import javafx.scene.control.TextArea;

import java.time.LocalTime;

public class WebImporter extends Task<Void> {

private final TextArea textArea;

public WebImporter(TextArea textArea) {
this.textArea = textArea;
}

@Override
protected Void call() throws Exception {
try {
while (!isCancelled()) {
Thread.sleep(500);

Platform.runLater(
() -> textArea.setText(
textArea.getText() + LocalTime.now() + "\n"
)
);
}
} catch (InterruptedException e) {
Thread.interrupted();
}

return null;
}
}

textlogger.TextLoggingSample.java

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

public class TextLoggingSample extends Application {
@Override
public void start(Stage stage) {
try {
FXMLLoader loader = new FXMLLoader();
Parent root = loader.load(
getClass().getResourceAsStream(
"Root.fxml"
)
);

Scene scene = new Scene(root);
stage.setScene(scene);
stage.show();
} catch(Exception e) {
e.printStackTrace();
}
}

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

关于JavaFX Controller 类不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32081713/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com