2016-06-20 47 views
1

所以我有一個列表,裏面充滿了我的數據庫中的名稱。這些名稱代表在公司工作或曾經工作過的員工。我已經看到可以改變單元格的文本顏色,但是當我應用它時,它會改變它們的全部。我真正想要的是改變沒有工作的客戶的顏色。如何在JavaFX中使用css更改ListView單元格的文本顏色

我在列表中添加了「不活躍」,所以我可以分開「活動」和「不活動」客戶端。

這裏就是我在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; 
    } 

而且這裏是我補充一點的ArrayList在我的ListView代碼:

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

現在,我wounder是有可能使用css將此列表中的文本顏色更改爲紅色,以禁止所有不再活動的員工?如果不是這樣,另一個解決方案就是如何更改這個特定的ListView單元格的文本顏色將會很有幫助。

+3

順便說一句,你不妨在讀了起來:在[防止SQL注入攻擊一個Java程序](http://stackoverflow.com/questions/9516625/prevent-sql-injection-attacks-in-a -java-程序)。 – jewelsea

+0

這是有點類似於這個問題:[JavaFX中的2種顏色的背景?](http://stackoverflow.com/questions/16200901/background-with-2-colors-in-javafx)。儘管這個問題是關於在TableView中設置單元格的樣式,但對列表單元格的樣式可以使用類似的原則。 – jewelsea

+0

關於sql注入攻擊,是的,我意識到這一點,我只是從我的程序中重新輸入代碼來解決我的問題,方法是編寫一個簡單的simular方法,將數據庫中的數據存入ArrayList。這意味着我只是重新輸入了所有需要查看我在這裏要做什麼的重要數據。 –

回答

2

您可以使用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; 
} 
+0

對我來說工作得很好。非常感謝你。 –

2

這裏是一個替代實現其只是使用風格類而不是僞造類。在這種情況下,僞類實現可能會更好。

儘管這個解決方案可能會稍微好一些,因爲您可以爲諸如選擇vs未選定或聚焦vs未聚焦的單元格指定單獨的僞類風格,如果您使用自定義僞類(儘管我不確定)。

activity

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

我已經測試了您的解決方案,但我認爲我會堅持使用Jamed_D的解決方案。你的工作也是如此。我感謝你的努力。再次感謝。 –

相關問題