JavaFX和addListener函数

时间:2016-12-27 16:06:37

标签: java javafx javafx-2

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

我真的不知道如何正确使用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;
}

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

2 个答案:

答案 0 :(得分:0)

您可以为Skin实施RadioButton,因为此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();
}

答案 1 :(得分:0)

您可以创建一个非常简单的选择模型&#34;,只需将选定的座位表示为ObjectProperty<Seat>即可。将常用的get / set / property方法添加到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;
}