当前位置: 首页 > 知识库问答 >
问题:

JavaFX TableView不更新UI

姜德容
2023-03-14

我有一个表视图

以下是我的表格创建:

pattern= new TableView<>(mainApp.getItemList());

    for (ObservableList<Item> row : pattern.getItems()) {

        for (int i= pattern.getColumns().size(); i<row.size(); i++){
            final int columnIndex = i ;

            TableColumn<ObservableList<Item>, Color> column = new TableColumn<>();

            column.setCellValueFactory( rowData -> 
                    rowData.getValue()
                    .get(columnIndex).displayColorProperty()); // the Item for this cell

            column.setCellFactory(col -> {
                ItemCell cell = new ItemCell();

                cell.setOnMouseEntered( e -> {
                    if (cell.getItem() != null) {
                        @SuppressWarnings("unchecked")
                        ObservableList<Item> stitchRow = 
                        (ObservableList<Item>) cell.getTableRow().getItem();
                        mainApp.getRLController().setItemLabel(itemRow.get(columnIndex).toString());
                    }
                });

                cell.setOnMouseExited( e -> {
                    mainApp.getRLController().setItemLabel(null);
                });

                cell.setOnMouseClicked((MouseEvent e) -> {
                    Item newItem = mainApp.getTBController().getSelectedItem();
                    if (e.getButton() == MouseButton.PRIMARY && newItem != null) {

                        ObservableList<Item> itemRow = 
                                (ObservableList<Item>) cell.getTableRow().getItem();
                        itemRow.set(columnIndex, newItem);  
                        mainApp.getRLController().setItemLabel(itemRow.get(columnIndex).toString());
                    }
                });

                return cell; 
                });

            column.setMinWidth(7);
            column.setPrefWidth(7);
            column.setMaxWidth(7);
            pattern.getColumns().add(column);
        }
    }
    pattern.setFixedCellSize(7);
    pattern.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);`

我的自定义细胞工厂代码:

public class ItemCell extends TableCell<ObservableList<Item>, Color> {

@Override 
protected void updateItem(Color color, boolean empty) {
    super.updateItem(color, empty); 

    if (empty || color == null) {
        setText(null);
        setStyle(null);
    } else {

        int r = (int) (color.getRed() * 255);
        int g = (int) (color.getGreen() * 255);
        int b = (int) (color.getBlue() * 255);

        this.setStyle("-fx-background-color: rgb(" + r + "," + g + "," + b + ");" 
             + "-fx-border-color: black; -fx-table-cell-border-color: black;");
    }
    }
}

共有1个答案

司空镜
2023-03-14

基本问题是,您正在更改的对象(作为表示行的列表元素的项)不是单元格正在观察更改的属性(属于该项的displayColorProperty())。您需要安排更改单元格正在观察的属性的值。

三种可能的解决方案:

如果可能,只需更改单元格显示的项目的显示颜色(以及其他数据)。一、 e。

            cell.setOnMouseClicked((MouseEvent e) -> {
                if (e.getButton() == MouseButton.PRIMARY && newItem != null) {

                    ObservableList<Item> itemRow = 
                            (ObservableList<Item>) cell.getTableRow().getItem();
                    Item item = itemRow.get(columnIndex);
                    item.setDisplayColor(...);
                    item.set...(...);  
                    // ...
                    mainApp.getRLController().setItemLabel(item.toString());
                }
            });

或者,替换整行:

            cell.setOnMouseClicked((MouseEvent e) -> {
                Item newItem = mainApp.getTBController().getSelectedItem();
                if (e.getButton() == MouseButton.PRIMARY && newItem != null) {

                    ObservableList<Item> itemRow = 
                            (ObservableList<Item>) cell.getTableRow().getItem();
                    ObservableList<Item> newRow = FXCollections.observableArrayList(itemRow);
                    newRow.set(columnIndex, newItem);  
                    pattern.getItems().set(cell.getTableRow().getIndex(), newRow);
                    mainApp.getRLController().setItemLabel(newRow.get(columnIndex).toString());
                }
            });

否则,您可以将您的表设置为TableView

这是使用第三种技术的完整示例:

import javafx.application.Application;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Scene;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.layout.BorderPane;
import javafx.scene.paint.Color;
import javafx.stage.Stage;

public class ColorTableExample extends Application {

    @Override
    public void start(Stage primaryStage) {
        TableView<ObservableList<ObjectProperty<Item>>> table = new TableView<>();


        int NUM_ROWS = 20 ;
        int NUM_COLS = 15 ;

        ObservableList<ObservableList<ObjectProperty<Item>>> data = table.getItems() ;

        for (int y = 0 ; y < NUM_ROWS; y++) {

            ObservableList<ObjectProperty<Item>> row = FXCollections.observableArrayList();
            data.add(row);

            double saturation = (1.0 * y) / NUM_ROWS ;
            for (int x = 0 ; x < NUM_COLS; x++) {
                double hue = x * 360.0 / NUM_COLS ;

                Color color = Color.hsb(hue, saturation, 1.0);
                row.add(new SimpleObjectProperty<>(new Item(color)));
            }

        }

        for (ObservableList<ObjectProperty<Item>> row : table.getItems()) {
            for (int i = table.getColumns().size() ; i < row.size(); i++) {
                int columnIndex = i ;
                TableColumn<ObservableList<ObjectProperty<Item>>, Item> column = new TableColumn<>(Integer.toString(i+1));
                column.setCellValueFactory(rowData -> rowData.getValue().get(columnIndex));
                column.setCellFactory(c -> {
                    TableCell<ObservableList<ObjectProperty<Item>>, Item> cell = new TableCell<ObservableList<ObjectProperty<Item>>, Item>() {
                        @Override
                        public void updateItem(Item item, boolean empty) {
                            super.updateItem(item, empty);
                            if (empty) {
                                setStyle("");
                            } else {
                                Color color = item.getDisplayColor() ;
                                int r = (int) (color.getRed() * 255) ;
                                int g = (int) (color.getGreen() * 255) ;
                                int b = (int) (color.getBlue() * 255) ;
                                String style = String.format(
                                        "-fx-background-color: rgb(%d, %d, %d);"
                                        + "-fx-border-color: black ;"
                                        + "-fx-table-cell-border-color: black ;"
                                        ,r, g, b);
                                setStyle(style);
                            }
                        }
                    };

                    cell.setOnMousePressed(evt -> {
                        if (! cell.isEmpty()) {
                            ObservableList<ObjectProperty<Item>> rowData = (ObservableList<ObjectProperty<Item>>) cell.getTableRow().getItem();
                            Color currentColor = cell.getItem().getDisplayColor();
                            double newHue = ( currentColor.getHue() + 15 ) % 360 ;
                            Color newColor = Color.hsb(newHue, currentColor.getSaturation(), currentColor.getBrightness());
                            rowData.get(columnIndex).set(new Item(newColor));
                        }
                    });

                    return cell ;
                });
                table.getColumns().add(column);
            }
        }

        BorderPane root = new BorderPane(table, null, null, null, null);
        primaryStage.setScene(new Scene(root, 600, 400));
        primaryStage.show();
    }

    public static class Item {
        private final ObjectProperty<Color> displayColor = new SimpleObjectProperty<>() ;

        public Item(Color color) {
            this.displayColorProperty().set(color);
        }

        public final ObjectProperty<Color> displayColorProperty() {
            return this.displayColor;
        }

        public final javafx.scene.paint.Color getDisplayColor() {
            return this.displayColorProperty().get();
        }

        public final void setDisplayColor(final javafx.scene.paint.Color displayColor) {
            this.displayColorProperty().set(displayColor);
        }


    }

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

(在某些时候,重构所有内容可能会更容易,这样您就有一个实际的类来表示表中的每一行,而不是使用列表。)

使用列表的提取器也可能有一个巧妙的解决方法,但我无法做到这一点。

 类似资料:
  • 我创建了一个TableView,其中包含一个复选框列(isSelected)和三个信息列(姓名、姓氏、职务)。我想根据用户信息禁用一些复选框。例如,如果用户名为“Peter”,则Peter旁边的复选框将被禁用。但我不能。以下是我的一些代码: 人JAVA 控制器。JAVA

  • 我的JSF页面是这样的,

  • 我有一个大 gui 的 JList,我删除了所有其他不相关的代码。我可以初始化列表,但在使用按钮时无法从中添加/删除项目。我读到的所有内容都说要使用DefaultListModel。然后,当您重新初始化列表时,它将自动更新列表。 我也尝试重新聚焦并重新粉刷面板和框架,但这也不起作用。

  • 我找到了更新数据的示例,但它使用了DefaultTableModel。当我创建自己的TableModel和自己的data类时,当我将数据添加到JTable中时,它不会更新。 有我的桌子模型: 当我添加了任何信息,但它没有更新。在JTable中,我必须把这个方法放在哪里来进行正确的数据更新?

  • 问题内容: 我正在通过ng-repeat循环渲染数据。而且我希望它在更新数组时进行更新。从我阅读的内容来看,这应该会自动发生,但是这是行不通的。那我在做什么错? 的HTML: 控制器(此功能通过ng-click在按钮上触发): Console.log显示该数组已正确更新,但是我视图中的表未更改。我不知道我在做什么错。 问题答案: 那是因为您在method中更改了数组引用。 为了避免这种情况,我们使

  • 我现在迷路了。