项目场景:
最近在用JavaFX做一个简易的商城界面,大概想实现这样的功能:
- 左边显示用户的最近五个购买的产品 使用ListView
- 点击ListView的项目会定位到相应的tablerow位置 方便用户快速查找
- 中间显示所有可用产品 使用TableView
- 双击tablerow的Item将弹出alert 询问用户购买数量
- 右边是Filter 根据filter将tableview实时分类
问题描述
如何生成一个正确的tableview呢?
public TableView<Item> table= new TableView<>();
在使用 table.setItems(data) 给table传值之前,我们需要给data设置好格式, 常用格式是
private final ObservableList<Item> data =FXCollections.observableArrayList();
紧接着,去给每个tableview中的column设置好cellvalue的映射
nameColumn.setCellValueFactory(new PropertyValueFactory("name"));
这里的名字需要Item类中需要有例如public String getName()来对应。
表中有了数据,如何给tableview设置点击事件 - 双击row弹出窗口?
// table row 点击事件
table.setRowFactory( tv -> {TableRow<Item> row = new TableRow<>();row.setOnMouseClicked(event -> {// 点击两次 且 row不为空if (event.getClickCount() == 2 && (! row.isEmpty()) ) {Item itemInfo = row.getItem();// 点击以后的事件System.out.println(itemInfo.getName());Alert alert = new Alert(Alert.AlertType.CONFIRMATION);alert.setTitle(null);alert.setContentText("你想将” + itemInfo.getName() +“加入购物车吗?");Optional<ButtonType> result = alert.showAndWait();// if (result.get().equals(ButtonType.OK)...之类的}});return row ;
});
好了现在加入购物车功能完成了
ListView跟tableview逻辑差不多而且更简单,一个for循环遍历将String加进去List,最后list.setItems(你的list) 就完事了。
重点来了 要如何在点击ListView的时候 聚焦Tableview的内容?
苦苦找了很久 没有人讲 只能去翻oracle的doc了 文档在这里
TableView.TableViewFocusModel (JavaFX 8)
翻完发现我要的就是他的成员方法 focus() !那要怎么使用呢?
很简单 不需要去新建一个TableViewFocusModel了 直接用现有的 table.getFocusModel.focus(index) 就能直接使用
好了来看看代码吧
Solution 1
找到table中的index以后 使用
table.requestFocus(); table.getFocusModel().focus(i);
效果是这样
Solution 2 (我采取的方案)
list.getSelectionModel().selectedItemProperty().addListener((ObservableValue<? extends String> ov,String old_val, String new_val) -> {for (int i=0; i<data.size(); i++){if (data.get(i).getName().equals(new_val)){// table.requestFocus();// table.getFocusModel().focus(i);table.getSelectionModel().select(i);table.scrollTo(i);System.out.println(i);}}});
此处的table.scrollTo(i) 是很重要的 否则聚焦了在下面的产品 用户也看不到
最后剩下Filter怎么办呢 更简单 换成一个FilteredList就搞定了。
// category 筛选事件
category.setOnAction( (event -> {categoryChosen = (String) category.getValue();filteredList =new FilteredList<>(data, t -> {if (categoryChosen.equals("All")){return true;} else return t.getCategory().equals(categoryChosen);});table.setItems(filteredList);
}));
完美实现所有功能 使用这个古老的语言真是麻烦 网上都没什么教程 找来找去只能看英文的文档 那就写份中文的记录一下吧。这次还实现了很多很酷的功能 但是懒得记了。