JavaFX and addListener function



如下所示:https://stackoverflow.com/a/27113623/7326194我创建了一个类似的剧院。

我真的不知道如何正确使用AddListener ..我希望一个客户只能在时间(时间一个红色圆圈)选择一个座位,而不超过一个,所以我试图设置以前选择的红色座椅是免费的,如果是一个(绿色和布尔人占领= false),每当客户选择一个新座位的红色座位,并将新座位与新座位进行红色。

你能帮我吗?

我真的很感谢您的帮助。


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

那是代码,只是创建剧院的部分

您可以为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();
}

您可以创建一个非常简单的"选择模型",只需将所选座椅表示为ObjectProperty<Seat>即可。将通常的GET/SET/属性方法添加到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;
}

相关内容

最新更新