Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

So I have a list which is full of names from my database. Those names represent employees that work or used to work in the firm. I've seen that is possible to change cell's text color but when I apply it, it changes all of them. What I really want is to change color of the clients that are no more working.

I've added "not active" in List so I can separate "active" and "not active" clients.

Here is the code where I add employees names in the 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;
    }

And here is the code where I add that ArrayList in my ListView:

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

Now, I wounder is it possible to change text-color in this list using css to red for all employees that are not active anymore? If it's not, another solution on how to change this specific ListView cell's text-color would be helpful.

like image 705
Nemanja Cvijan Avatar asked Mar 11 '23 22:03

Nemanja Cvijan


1 Answers

You can use a CSS pseudoclass to represent an "inactive" style and set the style in a CSS file. With your current code it would look something like:

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"));
    }
});

Then in an external css file you can define the style you want:

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

Just testing the string value here is pretty fragile (imagine what would happen if you tried to internationalize the application, or when your boss told you to change the presentation so that "not active" was in parentheses, or whatever...). I would recommend creating an Employee class:

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 ;
    }
}

and then you do

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);
            }
        }
    }
});

and make the obvious update to the method you posted:

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;
}
like image 180
James_D Avatar answered Mar 24 '23 08:03

James_D