Я создал пример того, как я это сделаю, но, пожалуйста: я создаю это в течение получаса или около того - код далеко не идеален, нормально?
Вот полный код ...
FXML:
<?xml version="1.0" encoding="UTF-8"?>
<!--
Do not edit this file it is generated by e(fx)clipse from ../src/application/TableTest.fxgraph
-->
<?import java.lang.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.layout.BorderPane?>
<BorderPane xmlns:fx="http://javafx.com/fxml" fx:controller="application.TableTestController">
<center>
<TableView fx:id="tableView">
<columns>
<TableColumn fx:id="tableColumnText" text="Text" prefWidth="150"/>
<TableColumn fx:id="tableColumnFlag" text="Flag" prefWidth="50"/>
<TableColumn fx:id="tableColumnAncestor" text="Ancestor" prefWidth="75"/>
<TableColumn fx:id="tableColumnDescendant" text="Descendant" prefWidth="100"/>
<TableColumn fx:id="tableColumnPoints" text="Points" prefWidth="75"/>
</columns>
<BorderPane.margin>
<Insets top="5" left="5" right="5" bottom="5"/>
</BorderPane.margin>
</TableView>
</center>
</BorderPane>
класс данных Модель (тот, который, представляющий собой одну строку в TableView):
package application;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
public class TableTestObject {
private StringProperty text = new SimpleStringProperty("");
private BooleanProperty flag = new SimpleBooleanProperty(false);
private StringProperty ancestor = new SimpleStringProperty("");
private StringProperty descendant = new SimpleStringProperty("");
private IntegerProperty points = new SimpleIntegerProperty(0);
public final StringProperty textProperty() {
return this.text;
}
public final String getText() {
return this.textProperty().get();
}
public final void setText(final String text) {
this.textProperty().set(text);
}
public final BooleanProperty flagProperty() {
return this.flag;
}
public final boolean isFlag() {
return this.flagProperty().get();
}
public final void setFlag(final boolean flag) {
this.flagProperty().set(flag);
}
public final StringProperty ancestorProperty() {
return this.ancestor;
}
public final String getAncestor() {
return this.ancestorProperty().get();
}
public final void setAncestor(final String ancestor) {
this.ancestorProperty().set(ancestor);
}
public final StringProperty descendantProperty() {
return this.descendant;
}
public final String getDescendant() {
return this.descendantProperty().get();
}
public final void setDescendant(final String descendant) {
this.descendantProperty().set(descendant);
}
public final IntegerProperty pointsProperty() {
return this.points;
}
public final int getPoints() {
return this.pointsProperty().get();
}
public final void setPoints(final int points) {
this.pointsProperty().set(points);
}
}
Основной класс:
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
public class Main extends Application {
@Override
public void start(Stage stage) throws Exception {
FXMLLoader loader = new FXMLLoader(getClass().getResource("TableTest.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root, 1200, 800);
stage.setScene(scene);
stage.show();
}
public static void main(String[] args) {
launch(args);
}
}
TableTestController (тот , что делает обязательный материал):
package application;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javafx.beans.property.SimpleObjectProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.Spinner;
import javafx.scene.control.SpinnerValueFactory;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.cell.PropertyValueFactory;
public class TableTestController {
@FXML
private TableView<TableTestObject> tableView;
@FXML
private TableColumn<TableTestObject, String> tableColumnText;
@FXML
private TableColumn<TableTestObject, TableTestObject> tableColumnFlag;
@FXML
private TableColumn<TableTestObject, TableTestObject> tableColumnAncestor;
@FXML
private TableColumn<TableTestObject, TableTestObject> tableColumnDescendant;
@FXML
private TableColumn<TableTestObject, TableTestObject> tableColumnPoints;
private Map<String, List<String>> descendantMap;
private ObservableList<String> ancestorList;
@FXML
protected void initialize() {
descendantMap = new HashMap<>();
descendantMap.put("1", Arrays.asList("A", "B", "C"));
descendantMap.put("2", Arrays.asList("Z", "L", "C"));
descendantMap.put("3", Arrays.asList("A", "B", "R"));
descendantMap.put("4", Arrays.asList("C", "B", "E"));
descendantMap.put("5", Arrays.asList("A", "E", "C"));
descendantMap.put("6", Arrays.asList("M", "V", "T"));
descendantMap.put("7", Arrays.asList("A", "G", "F"));
descendantMap.put("8", Arrays.asList("J", "O", "N"));
descendantMap.put("9", Arrays.asList("X", "G", "E"));
descendantMap.put("10", Arrays.asList("H", "I", "J"));
ancestorList = FXCollections.observableArrayList(descendantMap.keySet());
ObservableList<TableTestObject> data = FXCollections.observableArrayList();
TableTestObject test = new TableTestObject();
test.setText("Test");
test.setFlag(true);
test.setPoints(1);
data.add(test);
tableView.setItems(data);
tableColumnText.setCellValueFactory(new PropertyValueFactory<>("text"));
tableColumnFlag.setCellValueFactory(param -> new SimpleObjectProperty<TableTestObject>(param.getValue()));
tableColumnAncestor.setCellValueFactory(param -> new SimpleObjectProperty<TableTestObject>(param.getValue()));
tableColumnDescendant.setCellValueFactory(param -> new SimpleObjectProperty<TableTestObject>(param.getValue()));
tableColumnPoints.setCellValueFactory(param -> new SimpleObjectProperty<TableTestObject>(param.getValue()));
tableColumnFlag.setCellFactory(param -> new TableCell<TableTestObject, TableTestObject>() {
@Override
protected void updateItem(TableTestObject item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
} else {
CheckBox cb = new CheckBox();
cb.selectedProperty().bindBidirectional(item.flagProperty());
setGraphic(cb);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
});
tableColumnAncestor.setCellFactory(param -> new TableCell<TableTestObject, TableTestObject>() {
@Override
protected void updateItem(TableTestObject item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
} else {
ComboBox<String> cb = new ComboBox<>(ancestorList);
cb.getSelectionModel().selectedItemProperty().addListener((ChangeListener<String>) (observable, oldValue, newValue) -> {
item.ancestorProperty().set(newValue);
System.out.println(item.descendantProperty().get());
});
setGraphic(cb);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
});
tableColumnDescendant.setCellFactory(param -> new TableCell<TableTestObject, TableTestObject>() {
@Override
protected void updateItem(TableTestObject item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
} else {
ComboBox<String> cb = new ComboBox<>();
item.ancestorProperty().addListener((ChangeListener<String>) (observable, oldValue, newValue) -> {
item.descendantProperty().set("");
cb.setItems(FXCollections.observableArrayList(descendantMap.get(newValue)));
});
cb.getSelectionModel().selectedItemProperty().addListener((ChangeListener<String>) (observable, oldValue, newValue) -> {
item.descendantProperty().set(newValue);
System.out.println(item.descendantProperty().get());
});
setGraphic(cb);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
});
tableColumnPoints.setCellFactory(param -> new TableCell<TableTestObject, TableTestObject>() {
@Override
protected void updateItem(TableTestObject item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
} else {
Spinner<Integer> spinner = new Spinner<>();
spinner.setValueFactory(new SpinnerValueFactory.IntegerSpinnerValueFactory(-5, +5, item.getPoints()));
spinner.valueProperty().addListener((ChangeListener<Integer>) (observable, oldValue, newValue) -> {
item.pointsProperty().set(newValue);
System.out.println(item.pointsProperty().get());
});
setGraphic(spinner);
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
}
}
});
}
}
Еще раз: Контроллер - это тот, который выполняет привязку. С Lambdas код почти читабельен, но вы все равно должны его переработать.
Приветствия, Daniel
мой среды IDE NetBeans не распознан импорт javafx.scene.control.Spinner, как вы в состоянии компонент? – Doberon
Я пользователь Eclipse, поэтому я не уверен на 100 процентов. Я полагаю, он должен работать из коробки. Какую версию Java вы используете? – dzim