我需要为每个表格单元显示不同的工具提示

时间:2016-03-27 16:52:40

标签: javafx-8

请看这个 This is what I want to see... I mean the tool tip At run time I get this error message for each row that is being loaded. 工具提示文本位于一个对象中,并由thisRow.getCourseTootip(i)检索;

表中的列数各不相同,我创建它们并通过代码将它们添加到表视图中。

        for (int courseNo = 0; courseNo < numberOfCourses; courseNo++) {
        String colName = getASemesterCourse(thisSemester, courseNo).getCourseID();
        TableColumn<AResultRow, String> thisColumn = new TableColumn<>(colName);
        thisColumn.setPrefWidth(80);
        thisColumn.setStyle("-fx-alignment: CENTER; font-weight:bold;");
        String str = TableRows.get(1).getGrade(courseNo);
        final int i = courseNo;

        thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(i));
        thisColumn.setCellFactory(new Callback<TableColumn<AResultRow, String>, TableCell<AResultRow, String>>() {

            public TableCell<AResultRow, String> call(TableColumn<AResultRow, String> column) {
                return new TableCell<AResultRow, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (!empty) {
                            setText(item);
                            AResultRow thisRow = new AResultRow();
                            thisRow = getTableView().getItems().get(getTableRow().getIndex());
                            final Tooltip tip= new Tooltip();
                            tip.setText(thisRow.getCourseTootip(i));
                            setTooltip(tip);
                            tip.setStyle("-fx-background-color: pink; -fx-text-fill: black;  -fx-font: normal normal 12pt \"Times New Roman\"");

                        }
                    }
                };
            }
        });

        boolean retVal = thisTable.getColumns().addAll(thisColumn);
    }

错误是

Exception in thread "JavaFX Application Thread" java.lang.NullPointerException
at victoriairene.TheMainFXMLController$1$1.updateItem(TheMainFXMLController.java:434)
at victoriairene.TheMainFXMLController$1$1.updateItem(TheMainFXMLController.java:427)

第434行是

thisRow = getTableView().getItems().get(getTableRow().getIndex());

此单元格工具提示的文本来自thisRow.getCourseTootip(i)。

有人能告诉我,我的代码有什么问题吗?哪个对象为null?如果它为null,那么如何获取每行的错误消息,我如何才能看到正确的Tooltip文本?

我一直在为此苦苦挣扎一整天。

请提前帮助和谢谢。

根据Kleopatra的要求,我附上了整个创建表函数。

    public void createTableForThisSemester(int thisSemester, int numberOfCourses, javafx.collections.ObservableList<AResultRow> TableRows) {

    TableView<AResultRow> thisTable = new TableView<>();
    thisTable.setContextMenu(contextMenu);

    TableColumn<AResultRow, String> tcolRollNo = new TableColumn<>("Roll Number");
    tcolRollNo.setEditable(false);
    tcolRollNo.setPrefWidth(120);

    TableColumn<AResultRow, String> tcolName = new TableColumn<>("Student Name");
    tcolName.setEditable(false);
    tcolName.setPrefWidth(350);

    tcolRollNo.setCellValueFactory(cellData -> cellData.getValue().StudentIDProperty());
    tcolName.setCellValueFactory(cellData -> cellData.getValue().StudentNameProperty());
    boolean xyz = thisTable.getColumns().addAll(tcolRollNo, tcolName);


    //       TableColumn[] courseColumn = new TableColumn[numberOfCourses];
    for (int courseNo = 0; courseNo < numberOfCourses; courseNo++) {
        String colName = getASemesterCourse(thisSemester, courseNo).getCourseID();
        TableColumn<AResultRow, String> thisColumn = new TableColumn<>(colName);
        thisColumn.setPrefWidth(80);
        thisColumn.setStyle("-fx-alignment: CENTER; font-weight:bold;");
        String str = TableRows.get(1).getGrade(courseNo);
        final int i = courseNo;

        thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(i));
        thisColumn.setCellFactory(new Callback<TableColumn<AResultRow, String>, TableCell<AResultRow, String>>() {

            public TableCell<AResultRow, String> call(TableColumn<AResultRow, String> column) {
                return new TableCell<AResultRow, String>() {
                    @Override
                    protected void updateItem(String item, boolean empty) {
                        super.updateItem(item, empty);
                        if (!empty) {
                            setText(item);
                            AResultRow thisRow = new AResultRow();
                            thisRow = getTableView().getItems().get(getTableRow().getIndex());
                            final Tooltip tip= new Tooltip();
                            tip.setText(thisRow.getCourseTootip(i));
                            setTooltip(tip);
                            tip.setStyle("-fx-background-color: pink; -fx-text-fill: black;  -fx-font: normal normal 12pt \"Times New Roman\"");

                        }
                    }
                };
            }
        });

        boolean retVal = thisTable.getColumns().addAll(thisColumn);
    }

