Как решить конфликт со списком? - PullRequest
0 голосов
/ 28 декабря 2018

Я делаю приложение с JavaFX и Scene Builder.

-У меня есть одно поле со списком для выбора размера шрифта (id - размер)

-У меня есть одно поле со списком для выбора семейства шрифтов (id - шрифт)селектор)

-У меня есть метка (id - передняя метка)

Задача № 1: Когда я нажимаю на Combobox с выпадающим меню.Выпадающий список появляется только через секунду.Кажется, что он работает медленно

Проблема № 2: Когда я нажимаю на выпадающий список с семейством шрифтов и выбираю какой-то шрифт, он не применяется к метке, ноСемейство шрифтов применяется, когда я нажимаю на поле со списком и выбираю шрифт во второй раз.В этом случае я должен выбрать шрифт два раза подряд, чтобы применить шрифт к моему ярлыку

Задача № 3 (Основная проблема): У меня естьконфликт комбобоксов.Когда я выбираю семейство шрифтов, оно применяется к метке, но когда я выбираю размер шрифта из другого списка, также применяется размер комбинированного списка, но после этого семейство шрифтов метки становится стандартным.Такая же ситуация возникает, когда я выбираю размер шрифта, а затем выбираю семейство шрифтов из другого комбинированного списка.

Кажется, что только один комбинированный список может быть применен к метке.

Какрешить эти проблемы?

* Весь код находится в контроллере

* Проблема № 3 является изначальной.

Видео

@FXML  private ComboBox<String> fontSelector;
@FXML  private ComboBox<Integer> size;
@FXML  private Label fontLabel;

//create array of font sizes
ObservableList<Integer> fontSizes = FXCollections.observableArrayList(8, 
10, 11, 12, 14, 16, 18, 20, 24, 30, 36, 40, 48, 60, 72);

//get fonts from system
ObservableList<String> fonts = 
FXCollections.observableArrayList(Font.getFamilies());

//getting Controller variables and methods through Context class
Controller cont = Context.getInstance().getController();


@Override
public void initialize(URL location, ResourceBundle resources) {

//register FontController in  Context Class
Context.getInstance().setFontController(this);

 //bind text from textfield to label
 fontLabel.textProperty().bind(fontTextfield.textProperty());


 //show fonts' actual look in combobox list
 fontSelector.setCellFactory((ListView<String> listView) -> {
  final ListCell<String> cell = new ListCell<>(){
    @Override
    public void updateItem(String item, boolean empty) {
      super.updateItem(item, empty);
      if (item != null) {
        setText(item);
        setFont(new Font(item, 14));
      }
    }
  };
  return cell;
});


fontSelector.setItems(fonts);
size.setItems(fontSizes);
size.setOnAction(e -> updateFontSize());
}

Метод, который применяет размер шрифта к метке из выпадающего списка

private void updateFontSize() {
fontLabel.setFont(Font.font(size.getValue()));
}

Метод, который применяет семейство шрифтов из выпадающего списка к метке

public void changeLabel(ActionEvent event) {    
fontSelector.getSelectionModel().selectedItemProperty().addListener((obs, 
oldValue, newValue) -> fontLabel.setFont(Font.font(newValue, 
FontWeight.NORMAL, 35)));
}

РЕДАКТИРОВАТЬ:

Я предполагаю, что здесь возникает конфликт со списком:

fontSelector.getSelectionModel().selectedItemProperty().addListener((obs, 
oldValue, newValue) -> fontLabel.setFont(Font.font(newValue, 
FontWeight.NORMAL, 35)));

Как реорганизовать эту строку кода, чтобы она работала, но без конкретного размера шрифта после FontWeight. Нормально в скобках?

Ответы [ 2 ]

0 голосов
/ 28 декабря 2018

Вам необходимо объединить оба значения ComboBox es для создания шрифта.Вы используете только один каждый, хотя.Что касается задержки при открытии шрифта ComboBox: это, вероятно, связано с тем, что необходимо загрузить несколько Font.Вы можете заменить параметр типа ComboBox Font и предварительно загрузить шрифты.

Чтобы использовать настраиваемое отображение шрифта в области кнопок ComboBox, необходимо использовать тот же тип ячейки,cellFactory создается как buttonCell.

Использовать привязку для шрифта на основе 2 value свойств ComboBox es вместо

Пример

private static Font getFont(Font font, Integer size) {
    return Font.font(font == null ? null : font.getFamily(), size == null ? -1d : size.doubleValue());
}

@Override
public void start(Stage primaryStage) throws Exception {
    ComboBox<Font> fontSelector = new ComboBox<>();
    fontSelector.getItems().addAll(Font.getFamilies().stream().map(name -> Font.font(name, 14)).toArray(Font[]::new));

    ComboBox<Integer> size = new ComboBox<>();
    size.getItems().addAll(10, 11, 12, 14, 16, 18, 20, 24, 30, 36, 40, 48, 60, 72);

    Label fontLabel = new Label("Hello World");

    // bind font based on size/family
    fontLabel.fontProperty()
            .bind(Bindings.createObjectBinding(() -> getFont(fontSelector.getValue(), size.getValue()),
                    fontSelector.valueProperty(), size.valueProperty()));

    class FontListCell extends ListCell<Font> {

        @Override
        public void updateItem(Font item, boolean empty) {
            super.updateItem(item, empty);
            if (item != null) {
                setText(item.getFamily());
                setFont(item);
            } else {
                setText("");
                setFont(Font.font(14));
            }
        }
    }

    fontSelector.setCellFactory(lv -> new FontListCell());
    fontSelector.setButtonCell(new FontListCell());

    Scene scene = new Scene(new VBox(fontSelector, size, fontLabel), 300, 500);
    primaryStage.setScene(scene);
    primaryStage.show();
}
0 голосов
/ 28 декабря 2018

Это не комбобоксный конфликт.То, что происходит, это именно то, что вы кодировали.

При чтении javadoc из Font.font( size ):

Поиск соответствующего шрифта на основе имени семейства шрифтов по умолчанию и заданногоразмер шрифта.

На самом деле проблема довольно проста.Измените метод

private void updateFontSize() {
   // Here we retrieve the current font family name in order to not apply the default one.
   fontLabel.setFont(Font.font(fontLabel.getFont().getName(), size.getValue()));
}

Это та же идея, когда вы изменяете имя семейства шрифтов.Получите размер шрифта вашей метки и примените новое имя семейства шрифтов с предыдущим размером шрифта.

...