Skip to content
Snippets Groups Projects
Commit 97dd2d1d authored by Andreas Bayha's avatar Andreas Bayha
Browse files

TreeTableViewer: Added dynamic background color.

Added the possibility to dynamically set the background color of each
cell. The UIProvider offers a getBackgroundColor method to this end.

Issue-Ref: 4014
Issue-Url: https://af3-developer.fortiss.org/issues/4014


Signed-off-by: default avatarAndreas Bayha <bayha@fortiss.org>
parent 72d00d76
No related branches found
No related tags found
1 merge request!1254014
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
......
......@@ -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;
});
}
}
......@@ -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;
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment