【问题标题】:How to resolve conflict of comboboxes?如何解决组合框的冲突?
【发布时间】:2019-05-26 04:08:25
【问题描述】:

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

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

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

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

问题 #1: 当我单击带有 fThe 下拉菜单的 Combobox 时。下拉列表仅在一秒钟后出现。好像有效 慢

问题 #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 之后没有具体的字体大小?

【问题讨论】:

    标签: java javafx scenebuilder


    【解决方案1】:

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

    通过阅读javadocFont.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()));
    }
    

    更改字体系列名称时也是同样的想法。检索标签字体的大小并将新的字体系列名称与以前的字体大小一起应用。

    【讨论】:

    • 我试过你的代码,但我有一个错误 [image] (imgur.com/a/oSn9wmf)
    • 我也尝试将 Combobox 更改为 @FXML Combobox 大小;但什么也没发生
    • 您的问题是因为方法setFont(String pFontName, double pSize) 不接受Integer 作为第二个参数(大小)但double。顺便说一句,fabian 的回答比较干净。
    • setFont 方法采用Font 参数,而不是Stringdouble。您需要致电setFont(Font.font(fontLabel.getFont().getName(), size.getValue()))
    • @Slaw,完全是true,我忘记了Font 课程,我会更新我的帖子(或者考虑到Fabian 的更好,我应该删除它吗?)。
    【解决方案2】:

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

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

    使用基于 ComboBoxes 的 2 个 value 属性的字体绑定

    示例

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-03-01
      • 2020-12-17
      • 1970-01-01
      • 2015-10-15
      • 1970-01-01
      • 2012-04-20
      • 2010-10-22
      • 2016-03-04
      相关资源
      最近更新 更多