Как изменить положение метки RadioButton?

#java #css #javafx #radio-button #javafx-8

#java #css #javafx #переключатель #javafx-8

Вопрос:

По умолчанию RadioButton s имеют свою текстовую метку справа от кнопки. Я хочу, чтобы метка отображалась под кнопкой. Я нашел старую дискуссию на форумах Oracle, но решения не очень хороши или просто не работают.

Я могу создать пользовательский компонент с переключателем без текста и отдельной текстовой меткой и расположить их как в VBox . Но тогда только сама кнопка реагирует на пользовательские события, а не все целиком.

Неужели нет простого способа изменить положение метки?

Ответ №1:

Не существует «простого» способа сделать это (простой означает установку одного свойства или что-то в этом роде).

В качестве обходного пути вы могли бы сделать что-то вроде того, что вы упомянули с помощью a VBox , но с помощью a Label : вы можете установить в RadioButton качестве графического элемента Label и установить значение contentDisplayProperty TOP ( RadioButton помещается поверх Label ). И затем вы можете добавить обработчик событий Label для выбора RadioButton при нажатии.

Пример с таким подходом

 public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root, 400, 400);

            HBox hbox = new HBox();
            hbox.getChildren().add(createRadioLabel("Radio on the left", ContentDisplay.LEFT));
            hbox.getChildren().add(createRadioLabel("Radio on the top", ContentDisplay.TOP));
            hbox.getChildren().add(createRadioLabel("Radio on the bottom", ContentDisplay.BOTTOM));
            hbox.getChildren().add(createRadioLabel("Radio on the right", ContentDisplay.RIGHT));
            hbox.setSpacing(30);
            root.setCenter(hbox);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private Label createRadioLabel(String text, ContentDisplay cd) {
        Label label = new Label(text);
        label.setGraphic(new RadioButton());
        label.setContentDisplay(cd);
        label.addEventHandler(MouseEvent.MOUSE_CLICKED, e -> {
            RadioButton radioButton = (RadioButton) ((Label) e.getSource()).getGraphic();
            radioButton.requestFocus();
            radioButton.setSelected(!radioButton.isSelected());

        });
        return label;
    }


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

И созданные RadioButton :

введите описание изображения здесь

В качестве альтернативы, если вы хотите, чтобы текст RadioButton был повернут вокруг точки, вы можете использовать CSS rotations с атрибутом -fx-rotate :

 .radio-button { -fx-rotate:180; }
.radio-button > .text { -fx-rotate: 180; }
  

Первый селектор повернет все RadioButton , так что в результате текст будет размещен с левой стороны от «точки», вверх ногами. Второй селектор поворачивает текст обратно в нормальном направлении.

Пример

В этом примере показан RadioButton символ, который Text может быть размещен с любой стороны от «точки», указанной ComboBox выделением.

 public class Main extends Application {
    @Override
    public void start(Stage primaryStage) {
        try {
            BorderPane root = new BorderPane();
            Scene scene = new Scene(root, 400, 400);

            scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());

            RadioButton rb = new RadioButton("In all directions);

            ComboBox<PseudoClass> combo = new ComboBox<>();
            combo.getItems().addAll(PseudoClass.getPseudoClass("left"), 
                    PseudoClass.getPseudoClass("top"),
                    PseudoClass.getPseudoClass("right"), 
                    PseudoClass.getPseudoClass("bottom"));

            combo.valueProperty().addListener((obs, oldVal, newVal) -> {

                if (oldVal != null)
                    rb.pseudoClassStateChanged(oldVal, false);

                rb.pseudoClassStateChanged(newVal, true);
            });

            root.setTop(combo);
            root.setCenter(rb);

            primaryStage.setScene(scene);
            primaryStage.show();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

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

application.css

 .radio-button:left > .text { -fx-rotate: 180; }
.radio-button:left { -fx-rotate:180; }

.radio-button:right > .text { -fx-rotate: 0; }
.radio-button:right { -fx-rotate:0; }

.radio-button:top > .text { -fx-rotate: 0; }
.radio-button:top { -fx-rotate:-90; }

.radio-button:bottom > .text { -fx-rotate: 0; }
.radio-button:bottom { -fx-rotate:90; }
  

И отображаемый RadioButton :

введите описание изображения здесь

Комментарии:

1. Очень полный ответ и работает. Спасибо! В итоге я создал класс из кода, который вы дали, чтобы поддерживать группу переключателей, потому что метка этого не делает, и ей нужно делегировать его своей переключающей кнопке.

2. (Если у вас нет лучшего способа поддержки групп переключения с помощью этого)