gpt4 book ai didi

Javafx Tableview 将选定的行保留在当前 View 中

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:20:40 24 4
gpt4 key购买 nike

我正在使用 javafx tableview,每毫秒主动排序和插入一个新行...

我想要这个功能:

如果我选择了一行,那么当插入新行时它应该保持可见(即不应该从我的表格的当前可见部分上升或下降)。

最佳答案

这可能离它很远而且有点老套,但当我需要做类似的事情时它对我有用。

答案的要点是您需要访问 VirtualFlow TableViewSkin的成员.这并不像听起来那么简单,因为在解析 CSS 之前不会加载皮肤。我添加了一个 ListenerskinPropertyTableView并且能够得到 VirtualFlow那样。

tableView.skinProperty().addListener(new ChangeListener<Skin>()
{
@Override
public void changed(ObservableValue<? extends Skin> ov, Skin t, Skin t1)
{
if (t1 == null) { return; }

TableViewSkin tvs = (TableViewSkin)t1;
ObservableList<Node> kids = tvs.getChildrenUnmodifiable();

if (kids == null || kids.isEmpty()) { return; }
flow = (VirtualFlow)kids.get(1);
}
});

在您拥有 VirtualFlow 之后,可以听表的ObservableList进行更改并检查以确保所选项目仍在视口(viewport)中。

countries.addListener(new ListChangeListener<Country>()
{
@Override
public void onChanged(ListChangeListener.Change<? extends Country> change)
{
while (change.next())
{
if (change.wasAdded())
{
if (flow == null) { return; }
int first = flow.getFirstVisibleCell().getIndex();
int last = flow.getLastVisibleCell().getIndex();
int selected = tableView.getSelectionModel().getSelectedIndex();

if (selected < first || selected > last)
{
flow.show(selected);
}
}
}
}
});

仍然会有一些簿记工作需要管理。例如,如果您想将焦点放回 table 上。此外,值得注意的是 VirtualFlow不受表格可见矩形的严格限制,因此即使项目刚好在视口(viewport)之外,也可能被视为可见。你可以研究VirtualFlow更多细节。

这是一个 SSCCE。

JavaFXApplication21.java:

package javafxapplication21;

import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class JavaFXApplication21 extends Application
{
@Override
public void start(Stage stage) throws Exception
{
Parent root = FXMLLoader.load(getClass().getResource("Sample.fxml"));

Scene scene = new Scene(root);

stage.setScene(scene);
stage.show();
}

public static void main(String[] args)
{
launch(args);
}
}

示例.fxml:

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<AnchorPane id="AnchorPane" prefHeight="200.0" prefWidth="200.0" xmlns:fx="http://javafx.com/fxml" fx:controller="javafxapplication21.SampleController">
<children>
<ToolBar AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<items>
<Button fx:id="insertBtn" mnemonicParsing="false" text="Insert" />
</items>
</ToolBar>
<TableView fx:id="tableView" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="31.0">
<columns>
<TableColumn prefWidth="100.0" text="Country" fx:id="countryColumn" />
<TableColumn prefWidth="100.0" text="Capital" fx:id="capitalColumn" />
</columns>
</TableView>
</children>
</AnchorPane>

示例 Controller .java:

package javafxapplication21;

import com.sun.javafx.scene.control.skin.TableViewSkin;
import com.sun.javafx.scene.control.skin.VirtualFlow;
import java.net.URL;
import java.util.*;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.*;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;

public class SampleController implements Initializable
{
@FXML private Button insertBtn;
@FXML private TableView<Country> tableView;
@FXML private TableColumn<Country, String> countryColumn;
@FXML private TableColumn<Country, String> capitalColumn;

private VirtualFlow flow;

private ObservableList<Country> countries =
FXCollections.observableArrayList();
private List<Country> insertList = new ArrayList<>();

public SampleController()
{
countries.addAll(new Country("AG", "Buenos Aires"),
new Country("AU", "Vienna"),
new Country("BY", "Minsk"),
new Country("CO", "Bogota"),
new Country("EG", "Cairo"));

insertList.add(new Country("ZI", "Harare"));
insertList.add(new Country("UK", "London"));
insertList.add(new Country("TW", "Taipei"));
}

@Override
public void initialize(URL url, ResourceBundle rb)
{
countryColumn.setCellValueFactory(
new PropertyValueFactory<Country, String>("name"));
capitalColumn.setCellValueFactory(
new PropertyValueFactory<Country, String>("capital"));

tableView.setItems(countries);

tableView.skinProperty().addListener(new ChangeListener<Skin>()
{
@Override
public void changed(ObservableValue<? extends Skin> ov,
Skin t, Skin t1)
{
if (t1 == null) { return; }

TableViewSkin tvs = (TableViewSkin)t1;
ObservableList<Node> kids = tvs.getChildrenUnmodifiable();

if (kids == null || kids.isEmpty()) { return; }

flow = (VirtualFlow)kids.get(1);
}
});

insertBtn.setOnAction(new EventHandler<ActionEvent>()
{
@Override
public void handle(ActionEvent t)
{
if (!insertList.isEmpty())
{
countries.add(2, insertList.get(0));
insertList.remove(0);
}
}
});

countries.addListener(new ListChangeListener<Country>()
{
@Override
public void onChanged(ListChangeListener.Change<? extends Country> change)
{
while (change.next())
{
if (change.wasAdded())
{
if (flow == null) { return; }
int first = flow.getFirstVisibleCell().getIndex();
int last = flow.getLastVisibleCell().getIndex();
int selected = tableView.getSelectionModel().getSelectedIndex();

if (selected < first || selected > last)
{
flow.show(selected);
}
}
}
}
});
}

public class Country
{
private SimpleStringProperty name;
private SimpleStringProperty capital;

public Country(String name, String capital)
{
this.name = new SimpleStringProperty(name);
this.capital = new SimpleStringProperty(capital);
}

public SimpleStringProperty nameProperty() { return name; }
public SimpleStringProperty capitalProperty() { return capital; }
}
}

关于Javafx Tableview 将选定的行保留在当前 View 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17268529/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com