簡體   English   中英

如何使用CSS在JavaFX中更改ListView單元格的文本顏色

[英]How to change ListView cell's text color in JavaFX using css

因此,我有一個列表,其中包含數據庫中的所有名稱。 這些名稱代表在公司工作或曾經在公司工作的員工。 我已經看到可以更改單元格的文本顏色,但是當我應用它時,它會更改所有文本。 我真正想要的是更改不再工作的客戶端的顏色。

我在列表中添加了“非活動”客戶端,因此我可以將“活動”和“非活動”客戶端分開。

這是我在ArrayList中添加員工姓名的代碼:

public  ArrayList<String> search(String unit, String name)
    {
        ArrayList<String> temp= new ArrayList<String>();
        String sql="";
        if(unit=="all units")
            sql="SELECT * FROM employees WHERE name='"+name+"';";
        else
            sql="SELECT * FROM employees WHERE unit='"+unit+"' AND name='"+name+"';";
        try {
        ResultSet rs=bp.select(sql);
            while(rs.next())
            {
                if(rs.getInt("active")==1)
                temp.add(rs.getString("name"));
                else
                    temp.add(rs.getString("name")+" - not active");
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        Collections.sort(temp);
        return temp;
    }

這是我在ListView中添加ArrayList的代碼:

for (String item: u.search(unitCB.getValue(),nameTF.getText()))
                            SearchLW.getItems().add(item);

現在,我可以為所有不再活動的員工使用CSS將列表中的文本顏色更改為紅色嗎? 如果不是,那么關於如何更改此特定ListView單元格的文本顏色的另一種解決方案將很有幫助。

您可以使用CSS偽類來表示“非活動”樣式,並在CSS文件中設置樣式。 使用您當前的代碼,它將類似於:

ListView<String> listView = new ListView<>();
PseudoClass inactive = PseudoClass.getPseudoClass("inactive");
listView.setCellFactory(lv -> new ListCell<String>() {
    @Override
    protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);
        setText(empty ? null : item);
        pseudoClassStateChanged(inactive, item != null && item.endsWith(" - not active"));
    }
});

然后,您可以在外部CSS文件中定義所需的樣式:

.list-cell:inactive {
    -fx-text-fill: red ;
}

僅在這里測試字符串值是非常脆弱的(想象一下,如果您嘗試使應用程序國際化,或者當老板告訴您更改演示文稿,以便在括號中顯示"not active" ,等等)。 我建議創建一個Employee類:

public class Employee {
    private final String name ;
    private final boolean active ;

    public Employee(String name, boolean active) {
        this.name = name ;
        this.active = active ;
    }

    public String getName() {
        return name ;
    }

    public boolean isActive() {
        return active ;
    }
}

然后你做

ListView<Employee> listView = new ListView<>();
PseudoClass inactive = PseudoClass.getPseudoClass("inactive");
listView.setCellFactory(lv -> new ListCell<Employee>() {
    @Override
    protected void updateItem(Employee employee, boolean empty) {
        super.updateItem(employee, empty);
        if (empty) {
            setText(null);
            pseudoClassStateChanged(inactive, false);
        } else {
            if (employee.isActive()) {
                setText(employee.getName());
                pseudoClassStateChanged(inactive, false);
            } else {
                setText(employee.getName() + " - not active");
                pseudoClassStateChanged(inactive, true);
            }
        }
    }
});

並對您發布的方法進行明顯的更新:

public  ArrayList<Employee> search(String unit, String name) {
    ArrayList<Employee> temp= new ArrayList<>();
    String sql="SELECT * FROM employees WHERE unit like ? AND name=?";

    try (PreparedStatement pStmnt = conn.prepareStatement(sql)) {

        if("all units".equals(unit))
            pStmnt.setString(1, "%");
        else
            pStmnt.setString(1, unit);

        pStmnt.setString(2, name);
        ResultSet rs=pStmnt.executeQuery();
        while(rs.next())
        {
            temp.add(new Employee(rs.getString("name"), rs.getInt("active")==1);
        }
    } catch (SQLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
    temp.sort(Comparator.comparing(Employee::getName));
    return temp;
}

這是一個替代實現,僅使用樣式類而不是偽類。 在這種情況下,偽類實現可能更好。

不過,也許這種解決方案的擴展性可能更好一些,因為您可以為選定的,未選定的單元格或焦點與未焦點單元格之類的東西指定單獨的偽類樣式,如果您使用自定義偽類,這可能會很困難(盡管(不確定)。

活動

ActivityListViewer.java

import javafx.application.Application;
import javafx.beans.property.*;
import javafx.collections.FXCollections;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.stage.Stage;

public class ActivityListViewer extends Application {
    @Override
    public void start(Stage stage) throws Exception {
        ListView<Activity> activityListView = new ListView<>(
                FXCollections.observableArrayList(
                        new Activity("Fetch super suit from drycleaner", false),
                        new Activity("Interview governor with Jimmy", false),
                        new Activity("Rescue stranded kitten", true),
                        new Activity("Dinner date with Lois", false)
                )
        );

        activityListView.setCellFactory(param -> new ListCell<Activity>() {
            static final String ACTIVE_CLASS = "active";
            @Override
            protected void updateItem(Activity item, boolean empty) {
                super.updateItem(item, empty);

                if (empty || item == null || item.getName() == null) {
                    setText(null);
                    getStyleClass().remove(ACTIVE_CLASS);
                } else {
                    if (item.isActive()) {
                        setText(item.getName() + " - active");
                    } else {
                        setText(item.getName());
                    }

                    if (item.isActive() && !getStyleClass().contains(ACTIVE_CLASS)) {
                        getStyleClass().add(ACTIVE_CLASS);
                    } else {
                        getStyleClass().remove(ACTIVE_CLASS);
                    }
                }
            }
        });

        activityListView.setPrefHeight(150);

        Scene scene = new Scene(activityListView);
        scene.getStylesheets().add(
                this.getClass().getResource("activity.css").toExternalForm()
        );

        stage.setScene(scene);
        stage.show();
    }

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

class Activity {
    private final StringProperty nameProperty;
    private final BooleanProperty activeProperty;

    public Activity(String name, boolean active) {
        this.nameProperty = new SimpleStringProperty(name);
        this.activeProperty = new SimpleBooleanProperty(active);
    }

    public String getName() {
        return nameProperty.get();
    }

    public StringProperty nameProperty() {
        return nameProperty;
    }

    public boolean isActive() {
        return activeProperty.getValue() != null
                ? activeProperty.getValue()
                : false;
    }

    public BooleanProperty activeProperty() {
        return activeProperty;
    }
}

activity.css

.active {
    -fx-text-fill: forestgreen;
}

.active:selected {
    -fx-text-fill: lawngreen;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM