- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
问题
TableView 的 setTableMenuButtonVisible 提供了一种机制来更改表列的可见性。然而,该功能还有很多不足之处:
public class TableViewSample extends Application {
private final TableView table = new TableView();
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
Scene scene = new Scene(new Group());
stage.setTitle("Table View Sample");
stage.setWidth(300);
stage.setHeight(500);
// create table columns
TableColumn firstNameCol = new TableColumn("First Name");
TableColumn lastNameCol = new TableColumn("Last Name");
TableColumn emailCol = new TableColumn("Email");
table.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
// add context menu
CustomMenuItem cmi;
ContextMenu cm = new ContextMenu();
// select all item
Label selectAll = new Label( "Select all");
selectAll.addEventHandler( MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
for( Object obj: table.getColumns()) {
((TableColumn) obj).setVisible(true);
} }
});
cmi = new CustomMenuItem( selectAll);
cmi.setHideOnClick(false);
cm.getItems().add( cmi);
// deselect all item
Label deselectAll = new Label("Deselect all");
deselectAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TableColumn) obj).setVisible(false);
}
}
});
cmi = new CustomMenuItem( deselectAll);
cmi.setHideOnClick(false);
cm.getItems().add( cmi);
// separator
cm.getItems().add( new SeparatorMenuItem());
// menu item for all columns
for( Object obj: table.getColumns()) {
TableColumn tableColumn = (TableColumn) obj;
CheckBox cb = new CheckBox( tableColumn.getText());
cb.selectedProperty().bindBidirectional( tableColumn.visibleProperty());
cmi = new CustomMenuItem( cb);
cmi.setHideOnClick(false);
cm.getItems().add( cmi);
}
// set context menu
table.setContextMenu(cm);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 0, 0, 10));
vbox.getChildren().addAll(table);
((Group) scene.getRoot()).getChildren().addAll(vbox);
stage.setScene(scene);
stage.show();
}
}
最佳答案
受到 ControlsFX 解决方案的启发,我自己使用反射解决了这个问题。如果有人有更好的想法和更清洁的方法而无需反射(reflection),我会全力以赴。我创建了一个 utils 类以区别于示例代码。
import java.lang.reflect.Field;
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.Label;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseEvent;
import com.sun.javafx.scene.control.skin.TableHeaderRow;
import com.sun.javafx.scene.control.skin.TableViewSkin;
public class TableViewUtils {
/**
* Make table menu button visible and replace the context menu with a custom context menu via reflection.
* The preferred height is modified so that an empty header row remains visible. This is needed in case you remove all columns, so that the menu button won't disappear with the row header.
* IMPORTANT: Modification is only possible AFTER the table has been made visible, otherwise you'd get a NullPointerException
* @param tableView
*/
public static void addCustomTableMenu( TableView tableView) {
// enable table menu
tableView.setTableMenuButtonVisible(true);
// get the table header row
TableHeaderRow tableHeaderRow = getTableHeaderRow((TableViewSkin) tableView.getSkin());
// get context menu via reflection
ContextMenu contextMenu = getContextMenu(tableHeaderRow);
// setting the preferred height for the table header row
// if the preferred height isn't set, then the table header would disappear if there are no visible columns
// and with it the table menu button
// by setting the preferred height the header will always be visible
// note: this may need adjustments in case you have different heights in columns (eg when you use grouping)
double defaultHeight = tableHeaderRow.getHeight();
tableHeaderRow.setPrefHeight(defaultHeight);
// modify the table menu
contextMenu.getItems().clear();
addCustomMenuItems( contextMenu, tableView);
}
/**
* Create a menu with custom items. The important thing is that the menu remains open while you click on the menu items.
* @param cm
* @param table
*/
private static void addCustomMenuItems( ContextMenu cm, TableView table) {
// create new context menu
CustomMenuItem cmi;
// select all item
Label selectAll = new Label("Select all");
selectAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TableColumn<?, ?>) obj).setVisible(true);
}
}
});
cmi = new CustomMenuItem(selectAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// deselect all item
Label deselectAll = new Label("Deselect all");
deselectAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TableColumn<?, ?>) obj).setVisible(false);
}
}
});
cmi = new CustomMenuItem(deselectAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// separator
cm.getItems().add(new SeparatorMenuItem());
// menu item for each of the available columns
for (Object obj : table.getColumns()) {
TableColumn<?, ?> tableColumn = (TableColumn<?, ?>) obj;
CheckBox cb = new CheckBox(tableColumn.getText());
cb.selectedProperty().bindBidirectional(tableColumn.visibleProperty());
cmi = new CustomMenuItem(cb);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
}
}
/**
* Find the TableHeaderRow of the TableViewSkin
*
* @param tableSkin
* @return
*/
private static TableHeaderRow getTableHeaderRow(TableViewSkin<?> tableSkin) {
// get all children of the skin
ObservableList<Node> children = tableSkin.getChildren();
// find the TableHeaderRow child
for (int i = 0; i < children.size(); i++) {
Node node = children.get(i);
if (node instanceof TableHeaderRow) {
return (TableHeaderRow) node;
}
}
return null;
}
/**
* Get the table menu, i. e. the ContextMenu of the given TableHeaderRow via
* reflection
*
* @param headerRow
* @return
*/
private static ContextMenu getContextMenu(TableHeaderRow headerRow) {
try {
// get columnPopupMenu field
Field privateContextMenuField = TableHeaderRow.class.getDeclaredField("columnPopupMenu");
// make field public
privateContextMenuField.setAccessible(true);
// get field
ContextMenu contextMenu = (ContextMenu) privateContextMenuField.get(headerRow);
return contextMenu;
} catch (Exception ex) {
ex.printStackTrace();
}
return null;
}
}
import javafx.application.Application;
import javafx.beans.property.SimpleStringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.stage.Stage;
public class CustomTableMenuDemo extends Application {
private final ObservableList<Person> data =
FXCollections.observableArrayList(
new Person("Jacob", "Smith", "jacob.smith@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Isabella", "Johnson", "isabella.johnson@example.com"),
new Person("Ethan", "Williams", "ethan.williams@example.com"),
new Person("Emma", "Jones", "emma.jones@example.com"),
new Person("Michael", "Brown", "michael.brown@example.com"));
public static void main(String[] args) {
launch(args);
}
@Override
public void start(Stage stage) {
stage.setTitle("Table Menu Demo");
stage.setWidth(500);
stage.setHeight(550);
// create table columns
TableColumn<Person, String> firstNameCol = new TableColumn<Person, String>("First Name");
firstNameCol.setMinWidth(100);
firstNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("firstName"));
TableColumn<Person, String> lastNameCol = new TableColumn<Person, String>("Last Name");
lastNameCol.setMinWidth(100);
lastNameCol.setCellValueFactory(new PropertyValueFactory<Person, String>("lastName"));
TableColumn<Person, String> emailCol = new TableColumn<Person, String>("Email");
emailCol.setMinWidth(180);
emailCol.setCellValueFactory(new PropertyValueFactory<Person, String>("email"));
TableView<Person> tableView = new TableView<>();
tableView.setPlaceholder(new Text("No content in table"));
tableView.setItems(data);
tableView.getColumns().addAll(firstNameCol, lastNameCol, emailCol);
final VBox vbox = new VBox();
vbox.setSpacing(5);
vbox.setPadding(new Insets(10, 10, 10, 10));
BorderPane borderPane = new BorderPane();
borderPane.setCenter( tableView);
vbox.getChildren().addAll( borderPane);
Scene scene = new Scene( vbox);
stage.setScene(scene);
stage.show();
// enable table menu button and add a custom menu to it
TableViewUtils.addCustomTableMenu(tableView);
}
public static class Person {
private final SimpleStringProperty firstName;
private final SimpleStringProperty lastName;
private final SimpleStringProperty email;
private Person(String fName, String lName, String email) {
this.firstName = new SimpleStringProperty(fName);
this.lastName = new SimpleStringProperty(lName);
this.email = new SimpleStringProperty(email);
}
public String getFirstName() {
return firstName.get();
}
public void setFirstName(String fName) {
firstName.set(fName);
}
public String getLastName() {
return lastName.get();
}
public void setLastName(String fName) {
lastName.set(fName);
}
public String getEmail() {
return email.get();
}
public void setEmail(String fName) {
email.set(fName);
}
}
}
import javafx.collections.ObservableList;
import javafx.event.EventHandler;
import javafx.geometry.Side;
import javafx.scene.Node;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ContextMenu;
import javafx.scene.control.CustomMenuItem;
import javafx.scene.control.Label;
import javafx.scene.control.SeparatorMenuItem;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.input.MouseEvent;
import com.sun.javafx.scene.control.skin.TableHeaderRow;
import com.sun.javafx.scene.control.skin.TableViewSkin;
public class TableViewUtils {
/**
* Make table menu button visible and replace the context menu with a custom context menu via reflection.
* The preferred height is modified so that an empty header row remains visible. This is needed in case you remove all columns, so that the menu button won't disappear with the row header.
* IMPORTANT: Modification is only possible AFTER the table has been made visible, otherwise you'd get a NullPointerException
* @param tableView
*/
public static void addCustomTableMenu( TableView tableView) {
// enable table menu
tableView.setTableMenuButtonVisible(true);
// replace internal mouse listener with custom listener
setCustomContextMenu( tableView);
}
private static void setCustomContextMenu( TableView table) {
TableViewSkin<?> tableSkin = (TableViewSkin<?>) table.getSkin();
// get all children of the skin
ObservableList<Node> children = tableSkin.getChildren();
// find the TableHeaderRow child
for (int i = 0; i < children.size(); i++) {
Node node = children.get(i);
if (node instanceof TableHeaderRow) {
TableHeaderRow tableHeaderRow = (TableHeaderRow) node;
// setting the preferred height for the table header row
// if the preferred height isn't set, then the table header would disappear if there are no visible columns
// and with it the table menu button
// by setting the preferred height the header will always be visible
// note: this may need adjustments in case you have different heights in columns (eg when you use grouping)
double defaultHeight = tableHeaderRow.getHeight();
tableHeaderRow.setPrefHeight(defaultHeight);
for( Node child: tableHeaderRow.getChildren()) {
// child identified as cornerRegion in TableHeaderRow.java
if( child.getStyleClass().contains( "show-hide-columns-button")) {
// get the context menu
ContextMenu columnPopupMenu = createContextMenu( table);
// replace mouse listener
child.setOnMousePressed(me -> {
// show a popupMenu which lists all columns
columnPopupMenu.show(child, Side.BOTTOM, 0, 0);
me.consume();
});
}
}
}
}
}
/**
* Create a menu with custom items. The important thing is that the menu remains open while you click on the menu items.
* @param cm
* @param table
*/
private static ContextMenu createContextMenu( TableView table) {
ContextMenu cm = new ContextMenu();
// create new context menu
CustomMenuItem cmi;
// select all item
Label selectAll = new Label("Select all");
selectAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TableColumn<?, ?>) obj).setVisible(true);
}
}
});
cmi = new CustomMenuItem(selectAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// deselect all item
Label deselectAll = new Label("Deselect all");
deselectAll.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>() {
@Override
public void handle(MouseEvent event) {
for (Object obj : table.getColumns()) {
((TableColumn<?, ?>) obj).setVisible(false);
}
}
});
cmi = new CustomMenuItem(deselectAll);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
// separator
cm.getItems().add(new SeparatorMenuItem());
// menu item for each of the available columns
for (Object obj : table.getColumns()) {
TableColumn<?, ?> tableColumn = (TableColumn<?, ?>) obj;
CheckBox cb = new CheckBox(tableColumn.getText());
cb.selectedProperty().bindBidirectional(tableColumn.visibleProperty());
cmi = new CustomMenuItem(cb);
cmi.setHideOnClick(false);
cm.getItems().add(cmi);
}
return cm;
}
}
关于menu - 适配 TableView 菜单按钮,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27739833/
ios10 适配-xcode8 问题解决: ios开发者,系统版本的更新,必定要跟着更新,不然有些功能不知道,开发的时候对可以体验,大打折扣了。 前段时间升级了xcode8,整体来说对oc的影响不
问题 TableView 的 setTableMenuButtonVisible 提供了一种机制来更改表列的可见性。然而,该功能还有很多不足之处: 菜单应保持打开状态。我有 e。 G。 15个表格列,
我正在开发一个使用 MapKit 的应用程序。鉴于 2012 年 6 月 11 日的 Apple 公告,我是否必须使用新的 API 完全重写它才能跟上这些变化? 最佳答案 iOS 6 仍处于 NDA
最近看了许多iphone x适配的文章,发现很少有介绍safearea的,就来随便写写 现在对于iphone x的适配,有一种常见的做法是给导航栏或tabbar增加一个固定的距离,比如顶部增加44
我正在使用 Big Nerd Ranch's recyclerview-multiselect库为我的 RecyclerView 的 CardViews 提供多选功能。我已经解决了大部分应用程序特定的
The Table with bad text-alignment 在图片中,您会看到文本对齐不正确的表格。 tbody 的元素不适合 thead 的元素。表头固定很重要,这样即使向下滚动也能看到。
我将尝试设置我的应用程序,以便它可以使用 Apple map 或 Google map ,所以我想我会有这样的东西: class AppleMap: MKMapView, MyMapProtocol
我已经在网站上工作了大约一个星期,我们需要包含一些非常规字体。没问题,我会在 CSS 中使用 @font-face{},它就像一个魅力。 . .除非你的名字是 Internet Explorer。 由
我遇到了一个问题,csv 文件中的字符显示为带有 ?在中间。 我已经编写了解析 csv 的代码,但我不明白为什么字符串不能正确读取 unicode 字符。这可能与我的实现有关: StreamReade
试图在底部模仿当前的谷歌地图栏。我失败了那么多,也尝试了那么多; CollapsingToolbar、BottomSheet、自定义库。 我想要的:当 BottomSheet 滑动时,让 map Vi
我有 5000 行 CSS 用于 Firefox、Opera,有时还有 IE 8。毕竟,account 告诉我,它必须在 IE 7 下正常工作。我该怎么做,而不重写 40% 的代码? 最佳答案 在
我使用 Glide 和 CircleTransform 将圆形图像放入此 ImageView。 ImageView 具有 wrap_content 属性,但是 ImageView 不适合 Circle
为什么 Apache Hive 需要 Apache Thrift?在 Thrift 的网站上,它说它可以用多种语言编译,但我不明白它适合哪里以及为什么 Hive 需要它。谢谢 最佳答案 引用 from
我使用此命令在 m4v 中转换了一些 YUV 视频,请注意我使用的是 CIF 格式的视频: ffmpeg -s cif -r 30 -i video.yuv -vcodec mpeg4 -g 30 -
我已从教程中获取代码并尝试对其进行修改以包括双向性和 GRU 的任意数量的层。 链接到使用单向、单层 GRU 的教程: https://pytorch.org/tutorials/intermedia
在使用 C++ 11 进行测试期间,我使用了以下结构: std::for_each( coll.begin(), coll.end(), [ &obj, expRes ]( const val
假设我有一个带有 std::pair 的 STL 容器。有什么方法可以使用 boost 为 STL 算法 lambda 调整对的秒数? std::vector> vec; const auto Pre
我有一个自定义的 ListView 适配器,它实现了一个 ImageThreadLoader 类。不幸的是,该类没有启用缓存选项 - 从 Web 下载图像并将它们保存为缓存。 然后我找到了这个 Laz
我有一个关于在 CSS 中使用 PHP 的一般性问题。我现在正在研究 Wordpress 主题,并希望尽可能地定制它。因此,我将我想通过 PHP 更改的 CSS 属性发送到一个为我更改它们的 JS 文
我安装了包 react-treebeard https://react.rocks/example/react-treebeard 允许我为我的 React TS 网站提供一个开箱即用的树控件,它允许
我是一名优秀的程序员,十分优秀!