如何从常规 class 访问控制器 class 的字段? - JavaFX 胶子
How can I access the fields of a controller class, from a regular class? - JavaFX Gluon
我正在使用 JavaFX 通过 Gluon 框架创建 Android/Iphone 应用程序。
我知道 "how can I get the controller class" 这种类型的问题。但是这次不一样。
我知道如何获得控制器 class,但这不是我要的。我问如何在不创建任何新对象的情况下从控制器 class 访问字段。
假设我们有一个像这样的 JavaFX 控制器class:
public class PrimaryPresenter {
@FXML
private View primary;
@FXML
public LineChart<String, Number> lineChart; // Every time we update the socket, we update the chart too
public void initialize() {
primary.setShowTransitionFactory(BounceInRightTransition::new);
primary.showingProperty().addListener((obs, oldValue, newValue) -> {
if (newValue) {
AppBar appBar = MobileApplication.getInstance().getAppBar();
appBar.setNavIcon(MaterialDesignIcon.MENU.button(e ->
MobileApplication.getInstance().getDrawer().open()));
appBar.setTitleText("Plot");
}
});
/*
* Initial stuffs for the lineChart
*/
lineChart.setTitle("Adaptive MPC");
}
}
并且我想从另一个 class 访问 lineChart
对象而不创建新的 PrimaryPresenter
控制器 class。 FXML 文件由 Scene Builder 创建。
我之所以问这个问题,是因为我有另一个 class 通过线程循环,该线程将实时更新 lineChart
对象。
这是我的答案。在每个 Gluon 项目中,都有一个名为 GluonApplication
的 class,它看起来像这样:
package com.gluonapplication;
import com.gluonapplication.thread.SocketConnection;
import com.gluonapplication.views.PrimaryView;
import com.gluonapplication.views.SecondaryView;
import com.gluonhq.charm.glisten.application.MobileApplication;
import com.gluonhq.charm.glisten.visual.Swatch;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class GluonApplication extends MobileApplication {
public static final String PRIMARY_VIEW = HOME_VIEW;
public static final String SECONDARY_VIEW = "Secondary View";
@Override
public void init() {
addViewFactory(PRIMARY_VIEW, () -> new PrimaryView().getView());
addViewFactory(SECONDARY_VIEW, () -> new SecondaryView().getView());
DrawerManager.buildDrawer(this);
}
@Override
public void postInit(Scene scene) {
Swatch.GREEN.assignTo(scene);
scene.getStylesheets().add(GluonApplication.class.getResource("style.css").toExternalForm());
((Stage) scene.getWindow()).getIcons().add(new Image(GluonApplication.class.getResourceAsStream("/icon2.png")));
}
}
访问控制器 classes 中的所有字段。只需这样做:
public class GluonApplication extends MobileApplication {
public static final String PRIMARY_VIEW = HOME_VIEW;
public static final String SECONDARY_VIEW = "Secondary View";
private SocketConnection socketConnection;
private View primaryView; // Add
private View secondaryView; // Add
@Override
public void init() {
primaryView = new PrimaryView().getView();
secondaryView = new SecondaryView().getView();
addViewFactory(PRIMARY_VIEW, () -> primaryView);
addViewFactory(SECONDARY_VIEW, () -> secondaryView);
DrawerManager.buildDrawer(this);
/*
* This will start the socket connection
*/
socketConnection = new SocketConnection(primaryView, secondaryView);
socketConnection.start();
}
@Override
public void postInit(Scene scene) {
Swatch.GREEN.assignTo(scene);
scene.getStylesheets().add(GluonApplication.class.getResource("style.css").toExternalForm());
((Stage) scene.getWindow()).getIcons().add(new Image(GluonApplication.class.getResourceAsStream("/icon2.png")));
}
}
然后在SocketConnection的构造函数中。您可以像这样访问字段:
/*
* Constructor
*/
public SocketConnection(View primaryView, View secondaryView) {
/*
* For secondaryView
*/
statusTextField = (TextField) secondaryView.lookup("#statusTextField");
ipAddressTextField = (TextField) secondaryView.lookup("#ipAddressTextField");
startSignalModeComboBox = (ComboBox<String>) secondaryView.lookup("#startSignalModeComboBox");
predictHorizonTextField = (TextField) secondaryView.lookup("#predictHorizonTextField");
controlHorizonTextField = (TextField) secondaryView.lookup("#controlHorizonTextField");
sampleTimeTextField = (TextField) secondaryView.lookup("#sampleTimeTextField");
pwmDutyCallTextField = (TextField) secondaryView.lookup("#pwmDutyCallTextField");
endTimeOfStartSignalTextField = (TextField) secondaryView.lookup("#endTimeOfStartSignalTextField");
referencePointTextField = (TextField) secondaryView.lookup("#referencePointTextField");
portTextField = (TextField) secondaryView.lookup("#portTextField");
/*
* For primaryView
*/
lineChart = (LineChart<String, Number>) primaryView.lookup("#lineChart");
/*
* Declare the data object inside the chart
*/
time_output = new Series<String, Number>();
lineChart.getData().add(time_output);
}
我正在使用 JavaFX 通过 Gluon 框架创建 Android/Iphone 应用程序。
我知道 "how can I get the controller class" 这种类型的问题。但是这次不一样。
我知道如何获得控制器 class,但这不是我要的。我问如何在不创建任何新对象的情况下从控制器 class 访问字段。
假设我们有一个像这样的 JavaFX 控制器class:
public class PrimaryPresenter {
@FXML
private View primary;
@FXML
public LineChart<String, Number> lineChart; // Every time we update the socket, we update the chart too
public void initialize() {
primary.setShowTransitionFactory(BounceInRightTransition::new);
primary.showingProperty().addListener((obs, oldValue, newValue) -> {
if (newValue) {
AppBar appBar = MobileApplication.getInstance().getAppBar();
appBar.setNavIcon(MaterialDesignIcon.MENU.button(e ->
MobileApplication.getInstance().getDrawer().open()));
appBar.setTitleText("Plot");
}
});
/*
* Initial stuffs for the lineChart
*/
lineChart.setTitle("Adaptive MPC");
}
}
并且我想从另一个 class 访问 lineChart
对象而不创建新的 PrimaryPresenter
控制器 class。 FXML 文件由 Scene Builder 创建。
我之所以问这个问题,是因为我有另一个 class 通过线程循环,该线程将实时更新 lineChart
对象。
这是我的答案。在每个 Gluon 项目中,都有一个名为 GluonApplication
的 class,它看起来像这样:
package com.gluonapplication;
import com.gluonapplication.thread.SocketConnection;
import com.gluonapplication.views.PrimaryView;
import com.gluonapplication.views.SecondaryView;
import com.gluonhq.charm.glisten.application.MobileApplication;
import com.gluonhq.charm.glisten.visual.Swatch;
import javafx.scene.Scene;
import javafx.scene.image.Image;
import javafx.stage.Stage;
public class GluonApplication extends MobileApplication {
public static final String PRIMARY_VIEW = HOME_VIEW;
public static final String SECONDARY_VIEW = "Secondary View";
@Override
public void init() {
addViewFactory(PRIMARY_VIEW, () -> new PrimaryView().getView());
addViewFactory(SECONDARY_VIEW, () -> new SecondaryView().getView());
DrawerManager.buildDrawer(this);
}
@Override
public void postInit(Scene scene) {
Swatch.GREEN.assignTo(scene);
scene.getStylesheets().add(GluonApplication.class.getResource("style.css").toExternalForm());
((Stage) scene.getWindow()).getIcons().add(new Image(GluonApplication.class.getResourceAsStream("/icon2.png")));
}
}
访问控制器 classes 中的所有字段。只需这样做:
public class GluonApplication extends MobileApplication {
public static final String PRIMARY_VIEW = HOME_VIEW;
public static final String SECONDARY_VIEW = "Secondary View";
private SocketConnection socketConnection;
private View primaryView; // Add
private View secondaryView; // Add
@Override
public void init() {
primaryView = new PrimaryView().getView();
secondaryView = new SecondaryView().getView();
addViewFactory(PRIMARY_VIEW, () -> primaryView);
addViewFactory(SECONDARY_VIEW, () -> secondaryView);
DrawerManager.buildDrawer(this);
/*
* This will start the socket connection
*/
socketConnection = new SocketConnection(primaryView, secondaryView);
socketConnection.start();
}
@Override
public void postInit(Scene scene) {
Swatch.GREEN.assignTo(scene);
scene.getStylesheets().add(GluonApplication.class.getResource("style.css").toExternalForm());
((Stage) scene.getWindow()).getIcons().add(new Image(GluonApplication.class.getResourceAsStream("/icon2.png")));
}
}
然后在SocketConnection的构造函数中。您可以像这样访问字段:
/*
* Constructor
*/
public SocketConnection(View primaryView, View secondaryView) {
/*
* For secondaryView
*/
statusTextField = (TextField) secondaryView.lookup("#statusTextField");
ipAddressTextField = (TextField) secondaryView.lookup("#ipAddressTextField");
startSignalModeComboBox = (ComboBox<String>) secondaryView.lookup("#startSignalModeComboBox");
predictHorizonTextField = (TextField) secondaryView.lookup("#predictHorizonTextField");
controlHorizonTextField = (TextField) secondaryView.lookup("#controlHorizonTextField");
sampleTimeTextField = (TextField) secondaryView.lookup("#sampleTimeTextField");
pwmDutyCallTextField = (TextField) secondaryView.lookup("#pwmDutyCallTextField");
endTimeOfStartSignalTextField = (TextField) secondaryView.lookup("#endTimeOfStartSignalTextField");
referencePointTextField = (TextField) secondaryView.lookup("#referencePointTextField");
portTextField = (TextField) secondaryView.lookup("#portTextField");
/*
* For primaryView
*/
lineChart = (LineChart<String, Number>) primaryView.lookup("#lineChart");
/*
* Declare the data object inside the chart
*/
time_output = new Series<String, Number>();
lineChart.getData().add(time_output);
}