0
我在JavaFX中使用treeview來實現文件瀏覽器。我把Tab中的treeview設置爲conent。當我使用預定線程刷新treeview元素時,我無法滾動到以前選擇的樹項目。這裏是我的啓示的最小版本。JavaFX:刷新內容後如何記住tabcontent的滾動位置?
/**
*
* @author nika
*/
public class TabTreeView extends Application implements Runnable {
private TreeItem<String> root;
private TreeView<String> tv = new TreeView<>();
private static ArrayList<NumberPair> rememberExpanded = new ArrayList<>();
private TreeItem<String> previouslySelectedTreeItem;
@Override
public void run() {
root = new TreeItem<>("Root");
root.setExpanded(true);
for (int i = 0; i < 10; i++) {
TreeItem<String> sublevel = new TreeItem<>("Level : " + i + " TS: " + System.currentTimeMillis());
final int level = i;
if (rememberExpanded.contains(new NumberPair(level, -9999))) {
sublevel.setExpanded(true);
}
sublevel.expandedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
rememberExpanded.add(new NumberPair(level, -9999));
} else {
rememberExpanded.remove(new NumberPair(level, -9999));
}
}
});
for (int j = 0; j < 5; j++) {
TreeItem<String> subsublevel = new TreeItem<>("SubLevel : " + j + " @ " + i + " TS:" + System.currentTimeMillis());
final int level2 = j;
if (rememberExpanded.contains(new NumberPair(level, level2))) {
sublevel.setExpanded(true);
}
subsublevel.expandedProperty().addListener(new ChangeListener<Boolean>() {
@Override
public void changed(ObservableValue<? extends Boolean> observable, Boolean oldValue, Boolean newValue) {
if (newValue) {
rememberExpanded.add(new NumberPair(level, level2));
} else {
rememberExpanded.remove(new NumberPair(level, level2));
}
}
});
sublevel.getChildren().add(subsublevel);
}
root.getChildren().add(sublevel);
}
Platform.runLater(new Runnable() {
@Override
public void run() {
tv.setRoot(root);
//scroll to previously selected item
//i know this one is wrong 1. "as it is not working", 2. "because it will only look into children of root not grandchildren".
tv.scrollTo(root.getChildren().indexOf(previouslySelectedTreeItem));
}
});
}
@Override
public void start(Stage primaryStage) throws Exception {
TabPane tabpane = new TabPane();
tv.selectionModelProperty().addListener(new ChangeListener<MultipleSelectionModel<TreeItem<String>>>() {
@Override
public void changed(ObservableValue<? extends MultipleSelectionModel<TreeItem<String>>> observable, MultipleSelectionModel<TreeItem<String>> oldValue, MultipleSelectionModel<TreeItem<String>> newValue) {
previouslySelectedTreeItem = newValue.getSelectedItem();
}
});
Tab t = new Tab("Demo", tv);
tabpane.getTabs().add(t);
BorderPane bp = new BorderPane(tabpane);
primaryStage.setScene(new Scene(bp));
primaryStage.show();
ScheduledExecutorService exc = Executors.newScheduledThreadPool(1);
exc.scheduleAtFixedRate(this, 0, 2, TimeUnit.SECONDS);
}
public static void main(String[] args) throws Exception {
launch(TabTreeView.class, args);
}
private class NumberPair {
int first, second;
public NumberPair(int first, int second) {
this.first = first;
this.second = second;
}
public int getFirst() {
return first;
}
public void setFirst(int first) {
this.first = first;
}
public int getSecond() {
return second;
}
public void setSecond(int second) {
this.second = second;
}
@Override
public int hashCode() {
int hash = 3;
hash = 37 * hash + this.first;
hash = 37 * hash + this.second;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final NumberPair other = (NumberPair) obj;
if (this.first != other.first) {
return false;
}
if (this.second != other.second) {
return false;
}
return true;
}
@Override
public String toString() {
return "NumberPair{" + "first=" + first + ", second=" + second + '}';
}
}
}
有沒有辦法記住滾動tabcontent或treeview的位置?這樣我可以在刷新視圖後恢復滾動位置。
在這個實現中,我添加了一個NumberPair
類來記住擴展項目。