将两个表视图绑定在一起,但是由于内容行高不同而导致索引不匹配

时间:2019-05-31 14:15:08

标签: java javafx tableview

我正在使用javafx应用程序,并且需要在tableview中使用固定列,这就是为什么我将两个表绑定在一起并使其正常工作的原因,但是一个表只有一个列仅包含索引,而另一个表则具有多个列和许多数据。

如果任何行只有一行数据,则两个表的行具有相同的高度,但在不同情况下,行有多行,则索引不匹配。我正在分享我的测试代码:

 screenshot of current issue

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Orientation;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ScrollBar;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableRow;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;

/**
 *
 * @author nitin
 */
public class NewClass extends Application {

@Override
public void start(Stage primaryStage) throws Exception {
    primaryStage.setTitle("Fix Column");
    Scene scene = new Scene(getView());
    primaryStage.setScene(scene);
    primaryStage.show();
}

private BorderPane getView() {
    BorderPane borderPane = new BorderPane();
    List<Student> students = Student.getList();

    TableView<Student> fixedColumnTable = new TableView<>();
    fixedColumnTable.setItems(FXCollections.observableArrayList(students));
    TableColumn<Student, Number> possionNumber = new TableColumn<>("#");
    possionNumber.setCellValueFactory(value -> value.getValue().getIdProperty());
    fixedColumnTable.getColumns().add(possionNumber);
    fixedColumnTable.setColumnResizePolicy(fixedColumnTable.CONSTRAINED_RESIZE_POLICY);
    fixedColumnTable.setPrefWidth(60);
    VBox vBox = new VBox();
    vBox.getChildren().add(fixedColumnTable);
    VBox.setVgrow(fixedColumnTable, Priority.ALWAYS);
    HBox.setHgrow(fixedColumnTable, Priority.ALWAYS);
    borderPane.setLeft(vBox);
    Region region = new Region();

    TableView<Student> table = new TableView<>();
    table.setItems(FXCollections.observableArrayList(students));

    table.setRowFactory(tv -> new TableRow<Student>() {
        @Override
        public void updateItem(Student item, boolean empty) {
            setRowHight(fixedColumnTable, table);
        }
    });

    TableColumn<Student, String> nameCol = new TableColumn<>("Name");
    nameCol.setCellValueFactory(value -> value.getValue().getNameProperty());

    TableColumn<Student, Number> ageCol = new TableColumn<>("Age");
    ageCol.setCellValueFactory(value -> value.getValue().getAgeProperty());

    TableColumn<Student, String> courseCol = new TableColumn<>("Course");
    courseCol.setCellValueFactory(value -> value.getValue().getCourseProperty());

    table.getColumns().addAll(nameCol, ageCol, courseCol);
    borderPane.setCenter(table);

    Platform.runLater(() -> {
        ScrollBar fixColtableVerticalBar = (ScrollBar) fixedColumnTable.lookup(".scroll-bar:vertical");
        fixColtableVerticalBar.setPrefWidth(0);
        fixColtableVerticalBar.setMaxWidth(0);
        fixColtableVerticalBar.setVisible(false);
        fixColtableVerticalBar.setOpacity(1);
        ScrollBar tableVerticalBar = (ScrollBar) table.lookup(".scroll-bar:vertical");
        tableVerticalBar.valueProperty().bindBidirectional(fixColtableVerticalBar.valueProperty());

        ObservableList<Node> list = vBox.getChildren();
        Set<Node> scrollBars = table.lookupAll(".scroll-bar");
        Optional<Node> horizontalScrollBar = scrollBars.stream()
                .filter(node
                        -> ((ScrollBar) node).getOrientation().equals(Orientation.HORIZONTAL))
                .findAny();
        horizontalScrollBar.ifPresent(node
                -> node.visibleProperty().addListener((observable, oldValue, newValue) -> {
                    if (newValue && !list.contains(region)) {
                        list.add(region);
                        Platform.runLater(() -> region.setMinHeight(((ScrollBar) node).getHeight()));
                    } else {
                        list.remove(region);
                    }
                })
        );

    });

    return borderPane;
}

private void setRowHight(TableView t1, TableView t2) {
    List<Node> leftTableRows = new ArrayList(t1.lookupAll(".table-row-cell"));
    List<Node> rightTableRows = new ArrayList(t2.lookupAll(".table-row-cell"));
    if (leftTableRows.size() == rightTableRows.size()) {
        for (int i = 0; i < leftTableRows.size(); i++) {
            TableRow leftTableRow = (TableRow) leftTableRows.get(i);
            TableRow leftRow = (TableRow) leftTableRows.get(i);
            TableRow rightRow = (TableRow) rightTableRows.get(i);
            leftRow.setPrefHeight(rightRow.getHeight());
        }
    }
}

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

class Student {

private int id;
private String name;
private int age;
private String course;

public Student(int id, String name, int age, String course) {
    this.id = id;
    this.name = name;
    this.age = age;
    this.course = course;
}

public int getId() {
    return id;
}

public IntegerProperty getIdProperty() {
    return new SimpleIntegerProperty(id);
}

public String getName() {
    return name;
}

public StringProperty getNameProperty() {
    return name != null ? new SimpleStringProperty(name) : null;
}

public int getAge() {
    return age;
}

public IntegerProperty getAgeProperty() {
    return new SimpleIntegerProperty(age);
}

public String getCourse() {
    return course;
}

public StringProperty getCourseProperty() {
    return course != null ? new SimpleStringProperty(course) : null;
}

public static List<Student> getList() {
    List<Student> list = new ArrayList<>();
    list.add(new Student(0, "A", 18, "Java \n sfsf\n sdfsdf\ndsfsfsd : "));
    for (int i = 1; i <= 100; i++) {
        list.add(new Student(i, "A" + i, 18, "Java : " + i));
    }
    return list;
}
}

1 个答案:

答案 0 :(得分:2)

您需要获取每个表的每一行。然后根据正确的高度设置左边的高度。

private void setRowHight(TableView t1, TableView t2) {
    List<Node> leftTableRows = new ArrayList(t1.lookupAll(".table-row-cell"));
    List<Node> rightTableRows = new ArrayList(t2.lookupAll(".table-row-cell"));

    for (Node tableRow : rightTableRows) {
        TableRow<?> r = (TableRow<?>) tableRow;
        for (Node tableRowLeft : leftTableRows) {
            TableRow<?> l = (TableRow<?>) tableRowLeft;
                if (r.getIndex() == l.getIndex()) {
                    l.setPrefHeight(r.getHeight());
                    break;
                }
            }
    }    
}

enter image description here