public JooqRecordTableView(Table table, Result result)
public JooqRecordTableView(Table table, Record bRecord)
import javafx.collections.FXCollections;import javafx.collections.ObservableList;import javafx.scene.control.Alert;import javafx.scene.control.TableColumn;import javafx.scene.control.TableView;import org.jooq.*;
import java.util.ArrayList;import java.util.List;import java.util.stream.Stream;
import static java.util.stream.Collectors.toList;
public class JooqRecordTableView<B extends Record> extends TableView {
private static PropertiesHandle propertiesHandle; private Table<?> table; private ObservableList<B> records = FXCollections.observableArrayList(); private String propertyDirectory = "./resources/tables/"; private B templateRecord = null;
/* Constructor for standard tableView with JOOQ Result */ public JooqRecordTableView(Table table, Result result) { this.table = table; tableRecords(result); loadPropertiesForTable(); tableColumns(); this.setEditable(true); } /* generate Table Columns */ private <R extends Record, O extends Object> void tableColumns() {
List<TableColumn<R, ?>> tableColumns = new ArrayList<>();
if (templateRecord != null) { tableColumns.addAll(Stream.of(templateRecord.fields()) .map((Field<?> f) -> { TableColumn<R, ?> column = new TableColumn<>(f.getName()); column.setVisible((boolean) propertiesHandle.getProperty(f.getName() + "-visible", boolean.class)); column.setEditable((boolean) propertiesHandle.getProperty(f.getName() + "-editable", boolean.class)); column.setText(propertiesHandle.getProperty(f.getName(), String.class).toString()); column.setCellValueFactory(d -> new SimpleObjectProperty(d.getValue().get(f))); List<?> preloadValues = propertiesHandle.getPropertyValueList(f.getName(), String.class); column.setCellFactory(param -> new CellUniversalEditor(f, preloadValues)); column.setOnEditCommit( t -> { Field columnField = f; Object newValue = t.getNewValue();
if (f.getDataType().hasLength()) { String s = (String) newValue; if (f.getDataType().length() > s.length()) { records.get(t.getTablePosition().getRow()).set(columnField, newValue); ((UpdatableRecord) records.get(t.getTablePosition().getRow())).update(); System.out.println("Updating: " + f.getName() + "/" + newValue); } else { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setHeaderText("Error: too much characters"); alert.setContentText("Max.: " + f.getDataType().length()); alert.showAndWait(); } } else { records.get(t.getTablePosition().getRow()).set(columnField, newValue); ((UpdatableRecord) records.get(t.getTablePosition().getRow())).update(); System.out.println("Updating: " + f.getName() + "/" + newValue); } this.refresh(); } ); return column; }) .collect(toList()));
for (TableColumn tableColumn : tableColumns) { this.getColumns().add(tableColumn); } } } private void tableRecords(Result result) { for (Object o : result) { B record = (B) o; records.add(record); } if (records.size() > 0) { templateRecord = records.get(0); } this.setItems(records); this.refresh(); }
/* Constructor for inverted >single< Record tableView with JOOQ Record */ public JooqRecordTableView(Table table, Record bRecord) { this.setEditable(true); this.table = table; loadPropertiesForTable(); Record dataRecord = bRecord;
ObservableList<ColumnInformation> data = FXCollections.observableArrayList();
//prepare ColumnInformation for each Field for (Field field : bRecord.fields()) { String comment = propertiesHandle.getProperty(field.getName() + "-comment", String.class).toString(); String tooltip = propertiesHandle.getProperty(field.getName() + "-tooltip", String.class).toString(); Boolean visible = (Boolean) propertiesHandle.getProperty(field.getName() + "-visible", Boolean.class); Boolean editable = (Boolean) propertiesHandle.getProperty(field.getName() + "-editable", Boolean.class); if (comment.equals(field.getName() + "-comment")) { comment = ""; } if (tooltip.equals(field.getName() + "-tooltip")) { tooltip = ""; } List<?> preloadObjects = propertiesHandle.getPropertyValueList(field.getName(), String.class);
if (visible) { data.add(new ColumnInformation(propertiesHandle.getProperty(field.getName(), String.class).toString(), field.getValue(bRecord), comment, field, tooltip, editable, visible, preloadObjects)); } } getItems().addAll(data);
// table definition TableColumn<ColumnInformation, String> nameColumn = new TableColumn<>("Parameter"); nameColumn.setCellValueFactory(d -> new SimpleObjectProperty(d.getValue().getName())); nameColumn.setEditable(false);
TableColumn<ColumnInformation, Object> valueColumn = new TableColumn<>("Wert"); valueColumn.setEditable(true); valueColumn.setCellValueFactory(d -> new SimpleObjectProperty(d.getValue().getValue())); CellUniversalEditor cellUniversalEditor = new CellUniversalEditor(); valueColumn.setCellFactory(param -> new CellUniversalEditor()); valueColumn.setOnEditCommit( t -> { ColumnInformation cellData = data.get(t.getTablePosition().getRow()); Field columnField = cellData.getField(); Object newValue = t.getNewValue();
if (columnField.getDataType().hasLength()) { String s = (String) newValue; if (columnField.getDataType().length() > s.length()) { data.get(t.getTablePosition().getRow()).setValue(newValue); dataRecord.set(columnField, newValue); ((UpdatableRecord) dataRecord).update(); System.out.println("Updating: " + columnField.getName() + "/" + newValue); } else { Alert alert = new Alert(Alert.AlertType.ERROR); alert.setHeaderText("Error: too much characters"); alert.setContentText("Max.: " + f.getDataType().length()); alert.showAndWait(); } } else { data.get(t.getTablePosition().getRow()).setValue(newValue); dataRecord.set(columnField, newValue); ((UpdatableRecord) dataRecord).update(); System.out.println("Updating: " + columnField.getName() + "/" + newValue); } this.refresh(); } );
TableColumn<ColumnInformation, Object> commentColumn = new TableColumn<>("Kommentar"); commentColumn.setCellValueFactory(d -> new SimpleObjectProperty(d.getValue().getComment())); commentColumn.setEditable(false); valueColumn.setSortable(false); getColumns().setAll(nameColumn, valueColumn, commentColumn); }
/* Load Properties File for Table*/ private void loadPropertiesForTable() { String propertyPath = propertyDirectory + table.getName(); propertiesHandle = new PropertiesHandle(propertyPath); }
}
class ColumnInformation { private String name; private Object value; private String comment; private Field<?> field; private String tooltipText; private List<?> preloadValues;
private Boolean editable; private Boolean visible;
ColumnInformation(String name, Object value, String comment, Field<?> field, String tooltipText, Boolean editable, Boolean visible, List<?> preloadValues) { this.setName(name); this.setValue(value); this.setComment(comment); this.setField(field); this.setTooltipText(tooltipText); this.setVisible(visible); this.setEditable(editable); this.setPreloadValues(preloadValues); }
public String getTooltipText() { return tooltipText; }
public void setTooltipText(String tooltipText) { this.tooltipText = tooltipText; }
public Field<?> getField() { return field; }
public void setField(Field<?> field) { this.field = field; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public Object getValue() { return value; }
public void setValue(Object value) { this.value = value; }
public String getComment() { return comment; }
public void setComment(String comment) { this.comment = comment; }
public Boolean getEditable() { return editable; }
public void setEditable(Boolean editable) { this.editable = editable; }
public Boolean getVisible() { return visible; }
public void setVisible(Boolean visible) { this.visible = visible; }
public List<?> getPreloadValues() { return preloadValues; }
public void setPreloadValues(List<?> preloadValues) { this.preloadValues = preloadValues; }}
import javafx.scene.Node;import javafx.scene.control.*;import javafx.scene.input.KeyCode;import javafx.util.StringConverter;import org.jooq.Field;import org.jooq.Record;import org.jooq.Table;import tornadofx.control.DateTimePicker;
import java.time.LocalDate;import java.time.LocalDateTime;import java.util.ArrayList;import java.util.List;
class CellUniversalEditor<R extends Record> extends TableCell<Table<R>, Object> {
private TextField textField; private CheckBox checkBox; private DateTimePicker dateTimePicker; private DatePicker datePicker; private Label valueLabel = new Label(); private Spinner<Integer> integerSpinner; private ComboBox comboBox; private Field field = null;
private Object graphicElement;
private List<?> preloadValues = new ArrayList<>(); private Boolean cellEditable = false;
public CellUniversalEditor() { }
/* Constructor with preloadValues */ public CellUniversalEditor(Field field, List<?> preloadValues) { this.field = field; this.preloadValues = preloadValues; }
public Boolean getCellEditable() { return cellEditable; }
public void setCellEditable(Boolean cellEditable) { this.cellEditable = cellEditable; }
/* Override Functions for TableCell */ @Override public void startEdit() { String dataType = null; Object value = null; ColumnInformation columnInformation = null; value = getValue();
if (field == null) { columnInformation = (ColumnInformation) getTableRow().getItem(); dataType = columnInformation.getField().getDataType().getType().getSimpleName(); preloadValues = columnInformation.getPreloadValues(); cellEditable = columnInformation.getEditable(); } else { dataType = field.getDataType().getType().getSimpleName(); cellEditable = getTableColumn().isEditable(); }
if (cellEditable) { super.startEdit(); switch (dataType) { case "Boolean": checkBox = new CheckBox(); Boolean aBoolean = value == null ? false : (boolean) value; checkBox.setSelected(aBoolean); checkBox.setOnAction(event -> commitEdit(checkBox.isSelected())); graphicElement = checkBox; break;
case "LocalDateTime": dateTimePicker = new DateTimePicker(); dateTimePicker.setDateTimeValue((LocalDateTime) getValue()); dateTimePicker.setOnAction(event -> commitEdit(dateTimePicker.getDateTimeValue())); graphicElement = dateTimePicker; break;
case "LocalDate": datePicker = new DateTimePicker(); datePicker.setValue((LocalDate) getValue()); datePicker.setOnAction(event -> commitEdit(datePicker.getValue())); graphicElement = datePicker; break;
case "Integer": integerSpinner = new Spinner<>(); Integer integer = value == null ? 0 : (int) value; SpinnerValueFactory<Integer> valueFactory = new SpinnerValueFactory.IntegerSpinnerValueFactory(0, Integer.MAX_VALUE, integer); integerSpinner.setValueFactory(valueFactory); integerSpinner.setEditable(true); integerSpinner.getEditor().setOnMouseClicked(event -> integerSpinner.getEditor().selectAll()); integerSpinner.getEditor().setOnKeyPressed(t -> { if (t.getCode() == KeyCode.ENTER) { String integerString = integerSpinner.getEditor().getText(); if (valueFactory != null) { StringConverter<Integer> converter = valueFactory.getConverter(); if (converter != null) { try { valueFactory.setValue(converter.fromString(integerString)); commitEdit(integerSpinner.valueProperty().getValue()); } catch (NumberFormatException nfe) { integerSpinner.getEditor().setText(converter.toString(valueFactory.getValue())); } } } } else if (t.getCode() == KeyCode.ESCAPE) { cancelEdit(); } }); integerSpinner.getEditor().selectAll(); graphicElement = integerSpinner; break;
case "String": if (preloadValues.size() > 0) { comboBox = new ComboBox<>(); comboBox.getItems().add(""); comboBox.getItems().addAll(preloadValues); if (getValue() != null) { comboBox.getSelectionModel().select(getValue()); } comboBox.setOnAction(event -> commitEdit(comboBox.getValue())); graphicElement = comboBox; } else { String s = value == null ? "" : (String) value; textField = new TextField(s); textField.setMinWidth(this.getWidth() - this.getGraphicTextGap() * 2); textField.setOnKeyPressed(t -> { if (t.getCode() == KeyCode.ENTER) { commitEdit(textField.getText()); } else if (t.getCode() == KeyCode.ESCAPE) { cancelEdit(); } }); graphicElement = textField; } break;
default: Alert alert = new Alert(Alert.AlertType.ERROR); alert.setHeaderText("Form Error"); alert.setContentText("Datatype not supported!"); alert.showAndWait(); } setGraphic((Node) graphicElement); setContentDisplay(ContentDisplay.GRAPHIC_ONLY); } }
@Override public void cancelEdit() { super.cancelEdit(); setGraphic(valueLabel); }
@Override public void updateItem(Object item, boolean empty) { super.updateItem(item, empty); setGraphic(valueLabel); setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
if (empty || item == null) { setText(""); valueLabel.setText(""); } else { if (isEditing()) { } else { setText(getValue().toString()); switch (item.getClass().getSimpleName()) { case "Boolean": if ((Boolean) item == true) { valueLabel.setText("Yes"); } else { valueLabel.setText("No"); } break; case "LocalDate": valueLabel.setText(date2GermanFormat((LocalDate) item)); break; case "LocalDateTime": valueLabel.setText(datetime2GermanFormat((LocalDateTime) item)); break; default: valueLabel.setText(getValue().toString()); } } } }
private Object getValue() { return getItem() == null ? null : getItem(); }}
import org.apache.commons.io.FileUtils;
import java.io.File;import java.io.FileInputStream;import java.io.FileOutputStream;import java.io.IOException;import java.nio.file.Files;import java.nio.file.Path;import java.nio.file.Paths;import java.util.*;
public class PropertiesHandle {
private SortedProperties properties; private String propertyPath;
public PropertiesHandle(String propertyPath) { this.propertyPath = propertyPath + ".properties";
Path path = Paths.get(this.propertyPath); if (Files.exists(path)) { properties = new SortedProperties(); try { properties.load(new FileInputStream(this.propertyPath)); } catch (IOException e) { e.printStackTrace(); } } else { properties = new SortedProperties(); writeProperties2File(); } }
private void writeProperties2File() { File file = new File(propertyPath); try { FileOutputStream fileOut = FileUtils.openOutputStream(file); properties.store(fileOut, propertyPath); fileOut.close(); } catch (IOException e) { e.printStackTrace(); } }
public Object getProperty(String key, Class aClass) { Object o = null;
String value = properties.getProperty(key); //if key exists if (value != null) { //if key is empty if (!value.equals("")) { switch (aClass.getSimpleName()) { case "boolean": o = Boolean.valueOf(value); break;
case "Boolean": o = Boolean.valueOf(value); break;
default: o = aClass.cast(value); } } else { switch (aClass.getSimpleName()) { case "boolean": o = new Boolean(false); break; case "Boolean": o = new Boolean(false); break; default: o = key; }
} //if key not exists } else { properties.setProperty(key, ""); writeProperties2File(); switch (aClass.toString()) { case "boolean": o = new Boolean(false); break;
default: o = key; } }
return o; }
public List getPropertyValueList(String key, Class aClass) { List objects = new ArrayList<>(); String sValue = (String) getProperty(key + "-values", String.class); if (!sValue.equals(key + "-values")) { List<String> strings = Arrays.asList(sValue.split(",")); for (String s : strings){ objects.add(s.trim()); } } return objects; }
}
class SortedProperties extends Properties { public Enumeration keys() { Enumeration keysEnum = super.keys(); Vector<String> keyList = new Vector<String>(); while (keysEnum.hasMoreElements()) { keyList.add((String) keysEnum.nextElement()); } Collections.sort(keyList); return keyList.elements(); }}