通过单独的 CheckBox 隐藏 TableView 的 TableColumns Window
Hide TableColumns of TableView through CheckBox on separate Window
我有一个用 fxml 编写的 window,带有一个 TableView 和一些 TableColumns 以及其他东西。
我正在尝试在控制器中为此 window 创建一个函数,使用户能够 select 通过单独的 window 上的一组复选框来显示列。
此 Window 将是 HealthCheckTab 的子项 window。它会有一个按钮,一旦按下就会获取所有复选框的状态,并会调用 HealtkcheckTab 中的一个函数来更新 Tableview,使不需要的列不可见。
这是带有 TableView(提取)的window
</TitledPane>
<TitledPane fx:id="classificationNumbers" animated="false"
text="HealthCheck Classification Numbers">
<content>
<ScrollPane fitToHeight="true" fitToWidth="true"
hbarPolicy="ALWAYS" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" pannable="true">
<content>
<TableView fx:id="HcTable" editable="true"
maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
minWidth="-Infinity" tableMenuButtonVisible="true">
<columns>
<TableColumn fx:id="colId" editable="false"
maxWidth="-Infinity" minWidth="40.0" prefWidth="-1.0" text="ID" />
<TableColumn fx:id="colName" editable="false"
maxWidth="1.7976931348623157E308" minWidth="60.0"
prefWidth="-1.0" text="Name" />
<TableColumn fx:id="colVal" maxWidth="1.7976931348623157E308"
minWidth="55.0" prefWidth="-1.0" text="Value" />
<TableColumn fx:id="colDescrCn" editable="false"
maxWidth="1.7976931348623157E308" minWidth="90.0"
prefWidth="-1.0" text="Comment (CN)" />
<TableColumn fx:id="colDatatype" editable="false"
maxWidth="1.7976931348623157E308" minWidth="80.0"
prefWidth="-1.0" text="Datatype" />
<TableColumn fx:id="colTool" maxWidth="1.7976931348623157E308"
minWidth="50.0" prefWidth="-1.0" text="Tool" visible="false" />
<TableColumn fx:id="colPrio" editable="false"
maxWidth="1.7976931348623157E308" minWidth="60.0"
prefWidth="-1.0" text="Priority" />
<TableColumn fx:id="colScope" maxWidth="1.7976931348623157E308"
minWidth="50.0" prefWidth="-1.0" text="Scope" visible="false" />
<TableColumn fx:id="colAvg" editable="false"
maxWidth="1.7976931348623157E308" minWidth="50.0"
prefWidth="-1.0" text="AVG" visible="false" />
<TableColumn fx:id="colMin" maxWidth="1.7976931348623157E308"
minWidth="50.0" prefWidth="-1.0" text="MIN" visible="false" />
<TableColumn fx:id="colRelComp" prefWidth="122.0"
text="Relative Comparable" />
</columns>
</TableView>
</content>
</ScrollPane>
</content>
</TitledPane>
这是控制器(摘录)
@FXML
private TreeView<String> HCTree;
@FXML
private TableView<Map> HcTable;
@FXML
private TableColumn<Map, String> colId;
@FXML
private TableColumn<Map, String> colName;
@FXML
private TableColumn<Map, String> colVal;
@FXML
private TableColumn<Map, String> colDescrCn;
@FXML
private TableColumn<Map, String> colDatatype;
@FXML
private TableColumn<Map, String> colTool;
@FXML
private TableColumn<Map, String> colPrio;
@FXML
private TableColumn<Map, String> colScope;
@FXML
private TableColumn<Map, String> colAvg;
@FXML
private TableColumn<Map, String> colMin;
@FXML
private TableColumn<Map, String> colRelComp;
// -----------------------------------------------------------------------------------------------
// REFRESH TABLE
// -----------------------------------------------------------------------------------------------
public void refreshTable() {
System.out.println("apply");
colScope.setVisible(true);
//colId.setVisible(false);
}
单独 window(提取)
@FXML
private void handleApplyViewOptions() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("HealthCheckTab.fxml"));
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(new Scene(loader.load()));
HealthCheckTabController controller = loader.<HealthCheckTabController> getController();
controller.refreshTable();
} catch (IOException e) {
java.lang.System.err.println(e.getStackTrace());
}
Stage stage = (Stage) btnApply.getScene().getWindow();
stage.close();
}
refreshTable 函数根本不隐藏范围列。
不知道为什么...
您正在加载 HealthCheckTab.fxml
中定义的 UI 的新副本,并在控制器上为该 UI 调用 refreshTable
(从不显示)。
可能更简单的方法是在您创建的对话框中注册一个 onHidden
处理程序,并在对话框隐藏时调用 refreshTable
。
这是一个 SSCCE:
Main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<BorderPane fx:controller="MainController" xmlns:fx="http://javafx.com/fxml/1">
<center>
<TableView >
<columns>
<TableColumn fx:id="nameColumn" text="Name" />
<TableColumn fx:id="optionalColumn" text="Data" />
</columns>
</TableView>
</center>
<bottom>
<HBox alignment="CENTER">
<Button text="Configure View" onAction="#showViewOptions" />
<padding>
<Insets top="5" left="5" bottom="5" right="5"/>
</padding>
</HBox>
</bottom>
</BorderPane>
MainController.java:
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.stage.Stage;
public class MainController {
@FXML
private TableColumn<Void, Void> nameColumn ;
@FXML
private TableColumn<Void, Void> optionalColumn ;
@FXML
private void showViewOptions() throws IOException {
FXMLLoader loader = new FXMLLoader(ViewOptionsController.class.getResource("ViewOptions.fxml"));
Parent root = loader.load();
ViewOptionsController controller = loader.getController();
controller.setOptionalColumnVisible(optionalColumn.isVisible());
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.initOwner(nameColumn.getTableView().getScene().getWindow());
stage.setOnHidden(e -> {
refreshTable(controller.isOptionalColumnVisible());
});
stage.show();
}
private void refreshTable(boolean showOptionalColumn) {
optionalColumn.setVisible(showOptionalColumn);
}
}
ViewOptions.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox fx:controller="ViewOptionsController" spacing="5" alignment="center" xmlns:fx="http://javafx.com/fxml/1">
<CheckBox text="Show Data Column" fx:id="optionalColumnVisibleCheckBox" />
<Button text="OK" onAction="#close" />
<padding>
<Insets top="5" left="5" right="5" bottom="5"/>
</padding>
</VBox>
ViewOptionsController.java:
import javafx.beans.property.BooleanProperty;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
public class ViewOptionsController {
@FXML
private CheckBox optionalColumnVisibleCheckBox ;
public BooleanProperty optionalColumnVisibleProperty() {
return optionalColumnVisibleCheckBox.selectedProperty();
}
public final boolean isOptionalColumnVisible() {
return optionalColumnVisibleProperty().get();
}
public final void setOptionalColumnVisible(boolean optionalColumnVisible) {
optionalColumnVisibleProperty().set(optionalColumnVisible);
}
@FXML
private void close() {
optionalColumnVisibleCheckBox.getScene().getWindow().hide();
}
}
申请class:
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HideColumnsFromDialog extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(MainController.class.getResource("Main.fxml"));
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
顺便说一句,请注意,您在此处实现的功能已内置于 table 视图中:您可以使用
<TableView fx:id="HcTable" tableMenuButtonVisible="true" ... >
并且 table 将显示一个按钮,其中显示一个下拉菜单,用户可以从中选择哪些列是可见的。
我有一个用 fxml 编写的 window,带有一个 TableView 和一些 TableColumns 以及其他东西。 我正在尝试在控制器中为此 window 创建一个函数,使用户能够 select 通过单独的 window 上的一组复选框来显示列。 此 Window 将是 HealthCheckTab 的子项 window。它会有一个按钮,一旦按下就会获取所有复选框的状态,并会调用 HealtkcheckTab 中的一个函数来更新 Tableview,使不需要的列不可见。
这是带有 TableView(提取)的window
</TitledPane>
<TitledPane fx:id="classificationNumbers" animated="false"
text="HealthCheck Classification Numbers">
<content>
<ScrollPane fitToHeight="true" fitToWidth="true"
hbarPolicy="ALWAYS" maxHeight="1.7976931348623157E308"
maxWidth="1.7976931348623157E308" pannable="true">
<content>
<TableView fx:id="HcTable" editable="true"
maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308"
minWidth="-Infinity" tableMenuButtonVisible="true">
<columns>
<TableColumn fx:id="colId" editable="false"
maxWidth="-Infinity" minWidth="40.0" prefWidth="-1.0" text="ID" />
<TableColumn fx:id="colName" editable="false"
maxWidth="1.7976931348623157E308" minWidth="60.0"
prefWidth="-1.0" text="Name" />
<TableColumn fx:id="colVal" maxWidth="1.7976931348623157E308"
minWidth="55.0" prefWidth="-1.0" text="Value" />
<TableColumn fx:id="colDescrCn" editable="false"
maxWidth="1.7976931348623157E308" minWidth="90.0"
prefWidth="-1.0" text="Comment (CN)" />
<TableColumn fx:id="colDatatype" editable="false"
maxWidth="1.7976931348623157E308" minWidth="80.0"
prefWidth="-1.0" text="Datatype" />
<TableColumn fx:id="colTool" maxWidth="1.7976931348623157E308"
minWidth="50.0" prefWidth="-1.0" text="Tool" visible="false" />
<TableColumn fx:id="colPrio" editable="false"
maxWidth="1.7976931348623157E308" minWidth="60.0"
prefWidth="-1.0" text="Priority" />
<TableColumn fx:id="colScope" maxWidth="1.7976931348623157E308"
minWidth="50.0" prefWidth="-1.0" text="Scope" visible="false" />
<TableColumn fx:id="colAvg" editable="false"
maxWidth="1.7976931348623157E308" minWidth="50.0"
prefWidth="-1.0" text="AVG" visible="false" />
<TableColumn fx:id="colMin" maxWidth="1.7976931348623157E308"
minWidth="50.0" prefWidth="-1.0" text="MIN" visible="false" />
<TableColumn fx:id="colRelComp" prefWidth="122.0"
text="Relative Comparable" />
</columns>
</TableView>
</content>
</ScrollPane>
</content>
</TitledPane>
这是控制器(摘录)
@FXML
private TreeView<String> HCTree;
@FXML
private TableView<Map> HcTable;
@FXML
private TableColumn<Map, String> colId;
@FXML
private TableColumn<Map, String> colName;
@FXML
private TableColumn<Map, String> colVal;
@FXML
private TableColumn<Map, String> colDescrCn;
@FXML
private TableColumn<Map, String> colDatatype;
@FXML
private TableColumn<Map, String> colTool;
@FXML
private TableColumn<Map, String> colPrio;
@FXML
private TableColumn<Map, String> colScope;
@FXML
private TableColumn<Map, String> colAvg;
@FXML
private TableColumn<Map, String> colMin;
@FXML
private TableColumn<Map, String> colRelComp;
// -----------------------------------------------------------------------------------------------
// REFRESH TABLE
// -----------------------------------------------------------------------------------------------
public void refreshTable() {
System.out.println("apply");
colScope.setVisible(true);
//colId.setVisible(false);
}
单独 window(提取)
@FXML
private void handleApplyViewOptions() {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("HealthCheckTab.fxml"));
Stage stage = new Stage(StageStyle.DECORATED);
stage.setScene(new Scene(loader.load()));
HealthCheckTabController controller = loader.<HealthCheckTabController> getController();
controller.refreshTable();
} catch (IOException e) {
java.lang.System.err.println(e.getStackTrace());
}
Stage stage = (Stage) btnApply.getScene().getWindow();
stage.close();
}
refreshTable 函数根本不隐藏范围列。 不知道为什么...
您正在加载 HealthCheckTab.fxml
中定义的 UI 的新副本,并在控制器上为该 UI 调用 refreshTable
(从不显示)。
可能更简单的方法是在您创建的对话框中注册一个 onHidden
处理程序,并在对话框隐藏时调用 refreshTable
。
这是一个 SSCCE:
Main.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<BorderPane fx:controller="MainController" xmlns:fx="http://javafx.com/fxml/1">
<center>
<TableView >
<columns>
<TableColumn fx:id="nameColumn" text="Name" />
<TableColumn fx:id="optionalColumn" text="Data" />
</columns>
</TableView>
</center>
<bottom>
<HBox alignment="CENTER">
<Button text="Configure View" onAction="#showViewOptions" />
<padding>
<Insets top="5" left="5" bottom="5" right="5"/>
</padding>
</HBox>
</bottom>
</BorderPane>
MainController.java:
import java.io.IOException;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.stage.Stage;
public class MainController {
@FXML
private TableColumn<Void, Void> nameColumn ;
@FXML
private TableColumn<Void, Void> optionalColumn ;
@FXML
private void showViewOptions() throws IOException {
FXMLLoader loader = new FXMLLoader(ViewOptionsController.class.getResource("ViewOptions.fxml"));
Parent root = loader.load();
ViewOptionsController controller = loader.getController();
controller.setOptionalColumnVisible(optionalColumn.isVisible());
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.initOwner(nameColumn.getTableView().getScene().getWindow());
stage.setOnHidden(e -> {
refreshTable(controller.isOptionalColumnVisible());
});
stage.show();
}
private void refreshTable(boolean showOptionalColumn) {
optionalColumn.setVisible(showOptionalColumn);
}
}
ViewOptions.fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.layout.VBox?>
<?import javafx.scene.control.CheckBox?>
<?import javafx.scene.control.Button?>
<?import javafx.geometry.Insets?>
<VBox fx:controller="ViewOptionsController" spacing="5" alignment="center" xmlns:fx="http://javafx.com/fxml/1">
<CheckBox text="Show Data Column" fx:id="optionalColumnVisibleCheckBox" />
<Button text="OK" onAction="#close" />
<padding>
<Insets top="5" left="5" right="5" bottom="5"/>
</padding>
</VBox>
ViewOptionsController.java:
import javafx.beans.property.BooleanProperty;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
public class ViewOptionsController {
@FXML
private CheckBox optionalColumnVisibleCheckBox ;
public BooleanProperty optionalColumnVisibleProperty() {
return optionalColumnVisibleCheckBox.selectedProperty();
}
public final boolean isOptionalColumnVisible() {
return optionalColumnVisibleProperty().get();
}
public final void setOptionalColumnVisible(boolean optionalColumnVisible) {
optionalColumnVisibleProperty().set(optionalColumnVisible);
}
@FXML
private void close() {
optionalColumnVisibleCheckBox.getScene().getWindow().hide();
}
}
申请class:
import java.io.IOException;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class HideColumnsFromDialog extends Application {
@Override
public void start(Stage primaryStage) throws IOException {
Parent root = FXMLLoader.load(MainController.class.getResource("Main.fxml"));
Scene scene = new Scene(root, 600, 600);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
顺便说一句,请注意,您在此处实现的功能已内置于 table 视图中:您可以使用
<TableView fx:id="HcTable" tableMenuButtonVisible="true" ... >
并且 table 将显示一个按钮,其中显示一个下拉菜单,用户可以从中选择哪些列是可见的。