如何解决组合框冲突?

时间:2018-12-28 10:04:32

标签: java javafx scenebuilder

我正在使用JavaFX和Scene Builder制作一个应用程序。

-我有一个组合框用于选择字体大小(id-大小)

-我有一个组合框用于选择字体系列(id-字体选择器)

-我有一个标签(id-前标签)

  

问题#1: :当我单击带有下拉菜单的组合框时。下拉列表仅在一秒钟后出现。似乎可行   慢

     

问题2: :当我单击带有字体系列的组合框并选择某些字体时,它不适用于标签,但是当出现以下情况时,字体系列适用   我单击组合框,然后第二次选择字体。在这种情况下,我   应该连续两次选择一种字体以将字体应用于标签

     

问题3(主要问题): 。我遇到组合框冲突。当我选择字体系列时,它将应用于标签,但是当我选择字体时   其他组合框的大小也适用,但是在该字体系列之后   标签的默认值。当我选择字体时也会发生相同的情况   大小,然后从其他组合框中选择字体系列。

似乎只能将一个组合框应用于标签。

如何解决这些问题?

  

*所有代码都在控制器中

     

*问题3是原始问题。

Video

@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.Normal之后没有具体的字体大小?

2 个答案:

答案 0 :(得分:4)

您需要结合ComboBox的两个值来创建字体。不过,您每个人只能使用一个。至于打开字体ComboBox的延迟:这可能是由于需要加载多个Font所致。您可以替换ComboBox类型的参数Font并预加载字体。

要在ComboBox按钮区域中也为字体使用自定义显示,您需要使用将cellFactory创建的单元格类型设置为buttonCell

改为根据value es的2个ComboBox属性使用字体绑定

示例

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

答案 1 :(得分:0)

这不是组合框冲突。发生的事情正是您编写的代码。

通过阅读Font.font( size )的{​​{3}}:

  

根据默认字体系列名称和给定的字体大小搜索适当的字体

实际上,问题很简单。更改方法

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

更改字体系列名称时也是如此。检索标签字体的大小,然后应用具有先前字体大小的新字体系列名称。