ObjectOutputStream 在 PlayerList.java 中不可用 - 无法获取 table 的数据
ObjectOutputStream not available in PlayerList.java - impossible to get data for table
好的,再来一次。这是一个带有相关代码的新项目。正如您在文本字段中看到的,即使 initData 应该已经初始化了 testVar 变量,但它并没有发生,并且在 initialize() 中变量为空。不过,我需要在那里获取变量,这样我就可以将数据从网络连接中获取到 table。这里的代码:
FXMLController.java:
package de.freakyonline.testproject;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
public class FXMLController implements Initializable {
String testVar;
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private TextArea testTextArea;
@Override
public void initialize(URL url, ResourceBundle rb) {
// Here it's null
testTextArea.appendText("TestVar: " + testVar);
}
void initData(Remote remoteObj) {
this.testVar = remoteObj.getVar();
}
}
MainApp.java:
package de.freakyonline.testproject;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MainApp extends Application {
Thread remote;
Remote remoteObj;
String testVar = new String("success");
@Override
public void start(Stage stage) throws Exception {
FXMLLoader root = new FXMLLoader(
getClass().getResource("/fxml/Scene.fxml")
);
try {
remoteObj = new Remote(testVar);
remote = new Thread(remoteObj);
} catch (Exception ex) { ex.printStackTrace(); }
remote.start();
Scene scene = new Scene((Parent) root.load());
FXMLController controller = root.<FXMLController>getController();
controller.initData(remoteObj);
scene.getStylesheets().add("/styles/Styles.css");
stage.setTitle("TestProjects ...");
stage.setScene(scene);
stage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Scene.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.freakyonline.testproject.FXMLController">
<center>
<TextArea fx:id="testTextArea" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
Remote.java:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package de.freakyonline.testproject;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
/**
*
* @author uwe
*/
public class Remote implements Runnable {
private String testVar;
public Remote (String testVar) {
this.testVar = testVar;
}
public String getVar() {
return testVar;
}
public void run() {
}
}
控制器的 initialize()
方法在加载 FXML 时由 FXMLLoader
调用,即在调用 load()
期间调用。在您的示例代码中,您在调用 load()
之后调用 initData()
,因此很明显 testVar
在 initialize()
方法时无法初始化被执行。由于示例代码中的控制器是由 FXMLLoader
创建的,因此您不能在调用 initialize()
之前调用 initData(...)
。
(另外:使用一些简单的调试技术,例如使用逐步调试器,或者甚至只是在调用每个方法时打印一条消息,就会非常清楚这里的问题是什么。)
最简单的修复方法就是将依赖于 testVar
的代码移动到 initData()
方法(或其他一些调用 after 的方法 testVar
初始化):
public class FXMLController implements Initializable {
String testVar;
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private TextArea testTextArea;
@Override
public void initialize(URL url, ResourceBundle rb) {
}
void initData(Remote remoteObj) {
this.testVar = remoteObj.getVar();
testTextArea.appendText("TestVar: " + testVar);
}
}
这里的小缺点是控制器的初始化分布在多个方法中,在控制器生命周期的不同点执行。其他选项包括在代码中设置控制器,而不是在 FXML 文件中指定控制器 class,或使用控制器工厂。在代码中设置控制器的缺点是,如果您使用工具(例如 Scene Builder)设计 FXML,它不会意识到正在使用的控制器 class。使用控制器工厂更复杂,但可以避免这个问题。
好的,再来一次。这是一个带有相关代码的新项目。正如您在文本字段中看到的,即使 initData 应该已经初始化了 testVar 变量,但它并没有发生,并且在 initialize() 中变量为空。不过,我需要在那里获取变量,这样我就可以将数据从网络连接中获取到 table。这里的代码:
FXMLController.java:
package de.freakyonline.testproject;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Label;
import javafx.scene.control.TextArea;
public class FXMLController implements Initializable {
String testVar;
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private TextArea testTextArea;
@Override
public void initialize(URL url, ResourceBundle rb) {
// Here it's null
testTextArea.appendText("TestVar: " + testVar);
}
void initData(Remote remoteObj) {
this.testVar = remoteObj.getVar();
}
}
MainApp.java:
package de.freakyonline.testproject;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class MainApp extends Application {
Thread remote;
Remote remoteObj;
String testVar = new String("success");
@Override
public void start(Stage stage) throws Exception {
FXMLLoader root = new FXMLLoader(
getClass().getResource("/fxml/Scene.fxml")
);
try {
remoteObj = new Remote(testVar);
remote = new Thread(remoteObj);
} catch (Exception ex) { ex.printStackTrace(); }
remote.start();
Scene scene = new Scene((Parent) root.load());
FXMLController controller = root.<FXMLController>getController();
controller.initData(remoteObj);
scene.getStylesheets().add("/styles/Styles.css");
stage.setTitle("TestProjects ...");
stage.setScene(scene);
stage.show();
}
/**
* The main() method is ignored in correctly deployed JavaFX application.
* main() serves only as fallback in case the application can not be
* launched through deployment artifacts, e.g., in IDEs with limited FX
* support. NetBeans ignores main().
*
* @param args the command line arguments
*/
public static void main(String[] args) {
launch(args);
}
}
Scene.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.TextArea?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1" fx:controller="de.freakyonline.testproject.FXMLController">
<center>
<TextArea fx:id="testTextArea" prefHeight="200.0" prefWidth="200.0" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
Remote.java:
/*
* To change this license header, choose License Headers in Project Properties.
* To change this template file, choose Tools | Templates
* and open the template in the editor.
*/
package de.freakyonline.testproject;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
/**
*
* @author uwe
*/
public class Remote implements Runnable {
private String testVar;
public Remote (String testVar) {
this.testVar = testVar;
}
public String getVar() {
return testVar;
}
public void run() {
}
}
控制器的 initialize()
方法在加载 FXML 时由 FXMLLoader
调用,即在调用 load()
期间调用。在您的示例代码中,您在调用 load()
之后调用 initData()
,因此很明显 testVar
在 initialize()
方法时无法初始化被执行。由于示例代码中的控制器是由 FXMLLoader
创建的,因此您不能在调用 initialize()
之前调用 initData(...)
。
(另外:使用一些简单的调试技术,例如使用逐步调试器,或者甚至只是在调用每个方法时打印一条消息,就会非常清楚这里的问题是什么。)
最简单的修复方法就是将依赖于 testVar
的代码移动到 initData()
方法(或其他一些调用 after 的方法 testVar
初始化):
public class FXMLController implements Initializable {
String testVar;
@FXML
private ResourceBundle resources;
@FXML
private URL location;
@FXML
private TextArea testTextArea;
@Override
public void initialize(URL url, ResourceBundle rb) {
}
void initData(Remote remoteObj) {
this.testVar = remoteObj.getVar();
testTextArea.appendText("TestVar: " + testVar);
}
}
这里的小缺点是控制器的初始化分布在多个方法中,在控制器生命周期的不同点执行。其他选项包括在代码中设置控制器,而不是在 FXML 文件中指定控制器 class,或使用控制器工厂。在代码中设置控制器的缺点是,如果您使用工具(例如 Scene Builder)设计 FXML,它不会意识到正在使用的控制器 class。使用控制器工厂更复杂,但可以避免这个问题。