JavaFX和addListener函数
如图所示:我创建了一个类似的剧院 我真的不知道如何正确使用addListener。。我希望客户一次只能选择一个座位(一次只能选择一个红色圆圈),而不能选择多个座位,因此我尝试将以前选择的红色座位设置为自由,如果是一个(绿色,布尔占用=false),只要客户选择与红色座位不同的新座位,并将新座位设置为红色 你能帮我吗 我非常感谢你的帮助JavaFX和addListener函数,java,javafx,javafx-2,Java,Javafx,Javafx 2,如图所示:我创建了一个类似的剧院 我真的不知道如何正确使用addListener。。我希望客户一次只能选择一个座位(一次只能选择一个红色圆圈),而不能选择多个座位,因此我尝试将以前选择的红色座位设置为自由,如果是一个(绿色,布尔占用=false),只要客户选择与红色座位不同的新座位,并将新座位设置为红色 你能帮我吗 我非常感谢你的帮助 class座位扩展组{ 彩色freeColor=Color.rgb(30,250,40); Color freeColorClasse=Color.rgb(25
class座位扩展组{
彩色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 IAMReperved=新的SimpleBoleAnProperty(false);
int myNo;
公众座位(国际号码){
myNo=否;
圆枕=新圆(12);
如果(否){
枕套填充(n?保留颜色:(no>64?freeColor:freeColorClasse));
});
setOnMouseClicked(m->{
iamservered.set(!iamservered.get());
});
}
}
窗格影院1(窗格影院、弦乐影院){
双x=20;
双y=40;
int no=1;
用于(字符串行:theater.split(“\n”)){
整数计数=0;
for(int c:row.toCharArray()){
开关(c){
案例“x”:
同时(计数-->0){
座椅=新座椅(无++);
座椅。设置布局x(x);
x+=26;
座椅设置布局y(y);
pane.getChildren().add(座椅);
}
计数=0;
打破
案例“0”:案例“1”:案例“2”:案例“3”:案例“4”:案例“5”:案例“6”:案例“7”:案例“8”:案例“9”:
计数=10*计数+(c-‘0’);
打破
案例‘‘
x+=26;
打破
案例“”:
x+=13;
打破
默认值:System.out.println(“未知字符:“+(字符)c+”);
}
}
y+=36;
x=20;
}
返回窗格;
}
这就是代码,只有创建剧院的部分您可以为
单选按钮
实现一个皮肤
,因为这个控件
已经提供了您想要的功能。它只是看起来不像你想要的那样。通过使用蒙皮
,您可以更改此设置:
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);
}
}
示例使用
@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
。将常用的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;
}
private final ObjectProperty reservedSeat=new SimpleObjectProperty();
窗格影院1(窗格影院、弦乐影院){
双x=20;
双y=40;
int no=1;
用于(字符串行:theater.split(“\n”)){
整数计数=0;
for(int c:row.toCharArray()){
开关(c){
案例“x”:
同时(计数-->0){
座椅=新座椅(无++);
座椅。设置布局x(x);
x+=26;
座椅设置布局y(y);
pane.getChildren().add(座椅);
seat.reservedProperty().addListener((obs,was reserved,isNowReserved)->{
如果(现在保留){
if(reservedSeat.get()!=null){
reservedSeat.get().setReserved(false);
}
预留座位(座);
}否则{
reservedSeat.set(空);
}
});
}
计数=0;
打破
案例“0”:案例“1”:案例“2”:案例“3”:案例“4”:案例“5”:案例“6”:案例“7”:案例“8”:案例“9”:
计数=10*计数+(c-‘0’);
打破
案例‘‘
x+=26;
打破
案例“”:
x+=13;
打破
默认值:System.out.println(“未知字符:“+(字符)c+”);
}
}
y+=36;
x=20;
}
返回窗格;
}
完美的詹姆斯,这正是我想要的!我现在正在学习JavaFX,我从来没有听说过ObjectProperty。感谢大家的帮助,现在我正在尝试添加一个SQL数据库来保留预订的座位。嗨,James_D,你的解决方案既优雅又简单。谢谢。我对静态变量和最终变量有一些问题。我的javaFX应用程序允许用户预订座位。如何将所选座位保存在变量中(我必须检查是否未选择任何人,以及所选座位是否已忙)?我打开一篇帖子,你能帮我将这一新功能改进到你的代码中吗?@Condo我看到了那篇帖子,不知道你在问什么。
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;
}