Skip to content

Instantly share code, notes, and snippets.

@james-d
Last active January 4, 2016 21:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save james-d/6fa93bc0459b6404e5e4 to your computer and use it in GitHub Desktop.
Save james-d/6fa93bc0459b6404e5e4 to your computer and use it in GitHub Desktop.
import javafx.application.Application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ObservableValue;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Spinner;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.BorderPane;
import javafx.stage.Stage;
public class ParameterSettingsTable extends Application {
@Override
public void start(Stage primaryStage) {
TableView<Parameter<?>> table = new TableView<>();
table.setEditable(true);
TableColumn<Parameter<?>, String> nameColumn = new TableColumn<>("Name");
TableColumn<Parameter<?>, Object> valueColumn = new TableColumn<>("Value");
table.getColumns().add(nameColumn);
table.getColumns().add(valueColumn);
nameColumn.setCellValueFactory(cellData -> new ReadOnlyStringWrapper(cellData.getValue().getName()));
valueColumn.setCellValueFactory(cellData -> (ObservableValue<Object>)cellData.getValue().valueProperty());
valueColumn.setCellFactory(tc -> new ParameterValueEditingCell());
Parameter<Platform> platform = new EnumParameter<>("Platform", Platform.DESKTOP);
Parameter<OSVendor> os = new EnumParameter<>("Operating System", OSVendor.APPLE);
Parameter<Integer> cpus = new BoundIntegerParameter(1, 64, "CPUs", 8);
Parameter<String> notes = new StringParameter("Notes", "");
platform.valueProperty().addListener((obs, oldPlatform, newPlatform) -> {
if (newPlatform == Platform.MOBILE) {
cpus.setValue(1);
cpus.setEditable(false);
} else {
cpus.setEditable(true);
}
});
table.getItems().addAll(platform, os, cpus, notes);
primaryStage.setScene(new Scene(new BorderPane(table), 600, 600));
primaryStage.show();
}
public enum Platform { MOBILE, TABLET, LAPTOP, DESKTOP, SERVER }
public enum OSVendor { MICROSOFT, REDHAT, APPLE, GOOGLE }
public static class ParameterValueEditingCell extends TableCell<Parameter<?>, Object> {
@Override
public void updateItem(Object item, boolean empty) {
super.updateItem(item, empty);
if (empty || item == null) {
setText(null);
setGraphic(null);
} else {
if (isEditing()) {
setText(null);
Parameter<?> param = getTableView().getItems().get(getIndex());
setGraphic(param.getEditor());
} else {
setText(item.toString());
setGraphic(null);
}
}
}
@Override
public void startEdit() {
// check if current parameter is editable and bail if not:
int index = getIndex();
if (index < 0 || index >= getTableView().getItems().size()) {
return ;
}
if (! getTableView().getItems().get(index).isEditable()) {
return ;
}
super.startEdit();
setText(null);
setGraphic(getTableView().getItems().get(getIndex()).getEditor());
}
@Override
public void cancelEdit() {
super.cancelEdit();
Object item = getItem();
setText(item == null ? null : item.toString());
setGraphic(null);
}
}
public abstract static class Parameter<T> {
private final BooleanProperty editable = new SimpleBooleanProperty();
private final ObjectProperty<T> value = new SimpleObjectProperty<>();
private final String name ;
public Parameter(String name, T value, boolean editable) {
this.name = name ;
setValue(value);
setEditable(editable);
}
public Parameter(String name, T value) {
this(name, value, true);
}
public String getName() {
return name ;
}
public ObjectProperty<T> valueProperty() {
return value ;
}
public T getValue() {
return valueProperty().get();
}
public void setValue(T value) {
valueProperty().set(value);
}
public BooleanProperty editableProperty() {
return editable ;
}
public boolean isEditable() {
return editableProperty().get() ;
}
public void setEditable(boolean editable) {
editableProperty().set(editable);
}
public abstract Node getEditor() ;
}
public static class StringParameter extends Parameter<String> {
private final TextField editor ;
public StringParameter(String name, String value) {
super(name, value);
editor = new TextField();
editor.textProperty().bindBidirectional(valueProperty());
}
@Override
public Node getEditor() {
return editor ;
}
}
public static class BoundIntegerParameter extends Parameter<Integer> {
private final Spinner<Integer> editor ;
public BoundIntegerParameter(int min, int max, String name, int value) {
super(name, value);
editor = new Spinner<>(min, max, value);
editor.setEditable(true);
editor.getValueFactory().valueProperty().bindBidirectional(valueProperty());
}
@Override
public Node getEditor() {
return editor ;
}
}
public static class EnumParameter<E extends Enum<E>> extends Parameter<E> {
private final ComboBox<E> editor ;
public EnumParameter(String name, E value) {
super(name, value);
editor = new ComboBox<>();
@SuppressWarnings("unchecked")
Class<E> type = (Class<E>) value.getClass();
E[] values = type.getEnumConstants() ;
editor.getItems().setAll(values);
editor.valueProperty().bindBidirectional(valueProperty());
}
@Override
public Node getEditor() {
return editor ;
}
}
public static void main(String[] args) {
launch(args);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment