2016-12-27 54 views
0

如在這裏看到的:https://stackoverflow.com/a/27113623/7326194我創建了一個類似的劇院。JavaFX和addListener函數

我真的不知道如何正確使用addListener ..我希望客戶只能在一次選擇一個席位(時間上是一個紅色圓圈),但不能超過一個,所以我試圖如果客戶選擇一個不同於紅色座椅的新座椅,並且設置爲紅色新座椅,則將先前選定的紅色座椅設置爲空閒(如果是綠色和布爾佔用=假)。

你能幫我嗎?

我真的很感謝你的幫助。


class Seat extends Group { 
    Color freeColor = Color.rgb(30, 250, 40); 
    Color freeColorClasse = Color.rgb(255, 255, 0); 
    Color reservedColor = Color.rgb(170, 40, 40); 

    int contatoreBase = 0, contatorePC = 0; 
    BooleanProperty iamReserved = new SimpleBooleanProperty(false); 
    int myNo; 

    public Seat(int no) { 

     myNo = no; 
     Circle pillow = new Circle(12); 

     if (no <= 64) { 
      pillow.setFill(freeColorClasse); 
     } 
     else { 
      pillow.setFill(freeColor); 
     } 

     pillow.setStrokeWidth(1); 
     pillow.setStroke(Color.rgb(30, 40, 40)); 
     getChildren().add(pillow); 

     Text lable = new Text(""+no); 
     lable.setFont(Font.font(11)); 
     lable.setTextAlignment(TextAlignment.CENTER); 
     lable.setTextOrigin(VPos.CENTER); 
     lable.setLayoutX(-lable.getLayoutBounds().getWidth()/2); 
     getChildren().add(lable); 

     iamReserved.addListener((e, o, n) -> { 
      pillow.setFill(n ? reservedColor : (no > 64 ? freeColor: freeColorClasse)); 
     }); 
     setOnMouseClicked(m -> { 

      iamReserved.set(!iamReserved.get());   
     }); 
    } 


} 
Pane theater1(Pane pane, String theater) { 
    double x = 20; 
    double y = 40; 
    int no = 1; 


    for (String row : theater.split("\n")) { 
     int count = 0; 
     for (int c : row.toCharArray()) { 
      switch (c) { 
       case 'x': 
        while (count-- > 0) { 
         Seat seat = new Seat(no++); 
         seat.setLayoutX(x); 
         x+=26; 
         seat.setLayoutY(y); 
         pane.getChildren().add(seat); 
        } 
        count = 0; 
        break; 
       case '0': case '1': case '2': case '3': case '4': case '5': case'6': case '7': case '8': case '9': 
        count = 10 * count + (c - '0'); 
        break; 
       case '_': 
        x+=26; 
        break; 
       case '.': 
        x+=13; 
        break; 
       default: System.out.println("Unknown char: '"+(char)c+"'"); 
      } 
     } 
     y+=36; 
     x = 20; 
    } 
    return pane; 
} 

這是代碼,只有部分創建劇院

回答

0

您可以實現對RadioButton一個Skin,因爲這Control已經提供你正在尋找的功能。它只是不看你需要的方式。通過使用Skin你可以改變這一點:

public class SeatRadioSkin extends SkinBase<RadioButton> { 

    private final Circle circle; 
    private final Label text; 
    private final EventHandler<MouseEvent> downHandler = evt -> { 
     if (evt.getButton() == MouseButton.PRIMARY) { 
      RadioButton btn = getSkinnable(); 

      if (!btn.isFocused() && btn.isFocusTraversable()) { 
       btn.requestFocus(); 
      } 

      if (!btn.isArmed()) { 
       btn.arm(); 
      } 
     } 
    }; 

    private final EventHandler<MouseEvent> upHandler = evt -> { 
     if (evt.getButton() == MouseButton.PRIMARY) { 
      RadioButton btn = getSkinnable(); 

      if (btn.isArmed()) { 
       btn.disarm(); 
       btn.fire(); 
      } 
     } 
    }; 

    public SeatRadioSkin(RadioButton button) { 
     super(button); 
     circle = new Circle(); 
     circle.setManaged(false); 
     circle.getStyleClass().setAll("seat"); 

     text = new Label(); 
     text.setManaged(false); 
     text.textProperty().bind(button.textProperty()); 
     text.getStyleClass().setAll("text"); 

     getChildren().setAll(circle, text); 
     button.getStyleClass().setAll("seat-radio-button"); 
     button.addEventHandler(MouseEvent.MOUSE_PRESSED, downHandler); 
     button.addEventHandler(MouseEvent.MOUSE_RELEASED, upHandler); 
     // todo: more event handlers 
    } 

    @Override 
    protected void layoutChildren(double contentX, double contentY, double contentWidth, double contentHeight) { 
     circle.setRadius(Math.min(contentWidth, contentHeight)/2); 
     layoutInArea(circle, contentX, contentY, contentWidth, contentHeight, -1, HPos.CENTER, VPos.CENTER); 
     text.resize(contentWidth, contentHeight); 
     layoutInArea(text, contentX, contentY, contentWidth, contentHeight, -1, HPos.CENTER, VPos.CENTER); 
    } 

