Visualizzazione dei risultati da 1 a 2 su 2

Discussione: JavaFX ComboBox: selezionare valore scrivendo

  1. #1

    JavaFX ComboBox: selezionare valore scrivendo

    ciao!

    forse è una domanda banale, ma mi sono accorto di questa cosa.

    su una JComboBox (quindi parliamo di Swing), una volta impostato il focus sul componente, se scrive con la tastiera, la lista scorre verso gli elementi che corrispondono a quello che si è scritto.
    quindi, per esempio, se abbiamo una lista di autori, e si scrive ste, la lista scorrerà verso l'autore che inizia con ste (ad esempio stephen king).
    e questo è un comportamento che in genere si ha in tutti i componenti simili in altri linguaggi (una <select> in html per dire).

    se ci spostiamo in ambito JavaFX, il relativo componente ComboBox non ha lo stesso coportamento.
    quindi, impostato il focus sulla lista, scrivendo non succede nulla.
    avete riscontrato anche voi questa cosa?
    si può ovviare??
    sarebbe più comodo, soprattutto in caso di molte voci.
    questo il codice:
    codice:
    <GridPane.margin>
            <Insets bottom="5.0" left="5.0" right="5.0" top="5.0"/>
        </GridPane.margin>
    </ComboBox>
    
    
    @FXML
    public void initialize() {
        jsonRead = new ReadJson();
        service = new Service();
        TypeToken<List<Author>> authorToken = new TypeToken<List<Author>>() {
        };
        try {
            List<Author> listAuthors = jsonRead.readJson(new File(UrlAndPath.JSON_AUTORI), authorToken);
            ObservableList<Author> authors = FXCollections.observableArrayList(listAuthors);
            comboAuthor.setItems(authors);
            comboAuthor.setCellFactory(new ComboListCell<Author>());
        } catch (IOException e) {
            GenericDialog.showDialog(e.getMessage(), Alert.AlertType.ERROR);
        }
    
    }

  2. #2
    ho trovato questa soluzione, e sembra funzionare:
    codice:
    import com.sun.javafx.scene.control.skin.ComboBoxListViewSkin;
    import javafx.beans.value.ChangeListener;
    import javafx.collections.ObservableList;
    import javafx.event.EventHandler;
    import javafx.scene.control.ComboBox;
    import javafx.scene.control.ListView;
    import javafx.scene.input.KeyCode;
    import javafx.scene.input.KeyEvent;
    
    public class KeyComboListener implements EventHandler<KeyEvent> {
    
        private ComboBox cb;
        private StringBuilder sb = new StringBuilder();
    
        public KeyComboListener(ComboBox cb) {
            this.cb = cb;
            this.cb.setOnKeyReleased(KeyComboListener.this);
            this.cb.addEventFilter(KeyEvent.KEY_RELEASED, event -> {
                if (event.getCode() == KeyCode.ESCAPE && sb.length() > 0) {
                    sb.delete(0, sb.length());
                }
            });
            this.cb.focusedProperty().addListener((ChangeListener) (observable, oldValue, newValue) -> {
                if (newValue instanceof Boolean && !((Boolean) newValue).booleanValue())
                    sb.delete(0, sb.length());
                else {
                    ListView lv = ((ComboBoxListViewSkin) KeyComboListener.this.cb.getSkin()).getListView();
                    lv.scrollTo(lv.getSelectionModel().getSelectedIndex());
                }
            });
            this.cb.setOnMouseClicked(event -> {
                ListView lv = ((ComboBoxListViewSkin) KeyComboListener.this.cb.getSkin()).getListView();
                lv.scrollTo(lv.getSelectionModel().getSelectedIndex());
            });
        }
    
        @Override
        public void handle(KeyEvent event) {
            if (event.getCode() == KeyCode.DOWN || event.getCode() == KeyCode.UP || event.getCode() == KeyCode.TAB) {
                return;
            } else if (event.getCode() == KeyCode.BACK_SPACE && sb.length() > 0) {
                sb.deleteCharAt(sb.length() - 1);
            } else {
                sb.append(event.getText());
            }
    
            if (sb.length() == 0)
                return;
    
            boolean found = false;
            ObservableList items = cb.getItems();
            for (int i = 0; i < items.size(); i++) {
                if (event.getCode() != KeyCode.BACK_SPACE && items.get(i).toString().toLowerCase().startsWith(sb.toString().toLowerCase())) {
                    ListView lv = ((ComboBoxListViewSkin) cb.getSkin()).getListView();
                    lv.getSelectionModel().clearAndSelect(i);
                    lv.scrollTo(lv.getSelectionModel().getSelectedIndex());
                    found = true;
                    break;
                }
            }
    
            if (!found && sb.length() > 0) {
                sb.deleteCharAt(sb.length() - 1);
            }
        }
    }
    poi basta richiamarla così:
    codice:
                List<Author> listAuthors = jsonRead.readJson(new File(UrlAndPath.JSON_AUTORI), authorToken);
                ObservableList<Author> authors = FXCollections.observableArrayList(listAuthors);
                comboAuthor.setItems(authors);
                comboAuthor.setCellFactory(new ComboListCell<Author>());
                KeyComboListener kcl = new KeyComboListener(comboAuthor);

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2018 vBulletin Solutions, Inc. All rights reserved.