Java 在一行中最后一个可编辑单元之后,在TreeTableView中的下一行添加选项卡
我正在使用Java中的JavaFXTreeTableView。我的大多数单元格都是可编辑的,但有些单元格不可编辑。编辑单元格时,按tab键会跳转到下一个可编辑的单元格(如预期),但当位于行的末尾时,它只会退出编辑。是否有方法更改此行为,以便选择下一行及其第一个可编辑单元格 添加新列时的自定义工厂:Java 在一行中最后一个可编辑单元之后,在TreeTableView中的下一行添加选项卡,java,javafx,javafx-2,javafx-8,treetableview,Java,Javafx,Javafx 2,Javafx 8,Treetableview,我正在使用Java中的JavaFXTreeTableView。我的大多数单元格都是可编辑的,但有些单元格不可编辑。编辑单元格时,按tab键会跳转到下一个可编辑的单元格(如预期),但当位于行的末尾时,它只会退出编辑。是否有方法更改此行为,以便选择下一行及其第一个可编辑单元格 添加新列时的自定义工厂: /** * Create a column. The column is also added to the billing table. * * @param columnName *
/**
* Create a column. The column is also added to the billing table.
*
* @param columnName
* Name of the column.
* @return Created column.
*/
public TreeTableColumn<BillingTableRow, Double> addColumn(String columnName) {
TreeTableColumn<BillingTableRow, Double> column = new TreeTableColumn<>(columnName);
// Bind column data
column.setCellValueFactory(new Callback<TreeTableColumn.CellDataFeatures<BillingTableRow, Double>, ObservableValue<Double>>() {
@Override
public ObservableValue<Double> call(CellDataFeatures<BillingTableRow, Double> param) {
return new ObservableValueBase<Double>() {
@Override
public Double getValue() {
if (param.getValue().getValue().getType() == BillingTableRow.TYPE_SERVICE) {
if (param.getValue().getValue().getService().getAll().containsKey(columnName)) {
return param.getValue().getValue().getService().getAll().get(columnName).getTime();
}
}
return null;
}
};
}
});
// Cell editing
column.setCellFactory(new Callback<TreeTableColumn<BillingTableRow, Double>, TreeTableCell<BillingTableRow, Double>>() {
@Override
public TreeTableCell<BillingTableRow, Double> call(TreeTableColumn<BillingTableRow, Double> p) {
return new EditableTreeTableDoubleCell() {
@Override
public void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
BillingTableRow row = getTreeTableRow().getItem();
if (!empty && row != null) {
// Styling
if (row.getType() == BillingTableRow.TYPE_CLIENT) {
setStyle("-fx-font-weight: bold;");
} else {
setStyle("");
}
// Update total values
BillingTableRow parentRow = (BillingTableRow) getTreeTableRow().getTreeItem().getParent().getValue();
parentRow.updateTotal();
row.getTable().getRoot().getValue().updateTotal();
} else {
// Clear cell if it's empty
setText(null);
setGraphic(null);
}
// if (empty) {
// setEditable(false);
// }
}
};
}
});
// Edit event handler
column.setOnEditCommit(new EventHandler<TreeTableColumn.CellEditEvent<BillingTableRow, Double>>() {
@Override
public void handle(CellEditEvent<BillingTableRow, Double> t) {
BillingTableRow row = t.getTreeTablePosition().getTreeItem().getValue();
if (t.getNewValue() != null) {
if (row.getType() == BillingTableRow.TYPE_SERVICE && row.getService().getAll().containsKey(columnName)) {
row.getService().getAll().get(columnName).setTime(t.getNewValue());
}
}
if (row.getChildren().size() > 0) {
if (t.getTreeTablePosition().getTreeItem().getParent().getParent() != null)
t.getTreeTablePosition().getTreeItem().getParent().getParent().getValue().updateTotal();
}
}
});
table.getColumns().add(column);
return column;
}
/**
*创建一列。该列也将添加到计费表中。
*
*@param columnName
*列的名称。
*@return创建了一个列。
*/
public TreeTableColumn addColumn(字符串columnName){
TreeTableColumn=新的TreeTableColumn(columnName);
//绑定列数据
column.setCellValueFactory(新回调(){
@凌驾
公共observeValue调用(CellDataFeatures参数){
返回新的observeValueBase(){
@凌驾
公共双getValue(){
if(param.getValue().getValue().getType()==BillingTableRow.TYPE\u服务){
if(param.getValue().getValue().getService().getAll().containsKey(columnName)){
返回param.getValue().getValue().getService().getAll().get(columnName.getTime());
}
}
返回null;
}
};
}
});
//单元编辑
column.setCellFactory(新回调(){
@凌驾
公共TreeTableCell调用(TreeTableP列){
返回新的EditableTreeTableDoubleCell(){
@凌驾
public void updateItem(双项,布尔空){
super.updateItem(项,空);
BillingTableRow行=getTreeTableRow().getItem();
如果(!empty&&row!=null){
//造型
if(row.getType()==BillingTableRow.TYPE\u客户端){
setStyle(“-fx字体大小:粗体;”);
}否则{
设置样式(“”);
}
//更新总值
BillingTableRow parentRow=(BillingTableRow)getTreeTableRow().getTreeItem().getParent().getValue();
parentRow.updateTotal();
row.getTable().getRoot().getValue().updateTotal();
}否则{
//如果是空的,请清除单元格
setText(空);
设置图形(空);
}
//if(空){
//可编辑设置(假);
// }
}
};
}
});
//编辑事件处理程序
column.setOnEditCommit(新的EventHandler(){
@凌驾
公共无效句柄(CellEditEvent t){
BillingTableRow行=t.getTreeTablePosition().getTreeItem().getValue();
如果(t.getNewValue()!=null){
if(row.getType()==BillingTableRow.TYPE_服务和row.getService().getAll().containsKey(columnName)){
row.getService().getAll().get(columnName).setTime(t.getNewValue());
}
}
if(row.getChildren().size()>0){
if(t.getTreeTablePosition().getTreeItem().getParent().getParent()!=null)
t、 getTreeTablePosition().getTreeItem().getParent().getParent().getValue().updateTotal();
}
}
});
table.getColumns().add(列);
返回列;
}
自定义单元格:
package gui;
import java.util.ArrayList;
import java.util.List;
import javafx.application.Platform;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.EventHandler;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TextField;
import javafx.scene.control.TreeTableCell;
import javafx.scene.control.TreeTableColumn;
import javafx.scene.input.KeyCode;
import javafx.scene.input.KeyEvent;
/**
* Editable TreeTableCell of type double.
*
* @author Peter Jonsson, Graham Smith
*
*/
public class EditableTreeTableDoubleCell extends TreeTableCell<BillingTableRow, Double> {
private TextField textField;
public EditableTreeTableDoubleCell() {
}
@Override
public void startEdit() {
super.startEdit();
if (textField == null) {
if (isEditable()) {
createTextField();
} else {
return;
}
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
Platform.runLater(new Runnable() {
@Override
public void run() {
textField.requestFocus();
textField.selectAll();
}
});
}
@Override
public void cancelEdit() {
super.cancelEdit();
if (getItem() != null) {
setText(Double.toString(getItem()));
}
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
@Override
public void updateItem(Double item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
if (textField != null) {
textField.setText(getString());
}
setGraphic(textField);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
} else {
setText(getString());
setContentDisplay(ContentDisplay.TEXT_ONLY);
}
}
// Cell locking
if (item == null) {
setEditable(false);
} else {
setEditable(true);
}
}
private void createTextField() {
textField = new TextField(getString());
if (textField.getText().isEmpty()) {
textField.setText("0");
}
textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2);
textField.setOnKeyPressed(new EventHandler<KeyEvent>() {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public void handle(KeyEvent t) {
if (t.getCode() == KeyCode.ENTER) {
commitEdit(Double.parseDouble(sanitizeInput(textField.getText())));
} else if (t.getCode() == KeyCode.ESCAPE) {
cancelEdit();
} else if (t.getCode() == KeyCode.TAB) {
commitEdit(Double.parseDouble(sanitizeInput(textField.getText())));
TreeTableColumn nextColumn = getNextColumn(!t.isShiftDown());
if (nextColumn != null) {
getTreeTableView().edit(getTreeTableRow().getIndex(), nextColumn);
}
}
}
});
textField.focusedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (!newValue && textField != null) {
commitEdit(Double.parseDouble(sanitizeInput(textField.getText())));
}
}
});
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
/**
*
* @param forward
* true gets the column to the right, false the column to the
* left of the current column
* @return next column
*/
private TreeTableColumn<BillingTableRow, ?> getNextColumn(boolean forward) {
List<TreeTableColumn<BillingTableRow, ?>> columns = new ArrayList<>();
for (TreeTableColumn<BillingTableRow, ?> column : getTreeTableView().getColumns()) {
columns.addAll(getLeaves(column));
}
// There is no other column that supports editing.
if (columns.size() < 2) {
return null;
}
int currentIndex = columns.indexOf(getTableColumn());
int nextIndex = currentIndex;
if (forward) {
nextIndex++;
if (nextIndex > columns.size() - 1) {
nextIndex = 0;
}
} else {
nextIndex--;
if (nextIndex < 0) {
nextIndex = columns.size() - 1;
}
}
return columns.get(nextIndex);
}
private List<TreeTableColumn<BillingTableRow, ?>> getLeaves(TreeTableColumn<BillingTableRow, ?> root) {
List<TreeTableColumn<BillingTableRow, ?>> columns = new ArrayList<>();
if (root.getColumns().isEmpty()) {
// We only want the leaves that are editable.
if (root.isEditable()) {
columns.add(root);
}
return columns;
} else {
for (TreeTableColumn<BillingTableRow, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
/**
* Sanitize an inputted string.
*
* @param string
* String to sanitize.
* @return Sanitized string.
*/
private String sanitizeInput(String string) {
if (string != null && !string.isEmpty()) {
return string;
}
return "0";
}
}
packagegui;
导入java.util.ArrayList;
导入java.util.List;
导入javafx.application.Platform;
导入javafx.beans.value.ChangeListener;
导入javafx.beans.value.observeValue;
导入javafx.event.EventHandler;
导入javafx.scene.control.ContentDisplay;
导入javafx.scene.control.TextField;
导入javafx.scene.control.TreeTableCell;
导入javafx.scene.control.TreeTableColumn;
导入javafx.scene.input.KeyCode;
导入javafx.scene.input.KeyEvent;
/**
*类型为double的可编辑TreeTableCell。
*
*@作者彼得·琼森,格雷厄姆·史密斯
*
*/
公共类EditableTreeTableDoubleCell扩展了TreeTableCell{
私有文本字段文本字段;
public EditableTreeTableDoubleCell(){
}
@凌驾
公开作废已启动IT(){
super.startEdit();
if(textField==null){
如果(isEditable()){
createTextField();
}否则{
返回;
}
}
设置图形(文本字段);
setContentDisplay(仅限ContentDisplay.GRAPHIC_);
Platform.runLater(新的Runnable(){
@凌驾
公开募捐{
textField.requestFocus();
textField.selectAll();
}
});
}
@凌驾
公共作废取消编辑(){
super.cancelEdit();
如果(getItem()!=null){
setText(Double.toString(getItem());
}
setContentDisplay(仅限ContentDisplay.TEXT_);
}
@凌驾
public void updateItem(双项,布尔空){
super.updateItem(项,空);
if(空){
setText(空);
设置图形(空);
}否则{
if(isEditing()){
if(textField!=null){
setText(getString());
}
设置图形(文本字段);
setContentDisplay(仅限ContentDisplay.GRAPHIC_);
}否则{
setText(getString());
setContentDisplay(仅限ContentDisplay.TEXT_);
}
}
//细胞锁定
如果(项==null){
可编辑设置(假);
}否则{
可编辑设置(真);
}
}
私有void createTextField(){
textField=newtextfield(getString());