How to resolve conflict of comboboxes?

kentforth :

I'm making an app with JavaFX and Scene Builder.

-I have one combo box for selecting font size (id - size)

-I have one combo box for selecting font family (id - font selector)

-I have a label (id - front label)

Problem #1: When I I click on Combobox with fThe drop-down. Drop-down list appears only after a second. It seems like it works slow

Problem #2: When I click on combobox with font family and choose some font it doesn't apply to the label, but font family applies when I click on combobox and choose font second time. In this case, I should pick a font two times in a row to apply a font to my label

Problem a #3(Main problem): I have conflict of comboboxes. When I choose a font family it applies to the label, but when I choose font size from other combobox size also applies but after that font family of the label become default. Same situation occurs when I pick font size and then pick font family from other combobox.

It seems that only one combobox can be applied to the label.

How to resolve these problems?

*All code is in the Controller

*Problem #3 is the primordial one.

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

Method that applies font size to label from combobox

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

Method that applies font family from combobox to the label

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

EDIT:

I assume that conflict of comboboxes appears here:

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

How to refactor that line of code to make it work but without concrete font size after FontWeight.Normal in brackets?

fabian :

You need to combine both values of the ComboBoxes to create the font. You only use a single one each though. As for the delay when opening the font ComboBox: this is probably caused by the fact that multiple Fonts need to be loaded. You could replace the ComboBox type parameter Font and preload the fonts.

To use a custom display for the font in the ComboBox button area too, you need to use set the same cell type that is created by the cellFactory as buttonCell.

Use a binding for the font based on the 2 value properties of the ComboBoxes instead

Example

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

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=135624&siteId=1