2014年10月15日 星期三

JavaFX Cell Factory (1)

Cell Factory是JavaFX一項特殊的功能,適用於Combo Box, List View, Table, Tree, Tree Table等物件。以Combo Box為例,Cell Factory將每一個選項項目視為單元,稱為清單單元 (List Cell),藉由設定Cell Factory將每一個選項項目變更為其他物件如文字字串、文字欄位或複合方塊等物件,以改變每一個選項項目的形式。

以下範例分別示範以文字字串與顏色選項修改Combo Box的選項項目,第一個複合方塊設定為文字字串之選項項目,以setCellFactory()方法設定其Cell Factory,並在Cell Factory中分別設定各選項項目的文字顏色:
String title[] = new String[10];

for (int i=0; i < 10; i++)    
  title[i] = "Item " + i;

final ComboBox combobox1 = new ComboBox();
    
combobox1.setItems(FXCollections.observableArrayList(title));
combobox1.setValue("Item 0");
combobox1.setPromptText("Editable");
combobox1.setVisibleRowCount(5);
combobox1.setEditable(true);

// Cell Factory
combobox1.setCellFactory(
  new Callback<ListView<String>, ListCell<String>>() {
  @Override  
  public ListCell<String> call(ListView<String> param) {
    
    return new ListCell<String>() 
    {
      {
        super.setPrefWidth(60);
      }    
      @Override 
      protected void updateItem(String item, boolean empty) {
        super.updateItem(item, empty);

        if (item != null) {
          setText(item); 

          if (item.contains("Item 0")) 
            setTextFill(Color.RED);
          else if (item.contains("Item 1"))
            setTextFill(Color.GREEN);
          else if (item.contains("Item 2"))
            setTextFill(Color.BLUE);
          else if (item.contains("Item 3"))
            setTextFill(Color.AQUA);
          else if (item.contains("Item 4"))
            setTextFill(Color.BLUEVIOLET);
          else if (item.contains("Item 5"))
            setTextFill(Color.CHOCOLATE);
          else if (item.contains("Item 6"))
            setTextFill(Color.DIMGRAY);
          else if (item.contains("Item 7"))
            setTextFill(Color.FORESTGREEN);
          else if (item.contains("Item 8"))
            setTextFill(Color.GREENYELLOW);
          else if (item.contains("Item 9"))
            setTextFill(Color.INDIGO);
        }
        else {
          setText(null);
        }
      }
    };
  }
});
...
【執行結果】 
第二個複合方塊則設定為顏色之選項項目,以setCellFactory()方法設定其Cell Factory,並在Cell Factory中以Rectangle類別設定各選項項目的顏色:
final ComboBox<Color> combobox2 = new ComboBox<>();;
    
combobox2.getItems().addAll(
  Color.RED, Color.GREEN, Color.BLUE, Color.AQUA, 
  Color.BLUEVIOLET, Color.CHOCOLATE, Color.DIMGRAY, 
  Color.FORESTGREEN, Color.GREENYELLOW, Color.INDIGO);

// select the last element
combobox2.getSelectionModel().select(3);
combobox2.setVisibleRowCount(5);
combobox2.setEditable(false);

// Cell Factory
combobox2.setCellFactory(
  new Callback<ListView<Color>, ListCell<Color>>() {
  @Override  
  public ListCell<Color> call(ListView<Color> param) {
    
    return new ListCell<Color>() 
    {
      {
        super.setPrefWidth(60);
      }    
      private final Rectangle rectangle;
      { 
        setContentDisplay(ContentDisplay.GRAPHIC_ONLY); 
        rectangle = new Rectangle(70, 15);
      }
         
      @Override  
      protected void updateItem(Color item, boolean empty) {
        super.updateItem(item, empty);
             
        if (item == null || empty) {
          setGraphic(null);
        } 
        else {
          rectangle.setFill(item);
          setGraphic(rectangle);
        }
      }
    };
  }
});
...
【執行結果】 
以List View為例,Cell Factory將每一個選項項目視為單元,稱為清單單元 (List Cell),藉由設定Cell Factory將每一個選項項目變更為其他物件如文字字串、文字欄位或複合方塊等物件,以改變每一個選項項目的形式。

以下範例分別示範以文字欄位與複合方塊修改List View的選項項目,當點選檢視清單的選項項目時,其清單單元分別轉換為文字欄位與複合方塊,因此選項項目可藉由文字欄位輸入資料或以複合方塊選擇選項項目。以下示範設定單選模式與設定文字欄位為檢視清單的Cell Factory:
ObservableList<String> data = FXCollections.observableArrayList(
  "January", "February", "March", "April", "May", "June", 
  "July", "August", "September", "October", "November", "December");

// ListView with TextFieldListCell
final ListView<String> listview1 = new ListView<>();
// 設定單選模式
listview1.getSelectionModel().setSelectionMode(SelectionMode.SINGLE);
listview1.setItems(data);
listview1.setPrefWidth(150);
listview1.setPrefHeight(100);
listview1.setOrientation(Orientation.VERTICAL);
listview1.setEditable(true);
listview1.setCellFactory(TextFieldListCell.forListView()); 
...

ObservableList<String> data = FXCollections.observableArrayList(
  "January", "February", "March", "April", "May", "June", 
  "July", "August", "September", "October", "November", "December");

// ListView with ComboBoxListCell
final ListView<String> listview2 = new ListView<>();
// 設定複選模式
Listview2.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
listview2.setItems(data);
listview2.setPrefWidth(150);
listview2.setPrefHeight(100);
listview2.setOrientation(Orientation.VERTICAL);
listview2.setEditable(true);
listview2.setCellFactory(ComboBoxListCell.forListView(data)); 
...
【執行結果】 
【參考資料】

[1] Java Official Web Site:http://www.oracle.com/technetwork/java/index.html
[2] JavaFX:http://www.oracle.com/technetwork/java/javafx
[3] JavaFX 8.0 API Specification.
[4] Java Platform, Standard Edition 8 API Specification.

© Chia-Hui Huang

沒有留言:

張貼留言