我想要在TableView
中显示以下ObservableMap:
private ObservableMap<String, Shape> myShapes = FXCollections.observableHashMap();
Shape
的定义如下:
public class Shape {
private StringProperty areaFormula = new SimpleStringProperty();
private IntegerProperty numSides = new SimpleIntegerProperty();
public Shape(String areaFormula, int numSides)
{
this.areaFormula.set(areaFormula);
this.numSides.set(numSides);
}
public String getAreaFormula() { return areaFormula.get(); }
public void setAreaFormula(String areaFormula) { this.areaFormula.set(areaFormula); }
public StringProperty areaFormulaProperty() { return this.areaFormula; }
public int getNumSides() { return numSides.get(); }
public void setNumSides(int sides) { this.numSides.set(sides); }
public IntegerProperty numSidesProperty() { return this.numSides; }
}
我希望TableView的第一列是Map Key(称之为key
),第二列是myShapes.get(key).getAreaFormula()
,第三列是myShapes.get(key).getnumSides()
。我希望TableView在Map更改时自动更新。
如果可能的话,让TableView
的第二和第三列可以编辑,并在地图中更新这些编辑,这也是非常好的。
我已经询问了有关使用ObservableMap填充TableView的stackoverflow,以便在此处更新更改: Populating a TableView with a HashMap that will update when HashMap changes。但是正如你在那里的讨论中所看到的那样,它没有像我这里那样处理自定义类。
到目前为止,这是我的解决方案:
ObservableMap<String, Shape> map = FXCollections.observableHashMap();
ObservableList<String> keys = FXCollections.observableArrayList();
map.addListener((MapChangeListener.Change<? extends String, ? extends Shape> change) -> {
boolean removed = change.wasRemoved();
if (removed != change.wasAdded()) {
// no put for existing key
if (removed) {
keys.remove(change.getKey());
} else {
keys.add(change.getKey());
}
}
});
map.put("square", new Shape("L^2", 4));
map.put("rectangle", new Shape("LW", 4));
map.put("triangle", new Shape("0.5HB", 3));
final TableView<String> table = new TableView<>(keys);
TableColumn<String, String> column1 = new TableColumn<>("Key");
column1.setCellValueFactory(cd -> Bindings.createStringBinding(() -> cd.getValue()));
TableColumn<String, String> column2 = new TableColumn<>("Value");
column2.setCellValueFactory( ... );
table.getColumns().setAll(column1, column2);
我被困的地方是倒数第二行column2.setCellValueFactory( ... )
。我希望column2
显示Shape
getAreaFormula()
SimpleStringProperty
,但我不知道如何设置CellValueFactory
到delete_these_indexes.each_with_index do |val, i|
my_array.delete_at(val - i)
end
这样做。
感谢您的帮助。
答案 0 :(得分:2)
这是最简单的,如果您创建一个不可变键值对列表而不是简单的键列表。这大大降低了您需要使用的侦听器的复杂性,因为public final class MapEntry<K, V> {
private final K key;
private final V value;
public MapEntry(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public boolean equals(Object obj) {
// check equality only based on keys
if (obj instanceof MapEntry) {
MapEntry<?, ?> other = (MapEntry<?, ?>) obj;
return Objects.equals(key, other.key);
} else {
return false;
}
}
public K getKey() {
return key;
}
public V getValue() {
return value;
}
}
将始终替换项目,如果值已更新且您不需要将监听器添加到ObservableMap<String, Shape> map = FXCollections.observableHashMap();
ObservableList<MapEntry<String, Shape>> entries = FXCollections.observableArrayList();
map.addListener((MapChangeListener.Change<? extends String, ? extends Shape> change) -> {
boolean removed = change.wasRemoved();
if (removed != change.wasAdded()) {
if (removed) {
// no put for existing key
// remove pair completely
entries.remove(new MapEntry<>(change.getKey(), (Shape) null));
} else {
// add new entry
entries.add(new MapEntry<>(change.getKey(), change.getValueAdded()));
}
} else {
// replace existing entry
MapEntry<String, Shape> entry = new MapEntry<>(change.getKey(), change.getValueAdded());
int index = entries.indexOf(entry);
entries.set(index, entry);
}
});
map.put("one", new Shape("a", 1));
map.put("two", new Shape("b", 2));
map.put("three", new Shape("c", 3));
final TableView<MapEntry<String, Shape>> table = new TableView<>(entries);
TableColumn<MapEntry<String, Shape>, String> column1 = new TableColumn<>("Key");
// display item value (= constant)
column1.setCellValueFactory(cd -> Bindings.createStringBinding(() -> cd.getValue().getKey()));
TableColumn<MapEntry<String, Shape>, String> column2 = new TableColumn<>("formula");
column2.setCellValueFactory(cd -> cd.getValue().getValue().areaFormulaProperty());
TableColumn<MapEntry<String, Shape>, Number> column3 = new TableColumn<>("sides");
column3.setCellValueFactory(cd -> cd.getValue().getValue().numSidesProperty());
table.getColumns().setAll(column1, column2, column3);
中<script type="text/javascript" src="http://code.jquery.com/jquery-latest.js"></script>
<script type="text/javascript">
$(document).ready(function(){
var myCookie = getCookie("helpText");
if (typeof myCookie === 'undefined') {
// close the div in 8 secs
window.setTimeout( closeHelpDiv, 8000 );
}
function closeHelpDiv(){
document.getElementById("helpdiv").style.display=" none";
}
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
});
</script>
s:
<script type="text/javascript">
jQuery(document).ready(function($){
var myCookie = getCookie("helpText");
if (typeof myCookie === 'undefined') {
// close the div in 8 secs
window.setTimeout( closeHelpDiv, 8000 );
//setTimeout(closeHelpDiv, 2000);
}
function closeHelpDiv(){
document.getElementById("helpdiv").style.display=" none";
}
function getCookie(name) {
var value = "; " + document.cookie;
var parts = value.split("; " + name + "=");
if (parts.length == 2) return parts.pop().split(";").shift();
}
});
</script>
$(document).ready(function(){});