下面列出了怎么用javafx.scene.control.TreeTableColumn的API类实例代码及写法,或者点击链接到github查看源代码。
/**
* @return the elements corresponding to the active cell
*/
public List<E> getSelectedElements() {
ObservableList<TreeTablePosition<EditableTreeTableLineItem<Wrapper<E>>, ?>> selectedcells = treetableview
.getSelectionModel().getSelectedCells();
if (selectedcells.size() == 1) {
TreeTablePosition<EditableTreeTableLineItem<Wrapper<E>>, ?> selectedposition = selectedcells.get(0);
TreeTableColumn<EditableTreeTableLineItem<Wrapper<E>>, ?> tablecolumn = selectedposition.getTableColumn();
if (tablecolumn instanceof EditableTreeTableValueColumn) {
@SuppressWarnings({ "unchecked", "rawtypes" })
EditableTreeTableValueColumn<E, ?, ?> tablecolumnparsed = (EditableTreeTableValueColumn) tablecolumn;
TreeItem<EditableTreeTableLineItem<Wrapper<E>>> treeitem = selectedposition.getTreeItem();
EditableTreeTableLineItem<Wrapper<E>> rowdata = treeitem.getValue();
ArrayList<Wrapper<E>> filteredvalues = tablecolumnparsed.columngrouping.filterItems(rowdata,
tablecolumnparsed.titlekey);
ArrayList<E> returnedvalues = new ArrayList<E>();
for (int i = 0; i < filteredvalues.size(); i++) {
returnedvalues.add(filteredvalues.get(i).getPayload());
}
return returnedvalues;
}
}
return new ArrayList<E>();
}
/**
* generates the root column showing label of line elements
*/
private void generateRootColumn() {
TreeTableColumn<
EditableTreeTableLineItem<Wrapper<E>>,
String> rootcolumn = new TreeTableColumn<EditableTreeTableLineItem<Wrapper<E>>, String>("Item");
rootcolumn.setCellValueFactory(new Callback<
CellDataFeatures<EditableTreeTableLineItem<Wrapper<E>>, String>, ObservableValue<String>>() {
@Override
public ObservableValue<String> call(CellDataFeatures<EditableTreeTableLineItem<Wrapper<E>>, String> param) {
return new SimpleStringProperty(param.getValue().getValue().getLabel());
}
});
treetableview.getColumns().add(rootcolumn);
}
@Override
@Nonnull
public List<TreeTableColumn<ModularFeatureListRow, Object>> createSubColumns(
@Nullable RawDataFile raw) {
List<TreeTableColumn<ModularFeatureListRow, Object>> cols = new ArrayList<>();
// create column per name
TreeTableColumn<ModularFeatureListRow, Object> min = new TreeTableColumn<>("min");
DataTypeCellValueFactory cvFactoryMin = new DataTypeCellValueFactory(raw, this);
min.setCellValueFactory(cvFactoryMin);
min.setCellFactory(new DataTypeCellFactory(raw, this, 0));
TreeTableColumn<ModularFeatureListRow, Object> max = new TreeTableColumn<>("max");
DataTypeCellValueFactory cvFactoryMax = new DataTypeCellValueFactory(raw, this);
max.setCellValueFactory(cvFactoryMax);
max.setCellFactory(new DataTypeCellFactory(raw, this, 1));
// add all
cols.add(min);
cols.add(max);
return cols;
}
public void resizeColumns() {
try {
Method method = getClass().getClassLoader()
.loadClass("javafx.scene.control.skin.TableSkinUtils")
.getMethod("resizeColumnToFitContent", TableViewSkinBase.class, TableColumnBase.class, int.class);
method.setAccessible(true);
for (TreeTableColumn<R, ?> column : this.getColumns()) {
method.invoke(null, getSkin(), column, -1);
}
} catch (Throwable t) {
//for some reason, a NPE will be thrown now and then, some racing condition?
log.warn("Failed to resize columns");
}
// TableSkinUtils.resizeColumnToFitContent((TableViewSkinBase<?, ?, ?, ?, ?>) getSkin(), getTreeColumn(), -1);
// ((ResizableJfxTreeTableViewSkin<R>)getSkin()).resizeAllColumns();
}
@Override
public TreeTableCell<T, Long> call(TreeTableColumn<T, Long> param) {
TreeTableCell<T, Long> cell = new TreeTableCell<T, Long>() {
private final Text text = new Text();
@Override
protected void updateItem(final Long item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null || (long) item <= 0) {
setText(null);
setGraphic(null);
return;
}
text.setText(FileTools.showFileSize((long) item));
setGraphic(text);
}
};
return cell;
}
@SuppressWarnings("unchecked")
@Test
public void selectMultipleCells() {
TreeTableView<?> treeTableView = (TreeTableView<?>) getPrimaryStage().getScene().getRoot().lookup(".tree-table-view");
LoggingRecorder lr = new LoggingRecorder();
Platform.runLater(() -> {
TreeTableViewSelectionModel<?> selectionModel = treeTableView.getSelectionModel();
selectionModel.setCellSelectionEnabled(true);
selectionModel.setSelectionMode(SelectionMode.MULTIPLE);
Point2D point = getPoint(treeTableView, 1, 0);
RFXTreeTableView rfxTreeTableView = new RFXTreeTableView(treeTableView, null, point, lr);
rfxTreeTableView.focusGained(null);
@SuppressWarnings("rawtypes")
TreeTableColumn column = getTreeTableColumnAt(treeTableView, 0);
selectionModel.select(1, column);
selectionModel.select(3, getTreeTableColumnAt(treeTableView, 1));
rfxTreeTableView.focusLost(null);
});
List<Recording> recordings = lr.waitAndGetRecordings(1);
Recording recording = recordings.get(0);
AssertJUnit.assertEquals("recordSelect", recording.getCall());
AssertJUnit.assertEquals(
"{\"cells\":[[\"/Sales Department/Ethan Williams\",\"Employee\"],[\"/Sales Department/Michael Brown\",\"Email\"]]}",
recording.getParameters()[0]);
}
@SuppressWarnings("unchecked")
@Test
public void selectACell() {
TreeTableView<?> treeTableView = (TreeTableView<?>) getPrimaryStage().getScene().getRoot().lookup(".tree-table-view");
LoggingRecorder lr = new LoggingRecorder();
Platform.runLater(() -> {
TreeTableViewSelectionModel<?> selectionModel = treeTableView.getSelectionModel();
selectionModel.setCellSelectionEnabled(true);
Point2D point = getPoint(treeTableView, 1, 0);
RFXTreeTableView rfxTreeTableView = new RFXTreeTableView(treeTableView, null, point, lr);
rfxTreeTableView.focusGained(null);
@SuppressWarnings("rawtypes")
TreeTableColumn column = getTreeTableColumnAt(treeTableView, 0);
selectionModel.select(1, column);
rfxTreeTableView.focusLost(null);
});
List<Recording> recordings = lr.waitAndGetRecordings(1);
Recording recording = recordings.get(0);
AssertJUnit.assertEquals("recordSelect", recording.getCall());
AssertJUnit.assertEquals("{\"cells\":[[\"/Sales Department/Ethan Williams\",\"Employee\"]]}", recording.getParameters()[0]);
}
/**
* Update the table column titles, by putting an asterisk to non saved snapshots or remove asterisk from saved
* snapshots.
*/
private void updateTableColumnTitles() {
// add the * to the title of the column if the snapshot is not saved
if (uiSnapshots.size() == 1) {
((TooltipTreeTableColumn<?>) getColumns().get(6)).setSaved(true); //uiSnapshots.get(0).isSaved());
} else {
TreeTableColumn<TreeTableEntry, ?> column = getColumns().get(4);
for (int i = 0; i < uiSnapshots.size(); i++) {
TreeTableColumn tableColumn = column.getColumns().get(i);
if(tableColumn instanceof DividerTreeTableColumn){
continue;
}
((TooltipTreeTableColumn<?>) tableColumn).setSaved(true); //uiSnapshots.get(i).isSaved());
}
}
}
@Override
public TreeTableCell<FeatureTableRow, Object> call(TreeTableColumn<FeatureTableRow, Object> p) {
return new TreeTableCell<FeatureTableRow, Object>() {
@Override
public void updateItem(Object object, boolean empty) {
super.updateItem(object, empty);
setStyle("-fx-alignment: CENTER;"
+ "-fx-border-color: transparent -fx-table-cell-border-color -fx-table-cell-border-color transparent;");
if (object == null) {
setText(null);
} else {
NumberFormat formatter = MZmineCore.getConfiguration().getMZFormat();
Double doubleValue = Double.parseDouble(object.toString());
setText(formatter.format(doubleValue));
}
}
};
}
@Override
public TreeTableCell<FeatureTableRow, Object> call(TreeTableColumn<FeatureTableRow, Object> p) {
return new TreeTableCell<FeatureTableRow, Object>() {
@Override
public void updateItem(Object object, boolean empty) {
super.updateItem(object, empty);
setStyle("-fx-alignment: CENTER;"
+ "-fx-border-color: transparent -fx-table-cell-border-color -fx-table-cell-border-color transparent;");
if (object == null) {
setText(null);
} else {
try {
NumberFormat formatter = new DecimalFormat("#0.00");
Double doubleValue = Double.parseDouble(object.toString());
setText(formatter.format(doubleValue));
} catch (NumberFormatException e) {
setText(object.toString());
}
}
}
};
}
@Override
public TreeTableCell<FeatureTableRow, Object> call(TreeTableColumn<FeatureTableRow, Object> p) {
return new TreeTableCell<FeatureTableRow, Object>() {
@Override
public void updateItem(Object object, boolean empty) {
super.updateItem(object, empty);
setStyle("-fx-alignment: CENTER;"
+ "-fx-border-color: transparent -fx-table-cell-border-color -fx-table-cell-border-color transparent;");
if (object == null) {
setText(null);
} else {
Integer integerValue = Integer.parseInt(object.toString());
setText(integerValue.toString());
}
}
};
}
@Override
public TreeTableCell<FeatureTableRow, Object> call(TreeTableColumn<FeatureTableRow, Object> p) {
return new TreeTableCell<FeatureTableRow, Object>() {
@Override
public void updateItem(Object object, boolean empty) {
super.updateItem(object, empty);
setStyle("-fx-alignment: CENTER;"
+ "-fx-border-color: transparent -fx-table-cell-border-color -fx-table-cell-border-color transparent;");
if (object == null) {
setText(null);
} else {
Range rangeValue = (Range) object;
NumberFormat formatter = MZmineCore.getConfiguration().getMZFormat();
String value = formatter.format(rangeValue.lowerEndpoint()) + " - "
+ formatter.format(rangeValue.upperEndpoint());
setText(value);
}
}
};
}
@Override
public TreeTableCell<FeatureTableRow, Object> call(TreeTableColumn<FeatureTableRow, Object> p) {
return new TreeTableCell<FeatureTableRow, Object>() {
@Override
public void updateItem(Object object, boolean empty) {
super.updateItem(object, empty);
setStyle("-fx-alignment: CENTER;"
+ "-fx-border-color: transparent -fx-table-cell-border-color -fx-table-cell-border-color transparent;");
if (object == null) {
setText(null);
} else {
Double doubleValue = Double.parseDouble(object.toString());
NumberFormat formatter = MZmineCore.getConfiguration().getIntensityFormat();
setText(formatter.format(doubleValue));
}
}
};
}
@Override
public TreeTableCell<FeatureTableRow, Object> call(TreeTableColumn<FeatureTableRow, Object> p) {
return new TreeTableCell<FeatureTableRow, Object>() {
@Override
public void updateItem(Object object, boolean empty) {
super.updateItem(object, empty);
setStyle("-fx-alignment: CENTER;"
+ "-fx-border-color: transparent -fx-table-cell-border-color -fx-table-cell-border-color transparent;");
if (object == null) {
setText(null);
} else {
NumberFormat formatter = MZmineCore.getConfiguration().getRTFormat();
Float floatValue = Float.parseFloat(object.toString());
setText(formatter.format(floatValue));
}
}
};
}
@Override
public TreeTableCell<FeatureTableRow, Object> call(TreeTableColumn<FeatureTableRow, Object> p) {
return new TreeTableCell<FeatureTableRow, Object>() {
@Override
public void updateItem(Object object, boolean empty) {
super.updateItem(object, empty);
setStyle("-fx-alignment: CENTER;"
+ "-fx-border-color: transparent -fx-table-cell-border-color -fx-table-cell-border-color transparent;");
if (object == null) {
setText(null);
} else {
// Default format to two decimals
NumberFormat formatter = new DecimalFormat("#0.00");
Double doubleValue = Double.parseDouble(object.toString());
setText(formatter.format(doubleValue));
}
}
};
}
@Override
public TreeTableColumn<ObjectDataElt, Integer> getTreeTableColumn(
PageActionManager pageactionmanager,
String actionkeyforupdate) {
TreeTableColumn<
ObjectDataElt, Integer> thiscolumn = new TreeTableColumn<ObjectDataElt, Integer>(this.getLabel());
if (actionkeyforupdate != null)
thiscolumn.setEditable(true);
int length = 110;
thiscolumn.setMinWidth(length);
CIntegerField thisdecimalfield = this;
thiscolumn.setCellValueFactory(
new Callback<TreeTableColumn.CellDataFeatures<ObjectDataElt, Integer>, ObservableValue<Integer>>() {
@Override
public ObservableValue<Integer> call(
javafx.scene.control.TreeTableColumn.CellDataFeatures<ObjectDataElt, Integer> p) {
ObjectDataElt line = p.getValue().getValue();
String fieldname = thisdecimalfield.getFieldname();
if (line == null)
return new SimpleObjectProperty<Integer>(null);
SimpleDataElt lineelement = line.lookupEltByName(fieldname);
if (lineelement == null)
return new SimpleObjectProperty<Integer>(null);
if (!(lineelement instanceof IntegerDataElt))
return new SimpleObjectProperty<Integer>(null);
IntegerDataElt linedataelt = (IntegerDataElt) lineelement;
return new SimpleObjectProperty<Integer>(linedataelt.getPayload());
}
});
return thiscolumn;
}
/**
* generates a listener to manage
* <ul>
* <li>on key pressed, edition starts</li>
* <li>delete removes content from the cell</li>
* </ul>
*/
private void generateEditionListener() {
treetableview.setOnKeyPressed(new EventHandler<KeyEvent>() {
@Override
public void handle(KeyEvent event) {
KeyCode keyCode = event.getCode();
logger.finest(" > Key event on table " + keyCode);
TreeTablePosition<
EditableTreeTableLineItem<Wrapper<E>>,
?> focusedcell = treetableview.getFocusModel().getFocusedCell();
if (treetableview.getEditingCell() != null) {
logger.finest(" >>Discard event as editing cell active");
} else {
if (keyCode == KeyCode.DELETE || keyCode == KeyCode.BACK_SPACE) {
logger.finest(" > Delete detected ");
TreeTableColumn<EditableTreeTableLineItem<Wrapper<E>>, ?> column = focusedcell.getTableColumn();
if (column instanceof EditableTreeTableValueColumn) {
@SuppressWarnings("unchecked")
EditableTreeTableValueColumn<
E, ?, ?> parsedcolumn = (EditableTreeTableValueColumn<E, ?, ?>) column;
TreeItem<EditableTreeTableLineItem<Wrapper<E>>> treeitem = focusedcell.getTreeItem();
parsedcolumn.clear(treeitem.getValue());
}
}
if (keyCode.isLetterKey() || keyCode.isDigitKey() || keyCode == KeyCode.DECIMAL
|| keyCode == KeyCode.SPACE) {
logger.finest(" > Detected real content");
treetableview.edit(focusedcell.getRow(), focusedcell.getTableColumn());
}
}
}
});
}
/**
* Add a new column to the table
*
* @param dataType
*/
public void addColumn(DataType dataType) {
// value binding
TreeTableColumn<ModularFeatureListRow, ? extends DataType> col = dataType.createColumn(null);
// add to table
if (col != null) {
this.getColumns().add(col);
columnMap.put(new ColumnID(dataType, ColumnType.ROW_TYPE, null), col);
rowTypesParameter.isDataTypeVisible(dataType);
// is feature type?
if (dataType.getClass().equals(FeaturesType.class)) {
// add feature columns for each raw file
for (RawDataFile raw : flist.getRawDataFiles()) {
// create column per name
TreeTableColumn<ModularFeatureListRow, String> sampleCol =
new TreeTableColumn<>(raw.getName());
// TODO get RawDataFile -> Color and set column header
// sampleCol.setStyle("-fx-background-color: #"+ColorsFX.getHexString(color));
// add sub columns of feature
for (DataType ftype : flist.getFeatureTypes().values()) {
TreeTableColumn<ModularFeatureListRow, ?> subCol = ftype.createColumn(raw);
if (subCol != null) {
sampleCol.getColumns().add(subCol);
columnMap.put(new ColumnID(ftype, ColumnType.FEATURE_TYPE, raw), subCol);
featureTypesParameter.isDataTypeVisible(ftype);
}
}
// add all
col.getColumns().add(sampleCol);
}
}
}
applyColumnVisibility();
}
@Nullable
private TreeTableColumn getColumn(ColumnID id) {
if (!columnMap.containsKey(id)) {
logger.info(id.getFormattedString());
}
return columnMap.get(id);
}
@Override
public Node getCellNode(TreeTableCell<ModularFeatureListRow, FeatureStatus> cell,
TreeTableColumn<ModularFeatureListRow, FeatureStatus> coll, FeatureStatus cellData,
RawDataFile raw) {
if (cellData == null)
return null;
Circle circle = new Circle();
circle.setRadius(10);
circle.setFill(cellData.getColorFX());
return circle;
}
@Override
public TreeTableCell<ModularFeatureListRow, Object> call(
TreeTableColumn<ModularFeatureListRow, Object> param) {
TextFieldTreeTableCell<ModularFeatureListRow, Object> cell = new TextFieldTreeTableCell<>();
if (type instanceof StringParser) {
cell.setConverter(((StringParser) type).getStringConverter());
cell.setAlignment(Pos.CENTER);
return cell;
} else {
logger.log(Level.SEVERE,
"Class in editable CellFactory is no StringParser: " + type.getClass().toString());
return null;
}
}
@Override
@Nonnull
public List<TreeTableColumn<ModularFeatureListRow, Object>> createSubColumns(
final @Nullable RawDataFile raw) {
List<TreeTableColumn<ModularFeatureListRow, Object>> cols = new ArrayList<>();
// create bar chart
TreeTableColumn<ModularFeatureListRow, Object> barsCol = new TreeTableColumn<>("Area Bars");
barsCol.setCellValueFactory(new DataTypeCellValueFactory(null, this));
barsCol.setCellFactory(new DataTypeCellFactory(null, this, cols.size()));
cols.add(barsCol);
TreeTableColumn<ModularFeatureListRow, Object> sharesCol = new TreeTableColumn<>("Area Share");
sharesCol.setCellValueFactory(new DataTypeCellValueFactory(null, this));
sharesCol.setCellFactory(new DataTypeCellFactory(null, this, cols.size()));
cols.add(sharesCol);
TreeTableColumn<ModularFeatureListRow, Object> shapes = new TreeTableColumn<>("Shapes");
shapes.setCellValueFactory(new DataTypeCellValueFactory(null, this));
shapes.setCellFactory(new DataTypeCellFactory(null, this, cols.size()));
cols.add(shapes);
/*
* sample columns are created in the FeatureListFX class
*/
return cols;
}
/**
* this is a blocking method so it should not be called from the ui thread,
* it will regroup the tree table view
*
* @param treeTableColumns
*/
public void group(TreeTableColumn<S, ?>... treeTableColumns) {
try {
lock.lock();
// init groups map
if (groupOrder.size() == 0) {
groups = new HashMap<>();
}
try {
if (originalRoot == null) {
originalRoot = getRoot();
}
List<TreeTableColumn<S, ?>> toBeAdded = new ArrayList<>();
for (TreeTableColumn<S, ?> treeTableColumn : treeTableColumns) {
if (groupOrder.contains(treeTableColumn)) {
continue;
}
toBeAdded.add(treeTableColumn);
groups = group(treeTableColumn, groups, null, (RecursiveTreeItem<S>) originalRoot);
}
groupOrder.addAll(toBeAdded);
// update table ui
buildGroupedRoot(groups, null, 0);
} catch (Exception e) {
e.printStackTrace();
}
} finally {
lock.unlock();
}
}
private void refreshGroups(List<TreeTableColumn<S, ?>> groupColumns) {
groups = new HashMap<>();
for (TreeTableColumn<S, ?> treeTableColumn : groupColumns) {
groups = group(treeTableColumn, groups, null, (RecursiveTreeItem<S>) originalRoot);
}
groupOrder.setAll(groupColumns);
// update table ui
buildGroupedRoot(groups, null, 0);
}
@Override
@Nullable
public String getFormattedSubColValue(int subcolumn,
TreeTableCell<ModularFeatureListRow, Object> cell,
TreeTableColumn<ModularFeatureListRow, Object> coll, Object value, RawDataFile raw) {
if (value == null)
return "";
switch (subcolumn) {
case 0:
return getFormatter().format(((Range) value).lowerEndpoint());
case 1:
return getFormatter().format(((Range) value).upperEndpoint());
}
return "";
}
/**
* Creates a TreeTableColumn or null if the value is not represented in a column. A
* {@link SubColumnsFactory} DataType can also add multiple sub columns to the main column
* generated by this class.
*
* @param raw null if this is a FeatureListRow column. For Feature columns: the raw data file
* specifies the feature.
*
* @return the TreeTableColumn or null if this DataType.value is not represented in a column
*/
@Nullable
public TreeTableColumn<ModularFeatureListRow, Object> createColumn(
final @Nullable RawDataFile raw) {
if (this instanceof NullColumnType)
return null;
// create column
TreeTableColumn<ModularFeatureListRow, Object> col = new TreeTableColumn<>(getHeaderString());
if (this instanceof SubColumnsFactory) {
col.setSortable(false);
// add sub columns (no value factory needed for parent column)
List<TreeTableColumn<ModularFeatureListRow, ?>> children =
((SubColumnsFactory) this).createSubColumns(raw);
col.getColumns().addAll(children);
return col;
} else {
col.setSortable(true);
// define observable
DataTypeCellValueFactory cvFactory = new DataTypeCellValueFactory(raw, this);
col.setCellValueFactory(cvFactory);
// value representation
if (this instanceof EditableColumnType) {
col.setCellFactory(new EditableDataTypeCellFactory(raw, this));
col.setEditable(true);
col.setOnEditCommit(event -> {
Object data = event.getNewValue();
if (data != null) {
if (raw == null)
event.getRowValue().getValue().set(this, data);
else
event.getRowValue().getValue().getFeatures().get(raw).set(this, data);
}
});
} else
col.setCellFactory(new DataTypeCellFactory(raw, this));
}
return col;
}
protected void addColumnNumber (String heading, int width, String propertyName)
{
TreeTableColumn<T, Number> column = new TreeTableColumn<> (heading);
column.setPrefWidth (width);
column
.setCellValueFactory (new TreeItemPropertyValueFactory<T, Number> (propertyName));
getColumns ().add (column);
column.setStyle ("-fx-alignment: CENTER-RIGHT;");
}
@SuppressWarnings("rawtypes")
public TreeTableCell getVisibleCellAt(TreeTableView<?> treeTableView, int row, int column) {
Set<Node> lookupAll = getTreeTableCells(treeTableView);
TreeTableCell cell = null;
for (Node node : lookupAll) {
TreeTableCell<?, ?> cell1 = (TreeTableCell<?, ?>) node;
TreeTableRow<?> tableRow = cell1.getTreeTableRow();
TreeTableColumn<?, ?> tableColumn = cell1.getTableColumn();
if (tableRow.getIndex() == row && tableColumn == treeTableView.getColumns().get(column)) {
cell = cell1;
break;
}
}
return cell;
}
private List<TreeTableColumn<S, ?>> getLeaves(TreeTableColumn<S, ?> root) {
List<TreeTableColumn<S, ?>> 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<S, ?> column : root.getColumns()) {
columns.addAll(getLeaves(column));
}
return columns;
}
}
protected int getTreeTableColumnIndex(TreeTableView<?> treeTableView, String columnName) {
ObservableList<?> columns = treeTableView.getColumns();
int ncolumns = columns.size();
for (int i = 0; i < ncolumns; i++) {
@SuppressWarnings("rawtypes")
String column = ((TreeTableColumn) columns.get(i)).getText();
if (columnName.equals(escapeSpecialCharacters(column))) {
return i;
}
}
throw new RuntimeException("Could not find column " + columnName + " in tree table");
}