2016-07-05 5 views
0

私はJava 8の編集可能なComboBoxを持っています。ここでは、デフォルトの項目が太字で、デフォルト以外の項目はCellFactoryによってアンボールドされています。 デフォルトを別のアイテムに変更すると、新しいデフォルトを太字にし、CellFactoryでアンボールドされた古いデフォルトを取得する唯一の方法は、古いデフォルトアイテムと新しいデフォルトアイテムの両方を削除して再追加することです。以前の現在のアイテムが削除されて現在のアイテムが変更されたアイテムに設定されているため、新しいアイテムを処理するコードがかなり必要になります。JavaFX ComboBoxのドロップダウンリストセルを強制的に再レン​​ダリングする方法を教えてください。

セルを汚れて再描画する必要があるため、2つのセルを削除して再追加する必要はありません。

私は半日を過ごしましたが、正しい質問をしていない可能性があります。

私はすべてのコンボボックスの項目をクリアしてそれらをすべて再追加すれば制御コードが簡単になると思いますが、これはあまり効率的ではありません。

編集:要求されたとして、ここCellFactoryです:

  bookComboBox.setCellFactory(
     new Callback<ListView<String>, ListCell<String>>() { 
      @Override public ListCell<String> call(ListView<String> param) { 
       final ListCell<String> cell = new ListCell<String>() { 
        { 
         super.setPrefWidth(100); 
        } 
        @Override public void updateItem(String item, 
         boolean empty) { 
          super.updateItem(item, empty); 
          if (item != null) { 
           setText(item); 
           if (item.equals(Book.getDefaultBook())) { 
            setFont(Font.font("System", FontWeight.BOLD, 14)); 
            System.out.println("bookComboBox.setCellFactory: set BOLD item=" + item); 
           } 
           else { 
            setFont(Font.font("System", FontWeight.NORMAL, 14)); 
            System.out.println("bookComboBox.setCellFactory: set NORMAL item=" + item); 
           } 
          } 
          else { 
           setText(null); 
          } 
         } 
        }; 
        return cell; 
       } 
      }); 

私はレンダリングする際に使用されるだけで、フォント、セルの値を変更していませんよ。 私はonEditCommit()を使用していません。 私はbookComboBox.setOnActionリスナーを使ってコンボボックス選択の変更に反応します。 setOnActionイベントは、テキストがコンボボックスに入力され、アクションキー(ENTER)が押された場合、またはComboboxがフォーカスを失った場合にも発生します。

+0

CellFactoryはどのように実装されていますか?おそらく、必要なのは、その内部のコントロールを更新することだけです。 – Itai

+0

いくつかのコードを表示するか、 '' 'onEditCommit'''を使用してください。原理的には、細胞は自動的に再レン​​ダリングされるべきです。 –

+0

@jorn:セルは自動的に一度だけレンダリングされます。セル内の値を変更したり、再レンダリングするには再度セルを削除または追加しなければならないようです。これらのオプションはすべて、不要なComboBox.setOnActionイベントを発生させます。 –

答えて

1

各セルの項目を太字にするかどうかを示すObservableValue<Boolean>を使用すると、フォントを更新するバインディングを作成できます。

例:これは、デフォルトとして次を使用する前に1秒間デフォルトとして各項目を使用

@Override 
public void start(Stage primaryStage) { 
    ComboBox<String> comboBox = new ComboBox<>(FXCollections.observableArrayList(
      "item 1", 
      "item 2", 
      "item 3", 
      "item 4", 
      "item 5" 
    )); 

    final Font BOLD_FONT = Font.font("System", FontWeight.BOLD, 14); 
    final Font NORMAL_FONT = Font.font("System", FontWeight.NORMAL, 14); 

    final StringProperty defaultValue = new SimpleStringProperty(); 
    comboBox.setCellFactory(lv -> new ListCell<String>() { 

     { 
      // use bold font if the item property contains the 
      // same value as the defaultValue property 
      fontProperty().bind(Bindings.when(itemProperty().isEqualTo(defaultValue)) 
             .then(BOLD_FONT) 
             .otherwise(NORMAL_FONT)); 
     } 

     @Override 
     protected void updateItem(String item, boolean empty) { 
      super.updateItem(item, empty); 

      if (empty || item == null) { 
       setText(null); 
      } else { 
       setText(item); 
      } 
     } 

    }); 

    // change default every second 
    PauseTransition animation = new PauseTransition(Duration.seconds(1)); 
    EventHandler<ActionEvent> eventHandler = new EventHandler<ActionEvent>() { 

     private Iterator<String> iterator = comboBox.getItems().iterator(); 

     @Override 
     public void handle(ActionEvent event) { 
      if (!iterator.hasNext()) { 
       iterator = comboBox.getItems().iterator(); 
      } 
      defaultValue.set(iterator.next()); 
      animation.play(); 
     } 
    }; 

    animation.setOnFinished(eventHandler); 

    eventHandler.handle(null); 
    Scene scene = new Scene(comboBox); 

    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 
+0

こんにちはファビアン、ありがとう!しかし、上記のコードはコンパイルされません。 2記号の問題が見つからない:Bindings.withとDuration.seconds。私はDuration.secondsは必要ありませんが、これを修正することができればうれしくて、これは実際の例です。 –

+0

@ChrisGood:どちらもjavaFX APIの一部です。 'javafx.beans.binding.Bindings'と' javafx.util.Duration'をインポートする必要があります – fabian

+0

ああ!私はnetbeansにインポートを追加さ​​せて、それは間違ってjavax.script.Bindingsとjava.time.Durationを選んだ。生活し、学びます。今すぐ動作します - もう一度ありがとう! –

関連する問題