    @Override 
    public void dispose() { 
     text.textProperty().unbind(); 
     RadioButton btn = getSkinnable(); 

     btn.removeEventHandler(MouseEvent.MOUSE_PRESSED, downHandler); 
     btn.removeEventHandler(MouseEvent.MOUSE_RELEASED, upHandler); 

     // todo: remove additional event handlers 

     super.dispose(); 
    } 

    private double prefSize(double widthOffset, double heightOffset) { 
     RadioButton btn = getSkinnable(); 
     double w = Math.max(30, btn.getPrefWidth()) + widthOffset; 
     double h = Math.max(30, btn.getPrefHeight()) + heightOffset; 
     return Math.min(w, h); 
    } 

    @Override 
    protected double computePrefHeight(double width, double topInset, double rightInset, double bottomInset, double leftInset) { 
     return prefSize(leftInset + rightInset, topInset + bottomInset); 
    } 

    @Override 
    protected double computePrefWidth(double height, double topInset, double rightInset, double bottomInset, double leftInset) { 
     return prefSize(leftInset + rightInset, topInset + bottomInset); 
    } 

} 

CSS

.seat-radio-button .seat { 
    -fx-fill: -seat-fill; 
    -fx-stroke: black; 
} 

.seat-radio-button:disabled { 
    -seat-fill-base: #444; 
    -text-fill: white; 
} 

.seat-radio-button:focused .seat { 
    -fx-effect: dropshadow(one-pass-box, -fx-focus-color, 10, 0, 0, 0); 
} 

.seat-radio-button .text { 
    -fx-fill: -text-fill; 
} 

.seat-radio-button { 
    -seat-fill-base: lime; 
    -seat-fill: -seat-fill-base; 
    -text-fill: black; 
} 

.seat-radio-button:armed { 
    -seat-fill: ladder(#aaa, black 0%, -seat-fill-base 100%); 
} 

.seat-radio-button:selected { 
    -seat-fill-base: red; 
} 

使用示例

@Override 
public void start(Stage primaryStage) { 
    ToggleGroup group = new ToggleGroup(); 

    RadioButton btn = createSeat("100", 30, 30, group); 
    RadioButton btn2 = createSeat("101", 30, 30, group); 
    RadioButton btn3 = createSeat("102", 30, 30, group); 

    btn2.setDisable(true); 

    HBox root = new HBox(10, btn, btn2, btn3); 
    root.setPadding(new Insets(10)); 

    Scene scene = new Scene(root, 200, 50); 
    scene.getStylesheets().add(getClass().getResource("style.css").toExternalForm()); 

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

您可以創建一個非常簡單的 「選擇模型」,簡單地通過代表所選座位爲ObjectProperty<Seat>。平時獲取/設置/屬性方法添加到Seat類:

class Seat extends Group { 
    private Color freeColor = Color.rgb(30, 250, 40); 
    private Color freeColorClasse = Color.rgb(255, 255, 0); 
    private Color reservedColor = Color.rgb(170, 40, 40); 

    private int contatoreBase = 0, contatorePC = 0; 
    private BooleanProperty iamReserved = new SimpleBooleanProperty(false); 
    private int myNo; 

    public BooleanProperty reservedProperty() { 
     return iamReserved ; 
    } 

    public final boolean isReserved() { 
     return reservedProperty().get(); 
    } 

    public final void setReserved(boolean reserved) { 
     reservedProperty().set(reserved); 
    } 

    // existing code omitted... 

} 

現在你可以這樣做:

private final ObjectProperty<Seat> reservedSeat = new SimpleObjectProperty<>(); 

Pane theater1(Pane pane, String theater) { 
    double x = 20; 
    double y = 40; 
    int no = 1; 


    for (String row : theater.split("\n")) { 
     int count = 0; 
     for (int c : row.toCharArray()) { 
      switch (c) { 
       case 'x': 
        while (count-- > 0) { 
         Seat seat = new Seat(no++); 
         seat.setLayoutX(x); 
         x+=26; 
         seat.setLayoutY(y); 
         pane.getChildren().add(seat); 

         seat.reservedProperty().addListener((obs, wasReserved, isNowReserved) -> { 
          if (isNowReserved) { 
           if (reservedSeat.get() != null) { 
            reservedSeat.get().setReserved(false); 
           } 
           reservedSeat.set(seat); 
          } else { 
           reservedSeat.set(null); 
          } 
         }); 

        } 
        count = 0; 
        break; 
       case '0': case '1': case '2': case '3': case '4': case '5': case'6': case '7': case '8': case '9': 
        count = 10 * count + (c - '0'); 
        break; 
       case '_': 
        x+=26; 
        break; 
       case '.': 
        x+=13; 
        break; 
       default: System.out.println("Unknown char: '"+(char)c+"'"); 
      } 
     } 
     y+=36; 
     x = 20; 
    } 
    return pane; 
} 
+0

完美James_D,這正是我一直在尋找!我正在學習JavaFX,並且我從來沒有聽說過ObjectProperty。 – Condo

+0

感謝大家的幫助,現在我試着添加一個SQL數據庫來保留預訂的席位。 – Condo

+0

嗨James_D,你的解決方案優雅而簡單。非常感謝。我有一些靜態和最終變量的問題。我的javaFX應用程序允許用戶預訂座位。我怎樣才能保存所選座位的變量(我必須檢查是否沒有人被選中,以及所選座位是否已經很忙)? – Condo