2017-03-13 5 views
0

私は予約システム用のインターフェイスで作業しています。ウィンドウでは、そのスロットが利用可能であるかどうかを確認するために、予約の開始時刻と予約の終了時刻を取得する必要があります。 (hh:mmだけ興味があり、私はその日のどこかにいる)。 コンボボックスは、次のようになります。JavaFXは、変更可能な入力に基づいていくつかのアイテムを無効にするためのComboBoxアイテムリストを更新します。

//startTime HBox 
    HBox startTime = new HBox(); 
    startTime.setSpacing(5); 
    final ComboBox startHours = new ComboBox(hours); 
    final ComboBox startMinutes = new ComboBox(minutes); 
    final Label colon = new Label(":"); 
    startTime.getChildren().addAll(startHours,colon,startMinutes); 

それはendTimeのために同じである(同じ要素を持つHBoxのがちょうど

変数名を変更し、私は私のstartTime時間コンボボックスが自動的より高いこれらの項目を無効にします現在のendTimeコンボボックス時間、およびその逆の場合は、startTimeコンボボックスよりも低いendTime時間項目を無効にします。 コンボボックスを編集する前にコンボボックスを開いた場合、セルファクトリを作成しようとしました。他のコンボボックス

startHours.setCellFactory(
    new Callback<ListView<String>, ListCell<String>>() { 
      @Override 
      public ListCell<String> call(ListView<String> param) { 
       final ListCell<String> cell = new ListCell<String>() { 

        @Override public void updateItem(String item, 
         boolean empty) { 
          super.updateItem(item, empty); 
          if (item!=null){ 
           setText(item); 
          } 
          if ((endHours.getValue()!=null) && (endHours.getValue().toString().compareTo(item)<0)){ 
           setDisable(true); 
           setStyle("-fx-background-color: #ffc0cb"); 
          } 
         } 
      }; 
      return cell; 
     } 
    }); 

答えて

1

セルは、他のコンボボックスの値を監視する必要があります。その値が変更された場合、無効状態を更新することがわかります。

セルの実装には他にもバグがあります。updateItem()メソッドのすべての可能性を考慮する必要があります。 (セルが空である)項目が適切に処理されていないか、必要なときに無効状態をfalseに戻すように設定します。最後に、ここでデータ型として文字列を使用することは不便です(これらの値を使用するにはある時点でintに変換して戻す必要があります)(例えば "10"が "2"より小さいため)ここではComboBox<Integer>を使用してください。

import java.util.function.BiPredicate; 

import javafx.application.Application; 
import javafx.beans.value.ObservableValue; 
import javafx.geometry.Insets; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.Label; 
import javafx.scene.control.ListCell; 
import javafx.scene.layout.GridPane; 
import javafx.stage.Stage; 


public class DependentComboBoxes extends Application { 

    private ComboBox<Integer> startHours ; 
    private ComboBox<Integer> endHours ; 

    @Override 
    public void start(Stage primaryStage) { 
     startHours = new ComboBox<>(); 
     endHours = new ComboBox<>(); 
     startHours.setCellFactory(lv -> new StartHoursCell()); 
     endHours.setCellFactory(lv -> new EndHoursCell()); 
     for (int i = 0; i < 24 ; i++) { 
      startHours.getItems().add(i); 
      endHours.getItems().add(i); 
     } 

     GridPane root = new GridPane(); 
     root.setHgap(5); 
     root.setVgap(5); 
     root.addRow(0, new Label("Start hours:"), startHours); 
     root.addRow(1, new Label("End hours:"), endHours); 

     root.setAlignment(Pos.CENTER); 
     root.setPadding(new Insets(20)); 
     primaryStage.setScene(new Scene(root)); 
     primaryStage.show(); 
    } 

    private class StartHoursCell extends ListCell<Integer> { 

     StartHoursCell() { 
      endHours.valueProperty().addListener((obs, oldEndHours, newEndHours) -> updateDisableState()); 
     } 

     @Override 
     protected void updateItem(Integer hours, boolean empty) { 
      super.updateItem(hours, empty); 
      if (empty) { 
       setText(null); 
      } else { 
       setText(hours.toString()); 
       updateDisableState(); 
      } 
     } 

     private void updateDisableState() { 
      boolean disable = getItem() != null && endHours.getValue() != null && 
        getItem().intValue() > endHours.getValue(); 
      setDisable(disable) ; 
      setOpacity(disable ? 0.5 : 1); 
     } 
    } 

    private class EndHoursCell extends ListCell<Integer> { 

     EndHoursCell() { 
      startHours.valueProperty().addListener((obs, oldEndHours, newEndHours) -> updateDisableState()); 
     } 

     @Override 
     protected void updateItem(Integer hours, boolean empty) { 
      super.updateItem(hours, empty); 
      if (empty) { 
       setText(null); 
      } else { 
       setText(hours.toString()); 
       updateDisableState(); 
      } 
     } 

     private void updateDisableState() { 
      boolean disable = getItem() != null && startHours.getValue() != null && 
        getItem().intValue() < startHours.getValue(); 
      setDisable(disable) ; 
      setOpacity(disable ? 0.5 : 1); 

     } 
    } 

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

これは私に多くの助けになります...その間、私は "Submit"ボタンonActionイベントのcuzでいくつかのエラーチェックを行うことにしました。私はこの方法が複雑すぎると思いました。しかし、あなたの答えはそれが難しいことではないことを証明します。リスナーとイベントの違いを説明するために、私の隣に誰かがいたことを祈っています:dその間に、ありがとう – SirWinning

0

として複雑ではありませんが、コンボボックス内の項目を無効にしないだけではstartHoursを残し、に選択された値を使用することです:

はここで働くわずか2「時間」コンボボックスでの実装ですendHoursに表示される内容を決定します。 startHoursの値が変更された場合、endHoursには開始から23時までの時間が入ります。endHoursが既に選択されており、startHoursを値より高く変更すると、何も表示されず、再選択する必要があります。 startHoursの値は変更する必要はありません。ちょうどendHoursの値です。

ComboBox<Integer> start = new ComboBox<Integer>(); 
ComboBox<Integer> end = new ComboBox<Integer>(); 
for(int i : IntStream.range(1, 24).toArray()) { 
    start.getItems().add(i); 
    end.getItems().add(i); 
} 
start.setOnAction(ae -> { 
    Integer selected = end.getSelectionModel().getSelectedItem(); 
    end.getItems().clear(); 
    for(int i : IntStream.range(start.getSelectionModel().getSelectedItem(), 24).toArray()) { 
     end.getItems().add(i); 
    } 
    if(end.getItems().contains(selected)) { 
     end.getSelectionModel().select(selected); 
    } 
}); 
関連する問題