Visualizzazione dei risultati da 1 a 10 su 11

Hybrid View

  1. #1
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Io cercherei di risolvere la questione in maniera object-oriented, separando bene i concetti. Ci sono infatti 2 concetti che sarebbero da tenere separati: il concetto del pattern da gestire (es. "!stephen !king") e il concetto del criterio di match all'interno di un oggetto (es. Film).

    Io una ideuzza ce l'avrei, se vuoi te la espongo .... c'è ben più codice da scrivere ma sarebbe riutilizzabile e ridurrebbe quel tuo listener a 2~3 righe.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  2. #2
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Io cercherei di risolvere la questione in maniera object-oriented, separando bene i concetti. Ci sono infatti 2 concetti che sarebbero da tenere separati: il concetto del pattern da gestire (es. "!stephen !king") e il concetto del criterio di match all'interno di un oggetto (es. Film).

    Io una ideuzza ce l'avrei, se vuoi te la espongo .... c'è ben più codice da scrivere ma sarebbe riutilizzabile e ridurrebbe quel tuo listener a 2~3 righe.
    bhe si grazie, quando hai tempo se ti va esponi!
    almeno imparo qualcosa di nuovo!

  3. #3
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da fermat Visualizza il messaggio
    bhe si grazie, quando hai tempo se ti va esponi!
    almeno imparo qualcosa di nuovo!
    Innanzitutto puoi fare una semplice interfaccia:

    codice:
    public interface TextMatcher {
        boolean matches(String text);
    }

    Poi in modo specifico per Film (ma lo potrai fare similarmente per qualunque altro oggetto) fai una classe di implementazione di TextMatcher:

    codice:
    public class FilmTextMatcher implements TextMatcher {
        private String titolo;
        private String author;
        private String note;
    
        public FilmTextMatcher(Film film) {
            titolo = film.getTitle().toLowerCase();
            author = film.getAuthor().toLowerCase();
            note = film.getNote().toLowerCase();
        }
    
        @Override
        public boolean matches(String text) {
            text = text.toLowerCase();
            return titolo.contains(text) || author.contains(text) || note.contains(text);
        }
    }

    Nota che in FilmTextMatcher NON c'è alcuna logica del "negativo". Un FilmTextMatcher fa solo una cosa: data una stringa la cerca all'interno dell'oggetto Film e restituisce se la trova o no. Per farlo deve stabilire: a) "dove" cercarla (in quali campi) e b) "come" cercarla (con contains() piuttosto che startWith() ecc...). Solo FilmTextMatcher "sa" come fare queste due cose (che sono specifiche di Film, ovviamente). E non fa altro.

    Poi fai una classe SearchPattern che rappresenta il pattern inserito dall'utente e che ha la capacità di "matchare" con un TextMatcher.

    codice:
    public class SearchPattern {
        private final Item[] items;
    
        public SearchPattern(String text) {
            String[] tokens = text.split("\\s+");
    
            items = new Item[tokens.length];
    
            for (int i = 0; i < items.length; i++) {
                items[i] = new Item(tokens[i]);
            }
        }
    
        public boolean matches(TextMatcher textMatcher) {
            boolean allMatch = true;
    
            for (int i = 0; allMatch && i < items.length; i++) {
                Item item = items[i];
                boolean match = textMatcher.matches(item.getText());
    
                if (item.isNegative()) {
                    allMatch &= !match;
                } else {
                    allMatch &= match;
                }
            }
    
            return allMatch;
        }
    
        private static class Item {
            final boolean negative;
            final String text;
    
            public Item(String text) {
                if (text.startsWith("!")) {
                    this.text = text.substring(1);
                    negative = true;
                } else {
                    this.text = text;
                    negative = false;
                }
            }
    
            public boolean isNegative() {
                return negative;
            }
    
            public String getText() {
                return text;
            }
        }
    }

    Nota come SearchPattern analizza il pattern in input (es. "!stephen !king") e si "compila" una lista di Item che rappresentano ciascun pezzo del pattern, con o senza la negazione.
    Quindi il matches semplicemente "prova" ciascuno di questi pezzi contro il TextMatcher. Ed è qui che viene usato il concetto di "negato". Se nel pattern c'è !stephen e stephen lo TROVO, allora per la negazione non è valido e allMatch diventa false.


    A quel punto il tuo listener diventa:

    codice:
    txtSearch.textProperty().addListener((observable, oldValue, newValue) -> {
        SearchPattern searchPattern = new SearchPattern(newValue);
        filteredData.setPredicate(film -> searchPattern.matches(new FilmTextMatcher(film)));
    });

    che puoi ancora abbreviare, se vuoi.

    Non è gestito il caso in cui newValue possa essere null ma in teoria non dovrebbe mai esserlo (non ho bene idea adesso sul textfield di JavaFX, dovrei documentarmi).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

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 © 2026 vBulletin Solutions, Inc. All rights reserved.