// System.out.println(“表格中的行数#”+“thisSemester +”] =“+ TableRows.size());

    TableColumn<AResultRow, String> tcolGPA = new TableColumn<>("GPA");
    tcolGPA.setEditable(false);
    tcolGPA.setPrefWidth(80);
    tcolGPA.setStyle("-fx-alignment: CENTER; font-weight:bold;");
    tcolGPA.setCellValueFactory(cellData -> cellData.getValue().returnStringGPA());
    boolean retVal = thisTable.getColumns().addAll(tcolGPA);

    thisTable.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
    thisTable.setItems(TableRows);
    thisTable.getSelectionModel().selectedItemProperty().addListener((observableValue, oldValue, newValue) -> {
        //Check whether item is selected and set value of selected item to Label
        if (thisTable.getSelectionModel().getSelectedItem() == null) {
            gRollNumber = null;
            gStudentName = null;
        } else {
            gRollNumber = newValue.getStudentID();
            gStudentName = newValue.getStudentName();
        }
    });
    ScrollPane thisScrollPane = new ScrollPane();
    thisScrollPane.setFitToWidth(true);
    thisScrollPane.setFitToHeight(true);
    thisScrollPane.setMinHeight((theDetails.getHeight() - 25));
    thisScrollPane.setMaxHeight((theDetails.getHeight() - 25));
    thisScrollPane.setMinWidth((theDetails.getWidth() - 25));
    thisScrollPane.setHbarPolicy(ScrollPane.ScrollBarPolicy.ALWAYS);
    Tab thisTab = tabs.getTabs().get(thisSemester);
    thisTab.setContent(thisScrollPane);

    thisScrollPane.setContent(thisTable);
}
  1. 我再次重复这个等级 - 请原谅。
    1. 表视图与名为ATableRows的可观察列表相关联,该列表是ATableRow类。
    2. ATableRow包含多个成员,其中一个是ACourseResult类的数组。
    3. 在我检索工具提示的文本之前,我需要知道ROW编号和数组索引(实际上是该Cell的表列编号)。
  2. 代码是有效的......除了空指针的运行时错误。我仍然不明白CellFactory和CellValueFactories的作用。对于那个很抱歉。甲骨文的文件没有说明他们做了什么......

    当我在这时...我想告诉你我的TABLE是只读的。我必须使用Observable List吗?我不能通过直接为每个单元格设置值(只是好奇心)来做到这一点。

    如果我的问题看起来很笨,请提前致谢并抱歉。

    感谢JAMES我的问题已经解决了....我正在为其他人附上修改后的代码。

            for (int courseNo = 0; courseNo < numberOfCourses; courseNo++) {
            String colName = getASemesterCourse(thisSemester, courseNo).getCourseID();
            TableColumn<AResultRow, String> thisColumn = new TableColumn<>(colName);
            thisColumn.setPrefWidth(80);
            thisColumn.setStyle("-fx-alignment: CENTER; font-weight:bold;");
            String str = TableRows.get(1).getGrade(courseNo);
            final int i = courseNo;
    
            thisColumn.setCellValueFactory(cellData -> cellData.getValue().courseGradeProperty(i));
            thisColumn.setCellFactory(new Callback<TableColumn<AResultRow, String>, TableCell<AResultRow, String>>() {
    
                public TableCell<AResultRow, String> call(TableColumn<AResultRow, String> column) {
                    return new TableCell<AResultRow, String>() {
                        @Override
                        protected void updateItem(String item, boolean empty) {
                            super.updateItem(item, empty);
                            if (!empty) {
                                setText(item);
                                AResultRow thisRow = new AResultRow();
                                final int k = this.getIndex(); **// These are the changes suggested by James**
                                thisRow = getTableView().getItems().get(k); ***// These are the changes suggested by James***
    

    // thisRow = getTableView()。getItems()。get(getTableRow()。getIndex()); &lt; - 这是旧代码注释掉的。                                 final Tooltip tip = new Tooltip();                                 tip.setText(thisRow.getCourseTootip(I));                                 setTooltip(尖端);                                 tip.setStyle(“ - fx-background-color:pink; -fx-text-fill:black; -fx-font:normal normal 12pt \”Times New Roman \“”);

                            }
                        }
                    };
                }
            });
    
            boolean retVal = thisTable.getColumns().addAll(thisColumn);
        }
    

