JavaFX TableView - 同一行中新Cell的新值 [英] JavaFX TableView - New Values in new Cell in same Row
问题描述
我遇到了以下问题:
我将TableViews单元格设置为矩形。现在我要添加带有X和Y坐标的对象( obj.getAblaufX()
和 obj.getAblaufY()
)。
如何在JavaFX TableView中正确添加它们?
I styled a TableViews Cells into Rectangles. Now I want to add Objects with an X and Y Coordinate in it (obj.getAblaufX()
and obj.getAblaufY()
).
How can I add them correctly in JavaFX TableView?
我的当前代码:
ObservableList<Event> eventList = loadEvents();
TableView<Event> tableView = new TableView<Event>();
tableView.getSelectionModel().setCellSelectionEnabled(true);
tableView.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
tableView.setItems(eventList);
for(int i = 0; i < 10; i++) {
TableColumn<Event, String> tmpCol = new TableColumn<>();
tmpCol.setId(Integer.toString(i));
tmpCol.setMaxWidth(40);
tmpCol.setCellValueFactory(cellData -> new ObservableValue<String>() {
@Override
public void addListener(InvalidationListener listener) {
// TODO Auto-generated method stub
}
@Override
public void removeListener(InvalidationListener listener) {
// TODO Auto-generated method stub
}
@Override
public void addListener(ChangeListener<? super String> listener) {
// TODO Auto-generated method stub
}
@Override
public void removeListener(ChangeListener<? super String> listener) {
// TODO Auto-generated method stub
}
@Override
public String getValue() {
if(Integer.parseInt(tmpCol.getId()) == cellData.getValue().getAblaufX()) {
return cellData.getValue().getAbteilung();
} else {
return "";
}
}
});
tableView.getColumns().add(tmpCol);
}
结果:
但是:
对象SP1有X = 0和Y = 0
对象SP2有X = 1而Y = 0
那么,如何解决这个问题?
So, how to fix this Problem?
推荐答案
使用事件
作为项目类型,你通过在每行显示多个事件
来实现 TableView
。使用 Integer
作为项目类型,并将值存储在 ObservableMap< TablePos,Event>
其中 TablePos
是一个包含 x
和 y
坐标的类:
By using Event
as item type, you pervent the TableView
from displaying more than one Event
per row. Use Integer
as item type instead and store the values in a ObservableMap<TablePos, Event>
where TablePos
is a class containing the x
and y
coordinates:
public final class TablePos {
private final int x;
private final int y;
public TablePos(int x, int y) {
this.x = x;
this.y = y;
}
@Override
public int hashCode() {
int hash = 7;
hash = 17 * hash + this.x;
hash = 17 * hash + this.y;
return hash;
}
@Override
public boolean equals(Object obj) {
if (obj == null || !(obj instanceof TablePos)) {
return false;
}
final TablePos other = (TablePos) obj;
return (this.x == other.x && this.y == other.y);
}
}
public class Event {
private final StringProperty name;
private final IntegerProperty x;
private final IntegerProperty y;
public Event(String name, int x, int y) {
// set beans for properties here to make this instance accessible to listeners
this.y = new SimpleIntegerProperty(this, "y", y);
this.x = new SimpleIntegerProperty(this, "x", x);
this.name = new SimpleStringProperty(this, "name", name);
}
public final String getName() {
return this.name.get();
}
public final void setName(String value) {
this.name.set(value);
}
public final StringProperty nameProperty() {
return this.name;
}
public final int getX() {
return this.x.get();
}
public final void setX(int value) {
this.x.set(value);
}
public final IntegerProperty xProperty() {
return this.x;
}
public final int getY() {
return this.y.get();
}
public final void setY(int value) {
this.y.set(value);
}
public final IntegerProperty yProperty() {
return this.y;
}
}
private static void put(Map<TablePos, Event> map, Event evt) {
map.put(new TablePos(evt.getX(), evt.getY()), evt);
}
@Override
public void start(Stage primaryStage) {
ObservableMap<TablePos, Event> contents = FXCollections.observableHashMap();
TableView<Integer> tableView = new TableView<>(FXCollections.observableArrayList());
TableColumn columnGroup = new TableColumn("Heutige Termine");
ChangeListener<Number> xChangeListener = (observable, oldValue, newValue) -> {
Event evt = (Event) ((Property) observable).getBean();
TablePos oldPos = new TablePos(oldValue.intValue(), evt.getY());
TablePos newPos = new TablePos(newValue.intValue(), evt.getY());
contents.remove(oldPos);
contents.put(newPos, evt);
};
ChangeListener<Number> yChangeListener = (observable, oldValue, newValue) -> {
Event evt = (Event) ((Property) observable).getBean();
TablePos oldPos = new TablePos(evt.getX(), oldValue.intValue());
TablePos newPos = new TablePos(evt.getX(), newValue.intValue());
contents.remove(oldPos);
contents.put(newPos, evt);
};
contents.addListener((MapChangeListener.Change<? extends TablePos, ? extends Event> change) -> {
if (change.wasRemoved()) {
Event evt = change.getValueRemoved();
evt.xProperty().removeListener(xChangeListener);
evt.yProperty().removeListener(yChangeListener);
}
if (change.wasAdded()) {
Event evt = change.getValueAdded();
evt.xProperty().addListener(xChangeListener);
evt.yProperty().addListener(yChangeListener);
}
});
// items denote the y coordinate
for (int i = 0; i < 10; i++) {
tableView.getItems().add(i);
}
// one column per x coordiante
for (int i = 0; i < 10; i++) {
final int index = i;
TableColumn<Integer, String> column = new TableColumn<>();
// take value from Map using x (index) and y (item value)
column.setCellValueFactory(cd
-> Bindings.selectString(
Bindings.valueAt(contents, new TablePos(index, cd.getValue())), "name"));
columnGroup.getColumns().add(column);
}
tableView.getColumns().add(columnGroup);
Event opTarget = new Event("Something", 2, 9);
put(contents, new Event("SP1", 0, 0));
put(contents, new Event("SP2", 1, 0));
put(contents, opTarget);
Button move = new Button("move");
move.setOnAction(evt -> opTarget.setX(9 - opTarget.getX()));
Button rename = new Button("rename");
rename.setOnAction(evt -> opTarget.setName(opTarget.getName().equals("42") ? "Answer" : "42"));
Scene scene = new Scene(new VBox(10, tableView, move, rename));
primaryStage.setScene(scene);
primaryStage.show();
}
请注意,这需要您知道初始化时的行数/列数(为简单起见,我使用了10)。如果不是这种情况,您可以向 ObservableMap
添加一个监听器,动态添加/删除行/列。
Note that this requires you to know the number of rows/columns at the initialisation (I used 10 for both for simplicity). If this is not the case, you could add a listener to the ObservableMap
that dynamically adds/removes rows / columns.
这篇关于JavaFX TableView - 同一行中新Cell的新值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!