JavaFx列表查看列表单元格的着色

时间:2017-07-12 21:30:04

标签: listview user-interface javafx listcellrenderer

我有一个标签的列表视图,我想在运行时为列表单元格着色。问题是我想用不仅是Label的背景颜色填充整个Cell。有没有办法在Java / CSS中做到这一点?

2 个答案:

答案 0 :(得分:4)

了解ListView单元格着色的动态特性

通常情况下,内部细胞颜色会根据许多因素而变化:

  1. 单元格是奇数行还是偶数行(偶数行的背景较浅)。
  2. 是否选中该行。
  3. 根据控件是否具有焦点,所选行具有不同的颜色(焦点选定的行为蓝色,未聚焦的选定行为灰色)。
  4. 因为单元格颜色可以根据状态而改变,所以在为单元格设置自定义着色时,需要决定是否要保留此行为。

    示例解决方案

    这是一个将单元格颜色设置为淡绿色的示例,具体取决于列表项是否与条件匹配(在这种情况下,为了测试目的而硬编码为以字母“J”开头的名称)。

    sample

    import javafx.application.Application;
    import javafx.collections.*;
    import javafx.geometry.Insets;
    import javafx.scene.Scene;
    import javafx.scene.control.*;
    import javafx.scene.layout.VBox;
    import javafx.stage.Stage;
    import javafx.util.Callback;
    
    public class ColoredList extends Application {
        private static final ObservableList<String> data = FXCollections.observableArrayList(
                "Jill",
                "Jack",
                "Tom",
                "Harry",
                "Jenney"
        );
    
        private static final String DEFAULT_CONTROL_INNER_BACKGROUND = "derive(-fx-base,80%)";
        private static final String HIGHLIGHTED_CONTROL_INNER_BACKGROUND = "derive(palegreen, 50%)";
    
        @Override
        public void start(Stage stage) throws Exception {
            ListView<String> listView = new ListView<>(data);
            listView.setCellFactory(new Callback<ListView<String>, ListCell<String>>() {
                @Override
                public ListCell<String> call(ListView<String> param) {
                    return new ListCell<String>() {
                        @Override
                        protected void updateItem(String item, boolean empty) {
                            super.updateItem(item, empty);
    
                            if (item == null || empty) {
                                setText(null);
                                setStyle("-fx-control-inner-background: " + DEFAULT_CONTROL_INNER_BACKGROUND + ";");
                            } else {
                                setText(item);
                                if (item.startsWith("J")) {
                                    setStyle("-fx-control-inner-background: " + HIGHLIGHTED_CONTROL_INNER_BACKGROUND + ";");
                                } else {
                                    setStyle("-fx-control-inner-background: " + DEFAULT_CONTROL_INNER_BACKGROUND + ";");
                                }
                            }
                        }
                    };
                }
            });
    
            VBox layout = new VBox(listView);
            layout.setPadding(new Insets(10));
    
            stage.setScene(new Scene(layout));
            stage.show();
        }
    
        public static void main(String[] args) {
            launch(ColoredList.class);
        }
    }
    

    有些注意事项:

    1. 自定义单元格渲染是通过ListView的自定义单元格工厂完成的。
    2. 单元工厂返回的单元格,根据单元格状态设置-fx-control-inner-background查找的CSS颜色。如果您不知道查找的颜色是什么,请在JavaFX CSS reference guide中查找并查看Java安装附带的jfxrt.jar文件中的modena.css文件。
    3. 默认的单元格渲染机制会使ListView中的偶数行和奇数行稍微变暗或变亮,即使是基于您的自定义颜色。
    4. 该示例仅为未选择的行设置自定义颜色。对于选定的行,将保留默认的蓝色和灰色。所以样本并不全面,但希望能为您提供足够的信息来实现您的目标。
    5. 该示例在代码中对默认颜色和自定义颜色进行编码,但更大的应用程序最好在单独的用户CSS样式表中定义这些颜色。

答案 1 :(得分:0)

在单元工厂的updateItem函数中,只需使用以下几行:

if(getIndex() % 2 == 1)
    setStyle("-fx-background-color: #AAAAAA");
else
    setStyle("");