我正在使用javafx应用程序,并且需要在tableview中使用固定列,这就是为什么我将两个表绑定在一起并使其正常工作的原因,但是一个表只有一个列仅包含索引,而另一个表则具有多个列和许多数据。
如果任何行只有一行数据,则两个表的行具有相同的高度,但在不同情况下,行有多行,则索引不匹配。我正在分享我的测试代码:
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;
}
}
答案 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;
}
}
}
}