JavaFX学习之样例7 博客分类: javafx分享 javafx表可编辑的表TextFiledCheckBox
程序员文章站
2024-02-28 23:02:46
...
该代码是个可编辑的table。
一般使用自定义tableCell实现cell的多样化,重写updateItem,设置Graphic和Text内容。若要实现编辑功能则可以重写startEdit和cancelEdit方法,这样就有在需要编辑时,显示需要的node,取消时,只显示text。
需要注意的地方是需要实现column.setOnEditCommit方法,更新pojo的值。因为cell的值对应pojo里面的get的值,若你不更新pojo,则cell值不变。
举个例子:value column的cell即对应NamedProperty的getValue。在方法updateItem里面参数item和getItem()方法获取的对象均等于getValue()。
但是当我注释掉setOnEditCommit方法里面的property.setValue(t.getNewValue()); 然后编辑value值,按逻辑来说getValue()没变,页面显示的值应该不会变化, 但是结果却变了。我在updateItem方法里面输出item和NamedProperty的getValue,发现不一样了。这让我疑惑了。我在想不应该啊,这二个值应该一样的。我试着重新加载,也就是把窗口缩小,直到看不到那行记录,然后在拉大(table会重新加载)。再一输出,页面显示的值变回来了,二个打印一样了。Item和getItem()的值始终是来自pojo的get方法的。
在代码里面可以看到,通过监听checkBox和textField的焦点集中属性来传递修改后的值。
正是通过commitEdit方法,修改了item的值。然后在cancel里面获取item的值,此时是最新的(在这里发现为什么item和get方法的值不一样了)。其实也不需要这样做,直接在cancel里面textField.getText或checkBox.isSelected获取最新值。
理解不对的地方希望大家评论下
这里有个javafx学习的中文网站,我把内容都丢那上面去了。
http://www.jfxee.com/
import java.lang.reflect.*; import java.util.Arrays; import java.util.logging.*; import javafx.application.Application; import javafx.beans.property.*; import javafx.beans.value.*; import javafx.collections.*; import javafx.event.EventHandler; import javafx.scene.Scene; import javafx.scene.control.*; import javafx.scene.control.TableColumn.CellEditEvent; import javafx.scene.control.cell.PropertyValueFactory; import javafx.scene.layout.*; import javafx.stage.Stage; import javafx.util.Callback; // click in the value column (a couple of times) to edit the value in the column. // property editors are defined only for String and Boolean properties. // change focus to something else to commit the edit. public class TableViewPropertyEditor extends Application { public static void main(String[] args) { launch(args); } @Override public void start(Stage stage) { final Person aPerson = new Person("Fred", true); final Label currentObjectValue = new Label(aPerson.toString()); TableView<NamedProperty> table = new TableView(); table.setEditable(true); table.setItems(createNamedProperties(aPerson)); TableColumn<NamedProperty, String> nameCol = new TableColumn("Name"); nameCol.setCellValueFactory(new PropertyValueFactory<NamedProperty, String>( "name")); TableColumn<NamedProperty, Object> valueCol = new TableColumn("Value"); valueCol.setCellValueFactory(new PropertyValueFactory<NamedProperty, Object>( "value")); valueCol.setCellFactory(new Callback<TableColumn<NamedProperty, Object>, TableCell<NamedProperty, Object>>() { @Override public TableCell<NamedProperty, Object> call( TableColumn<NamedProperty, Object> param) { return new EditingCell(); } }); //提交后更新pojo的值 valueCol.setOnEditCommit(new EventHandler<CellEditEvent<NamedProperty, Object>>() { @Override public void handle(CellEditEvent<NamedProperty, Object> t) { int row = t.getTablePosition().getRow(); NamedProperty property = (NamedProperty) t.getTableView() .getItems().get(row); property.setValue(t.getNewValue()); currentObjectValue.setText(aPerson.toString()); } }); table.getColumns().setAll(nameCol, valueCol); table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY); VBox layout = new VBox(10); layout.setStyle("-fx-background-color: cornsilk; -fx-padding: 10;"); layout.getChildren().setAll(currentObjectValue, table); VBox.setVgrow(table, Priority.ALWAYS); stage.setScene(new Scene(layout, 650, 600)); stage.show(); } private ObservableList<NamedProperty> createNamedProperties(Object object) { ObservableList<NamedProperty> properties = FXCollections .observableArrayList(); for (Method method : object.getClass().getMethods()) { String name = method.getName(); Class type = method.getReturnType(); if (type.getName().endsWith("Property")) { try { properties.add(new NamedProperty(name, (Property) method .invoke(object))); } catch (IllegalAccessException ex) { Logger.getLogger(TableViewPropertyEditor.class.getName()) .log(Level.SEVERE, null, ex); } catch (InvocationTargetException ex) { Logger.getLogger(TableViewPropertyEditor.class.getName()) .log(Level.SEVERE, null, ex); } catch (IllegalArgumentException ex) { Logger.getLogger(TableViewPropertyEditor.class.getName()) .log(Level.SEVERE, null, ex); } } } return properties; } public class NamedProperty { public NamedProperty(String name, Property value) { nameProperty.set(name); valueProperty = value; } private StringProperty nameProperty = new SimpleStringProperty(); public StringProperty nameProperty() { return nameProperty; } public StringProperty getName() { return nameProperty; } public void setName(String name) { nameProperty.set(name); } private Property valueProperty; public Property valueProperty() { return valueProperty; } public Object getValue() { return valueProperty.getValue(); } public void setValue(Object value) { valueProperty.setValue(value); } } public class Person { private final SimpleStringProperty firstName; private final SimpleBooleanProperty married; private Person(String firstName, Boolean isMarried) { this.firstName = new SimpleStringProperty(firstName); this.married = new SimpleBooleanProperty(isMarried); } public SimpleStringProperty firstNameProperty() { return firstName; } public SimpleBooleanProperty marriedProperty() { return married; } public String getFirstName() { return firstName.get(); } public void setFirstName(String fName) { firstName.set(fName); } public Boolean getMarried() { return married.get(); } public void setMarried(Boolean isMarried) { married.set(isMarried); } @Override public String toString() { return firstName.getValue() + ": " + married.getValue(); } } class EditingCell extends TableCell<NamedProperty, Object> { private TextField textField; private CheckBox checkBox; public EditingCell() { } @Override public void startEdit() { //开始编辑时,设置Graphic if (!isEmpty()) { super.startEdit(); if (getItem() instanceof Boolean) { createCheckBox(); setText(null); setGraphic(checkBox); } else { createTextField(); setText(null); setGraphic(textField); textField.selectAll(); } } } @Override public void cancelEdit() { //结束编辑时,取消Graphic,设置text super.cancelEdit(); System.out.println("cancel"); if (getItem() instanceof Boolean) { setText(getItem().toString()); } else { setText((String) getItem()); } setGraphic(null); } @Override public void updateItem(Object item, boolean empty) { super.updateItem(item, empty); if (getIndex() < 2) { NamedProperty property = getTableView().getItems().get( getIndex()); System.out.println("property=" + property.getValue()); System.out.println("item=" + getItem()); } if (empty) { setText(null); setGraphic(null); } else { if (isEditing()) { if (getItem() instanceof Boolean) { //为boolean就设置checkbox if (checkBox != null) { checkBox.setSelected(getBoolean()); } setText(null); setGraphic(checkBox); } else { //设置textFiled if (textField != null) { textField.setText(getString()); } setText(null); setGraphic(textField); } } else { setText(getString()); setGraphic(null); } } } private void createTextField() { textField = new TextField(getString()); textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); textField.focusedProperty().addListener(//焦点失去时事件 new ChangeListener<Boolean>() { @Override public void changed( ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if (!newValue) { commitEdit(textField.getText()); //传递值 } } }); } private void createCheckBox() { checkBox = new CheckBox(); checkBox.setSelected(getBoolean()); checkBox.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); checkBox.focusedProperty().addListener( new ChangeListener<Boolean>() { @Override public void changed( ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) { if (!newValue) { commitEdit(checkBox.isSelected()); } } }); } private String getString() { return getItem() == null ? "" : getItem().toString(); } private Boolean getBoolean() { return getItem() == null ? false : (Boolean) getItem(); } } }
一般使用自定义tableCell实现cell的多样化,重写updateItem,设置Graphic和Text内容。若要实现编辑功能则可以重写startEdit和cancelEdit方法,这样就有在需要编辑时,显示需要的node,取消时,只显示text。
需要注意的地方是需要实现column.setOnEditCommit方法,更新pojo的值。因为cell的值对应pojo里面的get的值,若你不更新pojo,则cell值不变。
举个例子:value column的cell即对应NamedProperty的getValue。在方法updateItem里面参数item和getItem()方法获取的对象均等于getValue()。
但是当我注释掉setOnEditCommit方法里面的property.setValue(t.getNewValue()); 然后编辑value值,按逻辑来说getValue()没变,页面显示的值应该不会变化, 但是结果却变了。我在updateItem方法里面输出item和NamedProperty的getValue,发现不一样了。这让我疑惑了。我在想不应该啊,这二个值应该一样的。我试着重新加载,也就是把窗口缩小,直到看不到那行记录,然后在拉大(table会重新加载)。再一输出,页面显示的值变回来了,二个打印一样了。Item和getItem()的值始终是来自pojo的get方法的。
在代码里面可以看到,通过监听checkBox和textField的焦点集中属性来传递修改后的值。
commitEdit(textField.getText()); //传递值
正是通过commitEdit方法,修改了item的值。然后在cancel里面获取item的值,此时是最新的(在这里发现为什么item和get方法的值不一样了)。其实也不需要这样做,直接在cancel里面textField.getText或checkBox.isSelected获取最新值。
理解不对的地方希望大家评论下
这里有个javafx学习的中文网站,我把内容都丢那上面去了。
http://www.jfxee.com/
下一篇: mysql中模糊查询的四种用法介绍