Pagina 1 di 4 1 2 3 ... ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 33
  1. #1

    [Java] Creazione automatica dei componenti Swing

    Buongiorno a tutti,
    Ho predisposto l'applicazione per la creazione automatica dei componenti.
    In Java i componenti figli vengono aggiunti al padre tramite il metodo del padre .add(figlio)
    Quindi pensavo di leggere l'albero gerarchico dei componenti in ordine inverso e calcolando il ramo più lungo con più livelli.
    La profondità massima l'ho già calcolata.
    Inoltre questa metodica dovrebbe verificare l'integrità delle relazioni tra i componenti.
    La creazione deve partire dal componente più profondo e risalire verso il primo livello.
    Una volta creati i componenti eseguo i cicli in ordine discendente dal 1° Livello e aggiungo ciascun componente ad ogni padre.
    Penso che questa metodica sia corretta.
    Voi che dite?
    Ultima modifica di jabjoint; 10-03-2025 a 10:22
    jabjoint

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    Quindi pensavo di leggere l'albero gerarchico dei componenti in ordine inverso e calcolando il ramo più lungo con più livelli.
    La profondità massima l'ho già calcolata.
    Non rendere le cose più complicate del necessario .... Mai sentito di dover calcolare il ramo più "lungo" di un albero per fare una GUI ...

    Dovresti anche precisare (non l'hai fatto qui, né mi pare nelle altre discussioni aperte di recente) COME hai rappresentato la gerarchia dei componenti. XML? JSON? Un file di testo con tua struttura fatta-in-casa? Un DSL? Una base dati? Altro?

    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    La creazione deve partire dal componente più profondo e risalire verso il primo livello.
    , no, cioè non è detto. In Swing non c'è la necessità obbligatoria di creare i componenti "padre" prima dei componenti "figli", né il contrario. In altri framework GUI invece è diverso. Ad esempio in SWT (il framework GUI fatto dalla Eclipse Foundation e usato anche da Eclipse), ogni componente deve ricevere nel costruttore il componente "padre". In SWT, Button e Label hanno i costruttori:

    public Button(Composite parent, int style)
    public Label(Composite parent, int style)

    Lì infatti è obbligatorio creare prima il parent. Ma in Swing no.

    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    Voi che dite?
    Che se chiarisci una volta per tutte come hai rappresentato la gerarchia, è meglio.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Non rendere le cose più complicate del necessario .... Mai sentito di dover calcolare il ramo più "lungo" di un albero per fare una GUI ...

    Dovresti anche precisare (non l'hai fatto qui, né mi pare nelle altre discussioni aperte di recente) COME hai rappresentato la gerarchia dei componenti. XML? JSON? Un file di testo con tua struttura fatta-in-casa? Un DSL? Una base dati? Altro?


    , no, cioè non è detto. In Swing non c'è la necessità obbligatoria di creare i componenti "padre" prima dei componenti "figli", né il contrario. In altri framework GUI invece è diverso. Ad esempio in SWT (il framework GUI fatto dalla Eclipse Foundation e usato anche da Eclipse), ogni componente deve ricevere nel costruttore il componente "padre". In SWT, Button e Label hanno i costruttori:

    public Button(Composite parent, int style)
    public Label(Composite parent, int style)

    Lì infatti è obbligatorio creare prima il parent. Ma in Swing no.


    Che se chiarisci una volta per tutte come hai rappresentato la gerarchia, è meglio.
    Questo è il file di configurazione:

    codice:
    [BEGIN-GENERAL] 
    
                    //Proprietà comuni a tutti gli oggetti:
    
                    [SET-COMMON-PROPERTIES=1]:
    
                            Layout(#null#);
                            Visible(#true#);
    
                    [SET-COMMON-PROPERTIES=0].
                   
    [END-GENERAL]
    
    
    
    [BEGIN-ALL-OBJECTS]
    
        
        [JFRAMES=1]
    
                    [FRAME=1].[INDEX=#0#] 
                                        
                                      [SET-COMMON-PROPERTIES=1]:
    
                                            Name(#MainFrame1#);
                                            Bounds(#0, 0, 800, 600#);
                                            Visible(#true#);
    
                                      [SET-COMMON-PROPERTIES=0].
                                       
                                      [SET-BASE-PROPERTIES=1]:
                                           
                                            Parent(#null, null#);
                                            CenterRelativeToParent(#true, true#).
                                      
                                      [SET-BASE-PROPERTIES=0].
    
                    [FRAME=0].[INDEX=#0#]
    
    
    
    
        [JFRAMES=0]
    
        [CONTAINERS=1]
    
           
                    [CONTAINER=1].[INDEX=#0#] 
                                        
                                      [SET-COMMON-PROPERTIES=1]:
    
                                            Name(#MainContainer#);
                                            Bounds(#0, 0, 800, 600#).
    
                                      [SET-COMMON-PROPERTIES=0].
                                       
                                      [SET-BASE-PROPERTIES=1]:
                                      
                                            Parent(#FRAME, MainFrame1#);
                                            CenterRelativeToParent(#true, true#).
                                      
                                      [SET-BASE-PROPERTIES=0].
    
                    [CONTAINER=0].[INDEX=#0#] 
            
        [CONTAINERS=0] 
                         
        [JPANELS=1]
    
          
                    [PANEL=1].[INDEX=#0#] 
                                        
                                      [SET-COMMON-PROPERTIES=1]:
    
                                            Name(#MainPanel#);
                                            Bounds(#10, 10, 400, 400#).
    
                                      [SET-COMMON-PROPERTIES=0].
                                       
                                      [SET-BASE-PROPERTIES=1]:
                                      
                                            Parent(#CONTAINER, MainContainer#);
                                            CenterRelativeToParent(#true, true#).
                                      
                                      [SET-BASE-PROPERTIES=0].
    
                    [PANEL=0].[INDEX=#0#]
    
        [JPANELS=0] 
    
     
    
    [END-ALL-OBJECTS]
    Per la creazione dinamica dei componenti uso:

    codice:
    Class classX = Class.forName(fullClassName);
    
    Constructor constr = classX.getDeclaredConstructor();
    
    constr.setAccessible(true);
    
                Component c = (Component) constr.newInstance();
    
    
    L'unica accortezza, allora, sarà di rendere visibile il componente PADRE solo dopo aver creato e aggiunto il FIGLIO? Oppure lo mostra comunque?
    Ultima modifica di jabjoint; 11-03-2025 a 08:06
    jabjoint

  4. #4
    In ogni caso serve avere la gerarchia di livello nel ramo proprio per aggiungere in modo appropriato i componenti.
    Trovare la gerarchia dal file di conf. è semplice, basta filtrare uguagliando il campo parent del figlio col campo nome del padre.

    Infatti io dovrò aggiungere figlio1 a padre1 ma poi padre1 è a sua volta figlio di padre0...e via dicendo.
    Ultima modifica di jabjoint; 11-03-2025 a 11:48
    jabjoint

  5. #5
    ...
    jabjoint

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    Questo è il file di configurazione:
    Ok .. quello che "temevo". Una soluzione "fatta in casa" che però ha un sacco di problemi. Ed ora cerco di spiegarti.

    Innanzitutto quel tuo file di configurazione è estremamente "prolisso". Poi, perché tutti quei "#"?? La gestione di questo formato che ti sei "inventato", è tutta a TUO carico. E non è affatto banale. Non voglio nemmeno immaginare (no, non farmelo vedere ..) cosa hai scritto per parsare questo formato!

    E in ogni caso, da quella struttura si capisce molto poco. Soprattutto, quello che si capisce poco è la struttura "effettiva" dell'albero dei componenti.

    Si vede ad esempio:

    Parent(#FRAME, MainFrame1#);

    e

    Parent(#CONTAINER, MainContainer#);

    Ma già così si capisce poco. MainFrame1 è il Name di un frame messo 27 righe prima. Ora, se già così si capisce poco, immagina uno scenario nemmeno troppo complesso: un JFrame che contiene 1 JPanel, che contiene 3 JPanel, e ciascuno contiene 10~12 componenti.

    Secondo te, una persona che LEGGE quel file, va continuamente a cercarsi avanti e indietro le relazioni tra i nomi?? E secondo te, solo leggendo il file, riesce a farsi una idea mentalmente della struttura (ad "albero") della interfaccia utente??

    E infatti: non è così che va fatto!

    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    Trovare la gerarchia dal file di conf. è semplice, basta filtrare uguagliando il campo parent del figlio col campo nome del padre.
    No, non è questo che va fatto!! Anche se tecnicamente lo facessi, il file resterebbe comunque (quasi) illeggibile.


    Quote Originariamente inviata da jabjoint Visualizza il messaggio
    Per la creazione dinamica dei componenti uso:
    codice:
    Class classX = Class.forName(fullClassName);
    
    Constructor constr = classX.getDeclaredConstructor();
    
    constr.setAccessible(true);
    
    Component c = (Component) constr.newInstance();
    Anche qui sbagli. Innanzitutto il setAccessible probabilmente non ti serve. Il setAccessible(true) serve per permettere l'accesso a metodi/costruttori/field che non sarebbero normalmente accessibili per reflection secondo le regole sui livelli di accesso.
    Ma a te NON serve usare cose "interne" di Swing. E te basta usare l'API "pubblica" di Swing. E per questo, il setAccessible NON serve.

    Ti dico di più. L'uso di "diretto" della reflection (Class, Field, Method ecc...) ok, è un conto, ma esiste un'altra API nel framework, quella nel package java.beans. Questa API è di più "alto" livello ed è stata fatta proprio per gestire gli oggetti che seguono la specifica dei JavaBeans (oggetti con getXxx/setXxx ecc...) e in modo specifico i componenti AWT/Swing, che di fatto sono proprio dei JavaBeans.

    Poi hai considerato anche altri aspetti? Ad esempio il fatto che il setVisible(true) generalmente è l'ultima cosa da fare su un frame.

    E inoltre anche un'altra cosa: come gestisci il fatto che ad esempio in una certa classe che estende JFrame hai bisogno del riferimento a certi componenti? Quando io faccio una UI Swing, generalmente scrivo una cosa tipo:
    codice:
    public class MyFrame extends JFrame {
        private JLabel infoLabel;
    
        public MyFrame() {
            // qui costruisco i componenti, es.:
            infoLabel = new JLabel();
            // ....
        }
    
        // altri metodi dove uso infoLabel
    }

    Se con un file di configurazione, la creazione dei componenti è dinamica basata su quel file, quel infoLabel = new JLabel(); di fatto non esiste più. Quindi la domande è: chi mi popola quel field infoLabel che comunque mi serve nel codice di MyFrame?
    Sappi che ci sono diverse soluzioni (almeno 2 ho in mente) per questo aspetto.

    Hai pensato e ragionato su questi aspetti?
    Ultima modifica di andbin; 11-03-2025 a 18:29
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Quote Originariamente inviata da andbin Visualizza il messaggio
    Ok .. quello che "temevo". Una soluzione "fatta in casa" che però ha un sacco di problemi. Ed ora cerco di spiegarti.

    Innanzitutto quel tuo file di configurazione è estremamente "prolisso". Poi, perché tutti quei "#"?? La gestione di questo formato che ti sei "inventato", è tutta a TUO carico. E non è affatto banale. Non voglio nemmeno immaginare (no, non farmelo vedere ..) cosa hai scritto per parsare questo formato!

    E in ogni caso, da quella struttura si capisce molto poco. Soprattutto, quello che si capisce poco è la struttura "effettiva" dell'albero dei componenti.

    Si vede ad esempio:

    Parent(#FRAME, MainFrame1#);

    e

    Parent(#CONTAINER, MainContainer#);

    Ma già così si capisce poco. MainFrame1 è il Name di un frame messo 27 righe prima. Ora, se già così si capisce poco, immagina uno scenario nemmeno troppo complesso: un JFrame che contiene 1 JPanel, che contiene 3 JPanel, e ciascuno contiene 10~12 componenti.

    Secondo te, una persona che LEGGE quel file, va continuamente a cercarsi avanti e indietro le relazioni tra i nomi?? E secondo te, solo leggendo il file, riesce a farsi una idea mentalmente della struttura (ad "albero") della interfaccia utente??

    E infatti: non è così che va fatto!


    No, non è questo che va fatto!! Anche se tecnicamente lo facessi, il file resterebbe comunque (quasi) illeggibile.




    Anche qui sbagli. Innanzitutto il setAccessible probabilmente non ti serve. Il setAccessible(true) serve per permettere l'accesso a metodi/costruttori/field che non sarebbero normalmente accessibili per reflection secondo le regole sui livelli di accesso.
    Ma a te NON serve usare cose "interne" di Swing. E te basta usare l'API "pubblica" di Swing. E per questo, il setAccessible NON serve.

    Ti dico di più. L'uso di "diretto" della reflection (Class, Field, Method ecc...) ok, è un conto, ma esiste un'altra API nel framework, quella nel package java.beans. Questa API è di più "alto" livello ed è stata fatta proprio per gestire gli oggetti che seguono la specifica dei JavaBeans (oggetti con getXxx/setXxx ecc...) e in modo specifico i componenti AWT/Swing, che di fatto sono proprio dei JavaBeans.

    Poi hai considerato anche altri aspetti? Ad esempio il fatto che il setVisible(true) generalmente è l'ultima cosa da fare su un frame.

    E inoltre anche un'altra cosa: come gestisci il fatto che ad esempio in una certa classe che estende JFrame hai bisogno del riferimento a certi componenti? Quando io faccio una UI Swing, generalmente scrivo una cosa tipo:
    codice:
    public class MyFrame extends JFrame {
        private JLabel infoLabel;
    
        public MyFrame() {
            // qui costruisco i componenti, es.:
            infoLabel = new JLabel();
            // ....
        }
    
        // altri metodi dove uso infoLabel
    }

    Se con un file di configurazione, la creazione dei componenti è dinamica basata su quel file, quel infoLabel = new JLabel(); di fatto non esiste più. Quindi la domande è: chi mi popola quel field infoLabel che comunque mi serve nel codice di MyFrame?
    Sappi che ci sono diverse soluzioni (almeno 2 ho in mente) per questo aspetto.

    Hai pensato e ragionato su questi aspetti?
    Per quanto riguarda il file di configurazione si, dovrò valutare un approccio migliore che tenga conto di più componenti.
    Il parsing è comunque immediato ed i # sono utili in queso per evitare errori di lettura secondo il mio punto di vista.

    Mi sembra che se il JFrame tramite il metodo add aggiunge un JLabel labelInfo questo componente è direttamente accessibile. Non riesco a comprendere cosa intendi forse.

    Se comunque esiste già una libreria Java Swing meglio usarla, questo si.
    Inoltre usando i bean di swing potrei lavorare meglio?
    jabjoint

  8. #8
    Per quanto riguarda le informazioni che prelevo dal file di configurazione le inserisco in un oggetto della nuova classe ClassProperty che può contenere un oggetto generico Component Brother sul quale è costruito l'oggetto Swing vero e proprio.
    Ultima modifica di jabjoint; 12-03-2025 a 11:35
    jabjoint

  9. #9
    Potrei anche creare il solito file xml annidando i figli uno nell'altro. Ma ci sono soluzioni migliori ad intuito che potrei adottare.
    Per chiarezza di lettura potrei anche definire tutti i figli di ciascun oggetto e adottare inoltre un approccio migliore.
    Ora ci penso meglio.
    jabjoint

  10. #10
    Questo è un approccio migliore per la gerarchia:

    codice:
    [ELEMENTS=1]
    
    
        [ELEMENTS hierarchy=#frames#]
                                
            [ELEMENT index=0]
    
                //Definizione elemento
    
            [ELEMENT].
    
            [ELEMENT index=1]
    
                //Definizione elemento
    
            [ELEMENT].
    
        [ELEMENTS].
    
    
        [ELEMENTS hierarchy=#frame[0].containers#]
                            
            [ELEMENT index=0]
    
                //Definizione elemento
    
            [ELEMENT].
    
           [ELEMENT index=1]
    
                //Definizione elemento
    
            [ELEMENT].
    
    
        [ELEMENTS].
    
    
        [ELEMENTS hierarchy=#frame[0].container[0].panels# ]
    
            [ELEMENT index=0]
    
                //Definizione elemento
    
            [ELEMENT].
    
        [ELEMENTS].
    
    
    [ELEMENTS=0]
    Ultima modifica di jabjoint; 12-03-2025 a 12:25
    jabjoint

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