JavaFX:检索节点
我有两个JavaFX:检索节点,javafx,fxml,Javafx,Fxml,我有两个FXML文档,每个文档代表一个视图,让我们称它们为View1和View2,我将它们分别放在选项卡中(选项卡1和选项卡2)的选项卡窗格中 现在在View1的Controller1中,我有一个事件将我的TabPane的selectedItem从Tab1切换到Tab2。我的问题是如何从Controller1 总的来说。如何在Javafx中检索某个节点 编辑 视图1 主视图 <TabPane fx:id="tabPane" fx:controller="controllers.MainCo
FXML
文档,每个文档代表一个视图,让我们称它们为View1
和View2
,我将它们分别放在选项卡
中(选项卡1
和选项卡2
)的选项卡窗格中
现在在View1
的Controller1
中,我有一个事件将我的TabPane
的selectedItem
从Tab1
切换到Tab2
。我的问题是如何从Controller1
总的来说。如何在Javafx
中检索某个节点
编辑
视图1
主视图
<TabPane fx:id="tabPane" fx:controller="controllers.MainController"/>
您应该创建一个“视图模型”,它封装视图的当前状态,并与每个控制器共享它。然后从主控制器观察,并做出相应的响应
例如:
public class ApplicationState {
private final StringProperty currentViewName = new SimpleStringProperty();
public StringProperty currentViewNameProperty() {
return currentViewName ;
}
public final String getCurrentViewName() {
return currentViewNameProperty().get();
}
public final void setCurrentViewName(String viewName) {
currentViewNameProperty().set(viewName);
}
}
现在您可以这样做了(注意,我在这里也删除了多余的重复代码):
请注意,由于控制器没有arg构造函数,因此我使用loader.setController(…)
在代码中设置它们。这意味着您必须从view1和view2的fxml文件中删除fx:controller
属性,例如,您的view1.fxml变为:
这种设计的优点是,当你的老板在8个月后走进你的办公室,说“客户不喜欢选项卡窗格,用一次只显示一个屏幕的东西来代替它”时,很容易做出这样的更改,因为一切都被适当地解耦了。(您只需更改主视图及其控制器,其他任何视图或控制器都不会更改。)如果将选项卡窗格暴露给所有其他控制器,则必须找到您访问过的所有位置才能进行类似更改。您应该创建一个“视图模型”它封装视图的当前状态,并与每个控制器共享。然后从主控制器观察,并做出相应的响应
例如:
public class ApplicationState {
private final StringProperty currentViewName = new SimpleStringProperty();
public StringProperty currentViewNameProperty() {
return currentViewName ;
}
public final String getCurrentViewName() {
return currentViewNameProperty().get();
}
public final void setCurrentViewName(String viewName) {
currentViewNameProperty().set(viewName);
}
}
现在您可以这样做了(注意,我在这里也删除了多余的重复代码):
请注意,由于控制器没有arg构造函数,因此我使用loader.setController(…)
在代码中设置它们。这意味着您必须从view1和view2的fxml文件中删除fx:controller
属性,例如,您的view1.fxml变为:
这种设计的优点是,当你的老板在8个月后走进你的办公室,说“客户不喜欢选项卡窗格,用一次只显示一个屏幕的东西来代替它”时,很容易做出这样的更改,因为一切都被适当地解耦了。(您只需更改主视图及其控制器,其他任何视图或控制器都不会更改。)如果将选项卡窗格暴露给所有其他控制器,则必须找到您访问过的所有位置才能进行类似更改。通常,您不应该从控制器中的一个视图访问另一个视图的控件。相反,改变一些可观察的数据,并在需要的地方观察这些数据。如果你能用一个例子来演示你的问题,那么在这里提供一个真实的答案会更容易。谢谢你的编辑,但是你能校对一下并修正打字错误吗?openView1()
不应该是openView2()
?我假设MainView中的mainController
应该是mainController
?一般来说,您不应该从控制器中的一个视图访问另一个视图的控件。相反,改变一些可观察的数据,并在需要的地方观察这些数据。如果你能用一个例子来演示你的问题,那么在这里提供一个真实的答案会更容易。谢谢你的编辑,但是你能校对一下并修正打字错误吗?openView1()
不应该是openView2()
?我假设MainView中的mainController
应该是mainController
?JavaFX可能在某些方面有所欠缺,但我认为它最好的一面是它以某种方式迫使您使用MVC模型。非常impressive@m0skit0是(至少有一个MVC/MVP/MVVM/etc)。大画面的设计非常好,即使一些细节可能需要一些调整。从长远来看,这可能是一个好迹象。JavaFX可能在某些方面有所欠缺,但它最好的一面是,它以某种方式迫使您使用MVC模型。非常好impressive@m0skit0是(至少有一个MVC/MVP/MVVM/etc)。大画面的设计非常好,即使一些细节可能需要一些调整。从长远来看,这可能是一个好迹象。
public class MainController implements Initializable {
@FXML
public TabPane tabPane;
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
try {
tabPane.getTabs().add(createView1Tab());
tabPane.getTabs().add(createView2Tab());
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected Tab createView1Tab() throws IOException {
Tab tab = new Tab();
tab.setContent(FXMLLoader.load(getClass().getResource("/views/View1.fxml")));
return tab;
}
protected Tab createView2Tab() throws IOException {
Tab tab = new Tab();
tab.setContent(FXMLLoader.load(getClass().getResource("/views/View2.fxml")));
return tab;
}
}
public class ApplicationState {
private final StringProperty currentViewName = new SimpleStringProperty();
public StringProperty currentViewNameProperty() {
return currentViewName ;
}
public final String getCurrentViewName() {
return currentViewNameProperty().get();
}
public final void setCurrentViewName(String viewName) {
currentViewNameProperty().set(viewName);
}
}
public class MainController implements Initializable {
@FXML
public TabPane tabPane;
private final ApplicationState appState = new ApplicationState();
private final Map<String, Tab> views = new HashMap<>();
@Override
public void initialize(URL arg0, ResourceBundle arg1) {
try {
tabPane.getTabs().add(createViewTab("View1", new Controller1(appState)));
tabPane.getTabs().add(createViewTab("View2", new Controller2(appState)));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
appState.currentViewNameProperty().addListener((obs, oldView, newView) ->
tabPane.getSelectionModel().select(views.get(newView)));
appState.setCurrentViewName("View1");
}
protected Tab createViewTab(String viewName, Object controller) throws IOException {
Tab tab = new Tab();
FXMLLoader loader = new FXMLLoader(getClass().getResource("/views/"+viewName+".fxml"));
loader.setController(controller);
tab.setContent(loader.load());
views.put(viewName, tab);
return tab;
}
}
public class Controller1{
private final ApplicationState appState ;
public Controller1(ApplicationState appState) {
this.appState = appState ;
}
public void openView2(){
appState.setCurrentViewName("View2");
}
}