JavaFX: Как правильно раскрасить фон выбранной TableCell? - PullRequest
0 голосов
/ 30 января 2019

Я хочу изменить цвет фона строки на зеленый при выборе строки.Однако, несмотря на то, что выбранная строка изменила цвет, дополнительно неправильная строка также изменила цвет.Я не могу понять, почему ??

Это кодировка JavaFX-программы в Intellij из Windows 10.

TestFXML.java:

public class TestFXML implements Initializable {
    @FXML
    TableView<ItemLog> table;
    @FXML
    TableColumn<ItemLog,String> column1,column2,column4;
    @FXML
    TableColumn<ItemLog,Number> column3;

    @Override
    public void initialize(URL location, ResourceBundle resources) {
        ObservableList<ItemLog> root=FXCollections.observableArrayList();
        root.addAll(
                new ItemLog("E0001","2.5㎟ XLPE", 1.2,"m"),
                new ItemLog("E0002","4㎟ XLPE",1.5,"m"),
                new ItemLog("E0003","6㎟ XLPE",2.0,"m"),
                new ItemLog("E0004","10㎟ XLPE",4.0,"m"),
                new ItemLog("E0005","16㎟ XLPE",6.2,"m"),
                new ItemLog("E0006","25㎟ XLPE",9.1,"m"),
                new ItemLog("E0007","35㎟ XLPE",14.5,"m"),
                new ItemLog("E0008","50㎟ XLPE",20.6,"m"),
                new ItemLog("E0009","70㎟ XLPE",31.2,"m"),
                new ItemLog("E00010","120㎟ XLPE",40.5,"m"),
                new ItemLog("E00011","150㎟ XLPE",55.3,"m"),
                new ItemLog("E00012","185㎟ XLPE",78.8,"m"),
                new ItemLog("E00013","240㎟ XLPE",96.0,"m"),
                new ItemLog("E0101","2.5㎟ PVC", 1.2,"m"),
                new ItemLog("E0102","4㎟ PVC",0.8,"m"),
                new ItemLog("E0103","6㎟ PVC",1.2,"m"),
                new ItemLog("E0104","10㎟ PVC",2.1,"m"),
                new ItemLog("E0105","16㎟ PVC",4.3,"m"),
                new ItemLog("E0106","25㎟ PVC",6.8,"m"),
                new ItemLog("E0107","35㎟ PVC",9.5,"m"),
                new ItemLog("E0108","50㎟ PVC",12.8,"m"),
                new ItemLog("E0109","70㎟ PVC",16.9,"m"),
                new ItemLog("E01010","120㎟ PVC",21.5,"m"),
                new ItemLog("E01011","150㎟ PVC",27.6,"m"),
                new ItemLog("E01012","185㎟ PVC",38.4,"m"),
                new ItemLog("E01013","240㎟ PVC",52.9,"m")
                );
        table.setItems(root);
        column1.setCellValueFactory(param -> param.getValue().code);
        column2.setCellValueFactory(param -> param.getValue().description);
        column3.setCellValueFactory(param -> param.getValue().price);
        column4.setCellValueFactory(param -> param.getValue().unit);
        //To change selected row color into green
        table.getFocusModel().focusedCellProperty().addListener((observable, oldValue, newValue) -> {
            if(newValue.getTableColumn() != null){
                newValue.getTableColumn().setCellFactory(param -> new TableCell(){
                    @Override
                    protected void updateItem(Object item, boolean empty) {
                        super.updateItem(item, empty);
                        if (empty) {
                            setText(null);
                            setGraphic(null);
                        }else{
                            setText(item.toString());
                            if(this.getIndex()==newValue.getRow()){
                                this.getTableRow().setStyle("-fx-background-color:green");
                            }
                        }
                    }
                });
            }
        });
    }
    private class ItemLog {
        StringProperty code=new SimpleStringProperty();
        StringProperty description=new SimpleStringProperty();
        DoubleProperty price=new SimpleDoubleProperty();
        StringProperty unit=new SimpleStringProperty();
        ItemLog(String code, String description, Double price, String unit) {
            this.code.set(code);
            this.description.set(description);
            this.price.set(price);
            this.unit.set(unit);
        }
    }
}

TestFXML.fxml:

<Pane prefHeight="414.0" prefWidth="602.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.TestFXML">
    <children>
       <TableView fx:id="table" maxHeight="1.7976931348623157E308" prefHeight="421.0" prefWidth="602.0">
         <columns>
           <TableColumn fx:id="column1" editable="false" prefWidth="100.0" text="A" />
           <TableColumn fx:id="column2" editable="false" prefWidth="300.0" text="B" />
             <TableColumn fx:id="column3" editable="false" prefWidth="100.0" text="C" />
             <TableColumn fx:id="column4" editable="false" prefWidth="100.0" text="D" />
        </columns>
      </TableView>
    </children>
</Pane>

Я ожидал, когда я выберу 1-ую строку, только 1-я строка изменит цвет на зеленый.Фактический результат - когда я выбрал 1-й ряд, 1-й и 19-й ряды изменили цвет на зеленый.

Ответы [ 2 ]

0 голосов
/ 30 января 2019

В вашем подходе есть 3 проблемы:

  1. Вы никогда не сбрасываете внешний вид ячейки, если ячейка становится пустой или элемент меняется на другой.
  2. TableView обычно не воссоздает ячейки, если cellFactory изменяется.Каждый cellFactory выбирает выделение ячейки на основе сфокусированной ячейки в то время, когда cellFactory создающая ячейку была создана .Даже если ячейки были воссозданы, вы все равно увидите выделенные ячейки в других столбцах, поскольку вы никогда не переключитесь обратно на cellFactory, не выделяя ячейки.
  3. Сфокусированные и выделенные ячейки могут отличаться.

Выполнение этих модификаций намного проще, если вы используете таблицу стилей CSS, поскольку TableCell s присваивается псевдокласс, когда они фокусируются, что позволяет вам определять только стиль фокусированных ячеек, не беспокоясь о cellFactorys:

style.css

.table-cell:selected {
    -fx-background-color: green;
}

fxml

<Pane stylesheets="style.css" prefHeight="414.0" prefWidth="602.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="sample.TestFXML">
    ...
</Pane>

Удалите назначения cellFactory из вашегоJava-код для вышеупомянутого подхода к работе.

Чтобы использовать только стиль TableView таким образом, вы можете, например, добавить класс стиля к TableView и выбрать его на основе класса стиля TableViewНапример,

.my-tableview .table-cell:selected {
    -fx-background-color: green;
}

Также становится намного проще комбинировать различные критерии, например

/* style for selected and hovered cell */
.table-cell:selected:hover {
    -fx-background-color: yellow;
}
0 голосов
/ 30 января 2019

Я получил решение сам.Чтобы изменить это:

if(this.getIndex()==newValue.getRow()){
    this.getTableRow().setStyle("-fx-background-color:green");
}

в:

if(this.getIndex()==newValue.getRow()){
    this.getTableRow().setStyle("-fx-background-color:green");
}else{
    this.getTableRow().setStyle("");
}
...