diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings index 56b30adfc28222598e2493e05c234ae0550d6c3f..b1f544d15c699c3bc88262241d90ad71ff1cb348 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/.ratings @@ -1,8 +1,8 @@ DynamicTextFieldTreeTableCell.java de24117e6f785b328f1ff62383626a0b4b54e8ff YELLOW DynamicTreeContentProviderBase.java 6760a6dc5721175b1dada8f30fd9da05f7bcc4b3 GREEN DynamicTreeItem.java 75dc5534b119ffdb3c10a65810c2a0f330b7955e GREEN -DynamicTreeTableUIProviderBase.java f78c0f8b52fbc939166b3f94f7f6006cc0f4d32b GREEN -DynamicTreeTableViewer.java ca3984b2fc404e3b37e409ce11859bcdc61aaf66 YELLOW +DynamicTreeTableUIProviderBase.java a8545621099da2a75f2e1aa25025e35902668bde YELLOW +DynamicTreeTableViewer.java 3d91b1bd43393f5d0733a253a85436b8255526ae YELLOW DynamicTreeUIProviderBase.java e9b68607683de279d0cb8712a28dc131c5c33ece GREEN DynamicTreeViewer.java 725f41f4fb4b6bfa813f010fb9083ab02eea164a GREEN DynamicTreeViewerBase.java a2013538b62d86f6a09efdf2cd78babac2072484 GREEN diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java index f78c0f8b52fbc939166b3f94f7f6006cc0f4d32b..a8545621099da2a75f2e1aa25025e35902668bde 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableUIProviderBase.java @@ -13,24 +13,33 @@ *******************************************************************************/ package org.fortiss.tooling.common.ui.javafx.control.treetableview; +import static javafx.collections.FXCollections.observableArrayList; +import static javafx.scene.paint.Color.WHITE; import static org.apache.commons.lang3.SystemUtils.IS_OS_LINUX; +import java.util.Collection; +import java.util.function.Function; + import javafx.beans.property.SimpleBooleanProperty; import javafx.beans.value.ChangeListener; import javafx.beans.value.ObservableValue; +import javafx.collections.ObservableList; import javafx.scene.Node; +import javafx.scene.control.ComboBox; import javafx.scene.control.ContextMenu; import javafx.scene.control.TextField; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableCell; import javafx.scene.control.TreeTableColumn; import javafx.scene.control.cell.CheckBoxTreeTableCell; +import javafx.scene.control.cell.ComboBoxTreeTableCell; import javafx.scene.control.cell.TextFieldTreeTableCell; import javafx.scene.input.Dragboard; import javafx.scene.input.KeyCode; import javafx.scene.input.KeyEvent; import javafx.scene.input.MouseButton; import javafx.scene.input.MouseEvent; +import javafx.scene.paint.Color; import javafx.util.Callback; import javafx.util.converter.DefaultStringConverter; @@ -61,6 +70,42 @@ public abstract class DynamicTreeTableUIProviderBase<T> { return null; } + /** + * Sets styling properties as background color for the given cell. + * + * This method is not intended to be overwritten. Instead there are getters as + * {@link #getBackgroundColor(Object, int)}. + * + * @param cell + * The cell to be layouted. + * @param columnIndex + * The number of the column in which this cell is contained in. + */ + private final void styleCell(TreeTableCell<T, ?> cell, int columnIndex) { + if(cell.getTreeTableRow() != null) { + T data = cell.getTreeTableRow().getItem(); + + if(data != null) { + String colorStr = colorToHex(getBackgroundColor(data, columnIndex)); + cell.setStyle("-fx-background-color: " + colorStr); + } + } + } + + /** + * Determines the background color for a given element in the specified column. + * + * @param element + * The element to specify the background color for. + * @param column + * The column number to specify the background color for. + * + * @return The {@link Color} to be used for the cell background. + */ + public Color getBackgroundColor(T element, int column) { + return WHITE; + } + /** * @param element * the element to be displayed in the current row @@ -105,6 +150,19 @@ public abstract class DynamicTreeTableUIProviderBase<T> { return false; } + /** + * Returns whether the given element is editable in the given column. + * + * @param column + * The column index + * @param element + * The element to be checked + * @return Whether the column is editable + */ + public boolean isElementEditable(int column, T element) { + return isEditable(column); + } + /** * Updates the value after the given column was edited for the given element. * @@ -197,25 +255,82 @@ public abstract class DynamicTreeTableUIProviderBase<T> { return booleanProp; } }); - column.setCellFactory(createEditableCheckboxCellFactory()); + column.setCellFactory(createEditableCheckboxCellFactory(i)); + } + + /** + * Configures the given {@link TreeTableColumn} according to this UI provider. + * + * @param columnIndex + * The index number of the column to be configured. + * @param column + * The {@link TreeTableColumn} to be configured. + * @param comboValueFactory + * A {@link Function} that maps the cell elements to their respective combo values. + */ + /* package */ final void applyToComboColumn(int columnIndex, TreeTableColumn<T, String> column, + Function<T, Collection<String>> comboValueFactory) { + column.setCellFactory( + createEditableComboCellFactory(columnIndex, column, comboValueFactory)); } /** Creates a cell factory for editable cells. */ private Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>> createEditableCellFactory(int colIndex) { return param -> { - return new MyTextFieldTreeTableCell(colIndex); + MyTextFieldTreeTableCell myTextFieldTreeTableCell = + new MyTextFieldTreeTableCell(colIndex); + styleCell(myTextFieldTreeTableCell, colIndex); + return myTextFieldTreeTableCell; }; } /** Creates a cell factory for editable cells. */ private Callback<TreeTableColumn<T, Boolean>, TreeTableCell<T, Boolean>> - createEditableCheckboxCellFactory() { + createEditableCheckboxCellFactory(int colIndex) { return param -> { - return new CheckBoxTreeTableCell<T, Boolean>(); + CheckBoxTreeTableCell<T, Boolean> checkBoxTreeTableCell = + new CheckBoxTreeTableCell<T, Boolean>() { + /** {@inheritDoc} */ + @Override + public void updateItem(Boolean item, boolean empty) { + super.updateItem(item, empty); + styleCell(this, colIndex); + } + }; + return checkBoxTreeTableCell; }; } + /** Creates the cell factory for {@link ComboBox} editing. */ + private Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>> + createEditableComboCellFactory(int columnIndex, TreeTableColumn<T, String> column, + Function<T, Collection<String>> comboValueFactory) { + // The list with the choices to be offered in the combo. + ObservableList<String> items = observableArrayList(); + Callback<TreeTableColumn<T, String>, TreeTableCell<T, String>> comboCellFactory = + param -> new ComboBoxTreeTableCell<T, String>(null, items) { + /** {@inheritDoc} */ + @Override + public void updateItem(String item, boolean empty) { + super.updateItem(item, empty); + styleCell(this, columnIndex); + } + }; + + // Changes the choices of the combo for every editing of every cell dynamically. + column.setOnEditStart(event -> { + TreeItem<T> treeItem = event.getRowValue(); + T rowEntry = treeItem.getValue(); + + Collection<String> comboValues = comboValueFactory.apply(rowEntry); + + items.clear(); + items.addAll(comboValues); + }); + return comboCellFactory; + } + /** Custom table cell implementation to allow on key released validation. */ private class MyTextFieldTreeTableCell extends TextFieldTreeTableCell<T, String> { /** The column index of this cell. */ @@ -311,6 +426,7 @@ public abstract class DynamicTreeTableUIProviderBase<T> { } this.setGraphic(icon); this.setContextMenu(menu); + styleCell(this, colIndex); } /** @@ -337,7 +453,52 @@ public abstract class DynamicTreeTableUIProviderBase<T> { } }; cell.textProperty().bind(cell.itemProperty()); + return cell; }; } + + /** Converts a {@link Color} object into a rgb hex format as used in css. */ + private final static String colorToHex(Color color) { + return String.format("#%02X%02X%02X", (int)(color.getRed() * 255), + (int)(color.getGreen() * 255), (int)(color.getBlue() * 255)); + } + + /** + * Applies this UIProvider to configure the given {@link TreeTableColumn}. + * + * @param columnIndex + * The index number of the column. + * @param column + * The column to be configured. + */ + public void applyToTextColumn(int columnIndex, TreeTableColumn<T, String> column) { + column.setCellFactory(ttColumn -> { + DynamicTextFieldTreeTableCell<T> cell = new DynamicTextFieldTreeTableCell<T>() { + + /** {@inheritDoc} */ + @Override + protected boolean canEdit(T element) { + return isElementEditable(columnIndex, element); + } + + /** {@inheritDoc} */ + @Override + protected void setValueOnLeavingCell(T element, String currentValue) { + updateValue(element, columnIndex, currentValue); + } + + /** {@inheritDoc} */ + @Override + public void updateItem(String item, boolean empty) { + super.updateItem(item, empty); + styleCell(this, columnIndex); + } + }; + + styleCell(cell, columnIndex); + + return cell; + }); + } } diff --git a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java index 282cb151c31917bf7bde759f04e33b08eaa326c6..3d91b1bd43393f5d0733a253a85436b8255526ae 100644 --- a/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java +++ b/org.fortiss.tooling.common.ui/src/org/fortiss/tooling/common/ui/javafx/control/treetableview/DynamicTreeTableViewer.java @@ -16,14 +16,11 @@ package org.fortiss.tooling.common.ui.javafx.control.treetableview; import static java.lang.Integer.MAX_VALUE; -import static javafx.collections.FXCollections.observableArrayList; -import static javafx.scene.control.cell.ComboBoxTreeTableCell.forTreeTableColumn; import java.util.Collection; import java.util.function.Function; import javafx.beans.property.SimpleObjectProperty; -import javafx.collections.ObservableList; import javafx.scene.control.SelectionMode; import javafx.scene.control.TreeItem; import javafx.scene.control.TreeTableColumn; @@ -151,14 +148,31 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { column.setCellValueFactory(param -> { T data = param.getValue().getValue(); - return new SimpleObjectProperty<String>(uiProvider.getLabel(data, num)); + SimpleObjectProperty<String> cell = + new SimpleObjectProperty<String>(uiProvider.getLabel(data, num)); + return cell; }); uiProvider.applyToColumn(num, column); + view.getColumns().add(column); return column; } + /** + * Adds an editable column to the table part of the view. The labels, context menus and icons + * are shown as + * defined in the {@link DynamicTreeTableUIProviderBase}. + */ + public TreeTableColumn<T, String> addTextColumn(String headerLabel, int prefWidth) { + int num = view.getColumns().size(); + TreeTableColumn<T, String> column = addColumn(headerLabel, prefWidth); + + uiProvider.applyToTextColumn(num, column); + + return column; + } + /** * Adds a boolean checkbox column to the table part of the view. The labels, context menus and * icons are shown as defined in the {@link DynamicTreeTableUIProviderBase}. @@ -191,22 +205,10 @@ public final class DynamicTreeTableViewer<T> extends DynamicTreeViewerBase<T> { */ public TreeTableColumn<T, String> addComboColumn(String headerLabel, int prefWidth, Function<T, Collection<String>> comboValueFactory) { + int num = view.getColumns().size(); TreeTableColumn<T, String> column = addColumn(headerLabel, prefWidth); - // The list with the choices to be offered in the combo. - ObservableList<String> items = observableArrayList(); - column.setCellFactory(forTreeTableColumn(items)); - - // Changes the choices of the combo for every editing of every cell dynamically. - column.setOnEditStart(event -> { - TreeItem<T> treeItem = event.getRowValue(); - T rowEntry = treeItem.getValue(); - - Collection<String> comboValues = comboValueFactory.apply(rowEntry); - - items.clear(); - items.addAll(comboValues); - }); + uiProvider.applyToComboColumn(num, column, comboValueFactory); return column; }