gpt4 book ai didi

user-interface - 如何在JavaFX的ListView中获取项目的位置?

转载 作者:行者123 更新时间:2023-12-04 06:53:08 26 4
gpt4 key购买 nike

如果我在 JavaFX 中创建一个 ListView,如下所示:

ObservableList<String> elements = FXCollections.observableArrayList("John", "Doe");
ListView<String> lView = new ListView<String>(elements);

我想要做的是从 ListView 中一行的末尾开始画一条线,从“约翰”说

为此,我需要“John”行的位置(x,y)。是否可以获取位置?

更新

这是我使用 Swing 和 Piccolo2D 获得的示例界面。但是,使用该库是痛苦的。我想知道我是否可以在 JavaFX 中做同样的事情

enter image description here

最佳答案

这是可能的,但它可能不像您希望的那样直接。为了确定特定 Cell 的布局坐标内ListView (或 TableView/TreeView )您需要访问该特定 Cell目的。最好的方法(也可能是 JavaFX 2.2 中唯一的方法)是为容器提供自定义 CellCellFactory暴露每个 Cell .你如何曝光 Cell取决于您绘制线条的触发器。

根据您的插图,您需要访问每个单元格一次 ListView s 已填充。您可以使用 List<ListCell<String>> 执行此操作CellFactory 中的字段.我会在这里提到一个关于 ListCell 的警告s。 ListViewSkin将重用 Cell尽可能。这意味着,如果您要尝试填充和连接最终滚动的列表,那么将行保持在正确的位置将更加困难。我建议尝试确保您的所有列表项都适合屏幕。

下面是一个示例,注释中有一些注释。请注意获取正确的坐标以绘制您的 Line可能需要计算你的 SceneGraph 的偏移量,而我在这个例子中没有这样做。

package listviewcellposition;

import java.util.ArrayList;
import java.util.List;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.*;
import javafx.scene.paint.Color;
import javafx.scene.shape.Line;
import javafx.stage.Stage;
import javafx.util.Callback;

public class ListViewCellPosition extends Application {

// CustomCellFactory for creating CustomCells
public class CustomCellFactory implements
Callback<ListView<String>, ListCell<String>> {

List<ListCell<String>> allCells = new ArrayList<>();

@Override
public ListCell<String> call(final ListView<String> p) {
final CustomCell cell = new CustomCell();
allCells.add(cell);
return cell;
}

public List<ListCell<String>> getAllCells() {
return allCells;
}
}

// CustomCell is where the exposure occurs. Here, it's based on the
// Cell being selected in the ListView. You could choose a different
// trigger here but you'll need to explore.
public class CustomCell extends ListCell<String> {
// General display stuff
@Override
protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (empty) {
setText(null);
setGraphic(null);
} else {
setText(item == null ? "" : item);
setGraphic(null);
}
}
}

@Override
public void start(Stage primaryStage) {
// This pane will contain the lines after they are created.
// I set it into an AnchorPane to avoid having to deal with
// resizing.
Pane linePane = new Pane();
AnchorPane pane = new AnchorPane();
pane.setPrefSize(100, 250);
AnchorPane.setBottomAnchor(linePane, 0.0);
AnchorPane.setLeftAnchor(linePane, 0.0);
AnchorPane.setRightAnchor(linePane, 0.0);
AnchorPane.setTopAnchor(linePane, 0.0);
pane.getChildren().add(linePane);

ListView<String> lView = new ListView<>();
lView.setPrefSize(100, 250);
CustomCellFactory lCellFactory = new CustomCellFactory();
lView.setCellFactory(lCellFactory);

ListView<String> rView = new ListView<>();
rView.setPrefSize(100, 250);
CustomCellFactory rCellFactory = new CustomCellFactory();
rView.setCellFactory(rCellFactory);

lView.getItems().addAll("Bill", "Doctor", "Steve", "Joanne");
rView.getItems().addAll("Seuss", "Rowling", "King", "Shakespeare");

HBox root = new HBox();
root.getChildren().addAll(lView, pane, rView);

Scene scene = new Scene(root, 300, 250);
primaryStage.setScene(scene);
primaryStage.show();

connectCells(lCellFactory, "Bill", rCellFactory, "Shakespeare", linePane);
connectCells(lCellFactory, "Doctor", rCellFactory, "Seuss", linePane);
connectCells(lCellFactory, "Steve", rCellFactory, "King", linePane);
connectCells(lCellFactory, "Joanne", rCellFactory, "Rowling", linePane);
}

// Looks up the ListCell<> for each String and creates a Line
// with the coordinates from each Cell. The calculation is very
// contrived because I know that all the components have the same
// x-coordinate. You'll need more complicated calculations if your
// containers are not aligned this way.
private void connectCells(CustomCellFactory lCellFactory, String lVal,
CustomCellFactory rCellFactory, String rVal, Pane linePane) {

List<ListCell<String>> lList = lCellFactory.getAllCells();
ListCell<String> lCell = null;

for (ListCell<String> lc : lList) {
if (lc.getItem() != null && lc.getItem().equals(lVal)) {
lCell = lc;
break;
}
}

List<ListCell<String>> rList = rCellFactory.getAllCells();
ListCell<String> rCell = null;

for (ListCell<String> rc : rList) {
if (rc.getItem() != null && rc.getItem().equals(rVal)) {
rCell = rc;
break;
}
}

if (lCell != null && rCell != null) {
double startY = lCell.getLayoutY() +
(lCell.getBoundsInLocal().getHeight() / 2);
double endY = rCell.getLayoutY() +
(rCell.getBoundsInLocal().getHeight() / 2);

Line line = new Line(0, startY,
linePane.getBoundsInParent().getWidth(), endY);
line.setStrokeWidth(2);
line.setStroke(Color.BLACK);

linePane.getChildren().add(line);
}
}

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

关于user-interface - 如何在JavaFX的ListView中获取项目的位置?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18965871/

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