1 个答案:

答案 0 :(得分:0)

问题的快速和错误答案是指出TableCell有一个getTableRow()方法,它将为您提供行数据,而无需通过行索引查找基础数据。

从技术上讲,在调用updateItem()方法时,您应该为TableCell提供独立工作所需的所有信息。这将意味着重构数据模型,使得表格单元格具有包含单元格的显示内容和工具提示中的文本的结构。似乎AResultRow数据结构有两个相关的列表,一个列表包含单元格中的任何显示,另一个列表包含任何进入工具提示的列表。我的建议是重构它,这样它就是一个包含两个数据元素的对象的列表。一旦你这样做,表结构的其余部分变得微不足道。这是一个有效的例子:

public class SampleTable extends Application {

private BorderPane testPane;

class TestPane extends BorderPane {

    public TestPane(List<DataModel> dataItems) {
        TableView<DataModel> tableView = new TableView<DataModel>();
        setCenter(tableView);
        TableColumn<DataModel, ClassInfo> column1 = new TableColumn<DataModel, ClassInfo>("column 1");
        TableColumn<DataModel, ClassInfo> column2 = new TableColumn<DataModel, ClassInfo>("column 2");
        column1.setCellValueFactory(new PropertyValueFactory<DataModel, ClassInfo>("column1Data"));
        column2.setCellValueFactory(new PropertyValueFactory<DataModel, ClassInfo>("column2Data"));
        column1.setCellFactory(column -> new CustomTableCell());
        column2.setCellFactory(column -> new CustomTableCell());
        tableView.getColumns().addAll(column1, column2);
        tableView.setItems(FXCollections.observableList(dataItems));
    }
}

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

public class CustomTableCell extends TableCell<DataModel, ClassInfo> {
    @Override
    protected void updateItem(ClassInfo item, boolean empty) {
        super.updateItem(item, empty);
        if (!empty) {
            if (item != null) {
                setText(item.getName());
                setTooltip(new Tooltip(item.getDescription()));
            }
        }
    }
}

@Override
public void start(Stage primaryStage) {
    primaryStage.setTitle("Task Progress Tester");
    List<DataModel> dataItems = new ArrayList<DataModel>();
    DataModel row1Data = new DataModel();
    row1Data.setColumn1Data(new ClassInfo("row1Col1Name", "This is the description for Row1, Column 1"));
    row1Data.setColumn2Data(new ClassInfo("row1Col2Name", "This is the description for Row1, Column 2"));
    dataItems.add(row1Data);
    DataModel row2Data = new DataModel();
    row2Data.setColumn1Data(new ClassInfo("row2Col1Name", "This is the description for Row2, Column 1"));
    row2Data.setColumn2Data(new ClassInfo("row2Col2Name", "This is the description for Row2, Column 2"));
    dataItems.add(row2Data);
    testPane = new TestPane(dataItems);
    primaryStage.setScene(new Scene(testPane, 300, 250));
    primaryStage.show();
}

public class DataModel {
    private ObjectProperty<ClassInfo> column1Data = new SimpleObjectProperty<ClassInfo>();
    private ObjectProperty<ClassInfo> column2Data = new SimpleObjectProperty<ClassInfo>();

    public void setColumn2Data(ClassInfo newValue) {
        column2Data.set(newValue);
    }

    public void setColumn1Data(ClassInfo newValue) {
        column1Data.set(newValue);
    }

    public ObjectProperty<ClassInfo> column1DataProperty() {
        return column1Data;
    }
}

public class ClassInfo {
    private String name;
    private String description;

    public ClassInfo(String name, String description) {
        this.setName(name);
        this.setDescription(description);
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }
}

}