Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 14
  1. #1
    Utente di HTML.it L'avatar di ZannaZ
    Registrato dal
    May 2006
    Messaggi
    82

    [SWING]Posizionare JButton su più righe

    Come faccio ad inserire dei JButton, con dimensione fissata, su più righe se sono troppi per starcene su di una?
    Perché il FlowLayout rende non visibili quelli che non ci stanno su di una riga*, mentre il GridLayout che sarebbe perfetto, tende ad occupare tutto lo spazio disponibile, ignorando la dimensione stabilita dei componenti.

    *Googleando un po' ho letto alcune guide che affermavano che nel caso una riga non bastasse per posizionare tutti i componenti, il FlowLayout si estendeva automaticamente in verticale; ma ciò non accade e nella documentazione delle API standard ciò non è spiegato chiaramente.

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284

    Re: [SWING]Posizionare JButton su più righe

    Originariamente inviato da ZannaZ
    Come faccio ad inserire dei JButton, con dimensione fissata, su più righe se sono troppi per starcene su di una?
    Perché il FlowLayout rende non visibili quelli che non ci stanno su di una riga*, mentre il GridLayout che sarebbe perfetto, tende ad occupare tutto lo spazio disponibile, ignorando la dimensione stabilita dei componenti.

    *Googleando un po' ho letto alcune guide che affermavano che nel caso una riga non bastasse per posizionare tutti i componenti, il FlowLayout si estendeva automaticamente in verticale; ma ciò non accade e nella documentazione delle API standard ciò non è spiegato chiaramente.
    Ti suggerisco di leggere:
    Effective Layout Management: Short Course
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  3. #3
    Utente di HTML.it L'avatar di ZannaZ
    Registrato dal
    May 2006
    Messaggi
    82

    Re: Re: [SWING]Posizionare JButton su più righe

    Originariamente inviato da andbin
    Ti suggerisco di leggere:
    Effective Layout Management: Short Course
    Innanzitutto grazie della risposta.
    Leggendo il tutorial di cui hai postato il link sono riuscito a capire il perché non riuscivo a fare ciò che avevo intenzione di fare: il FlowLayout non occupa più di una riga se è annidato in un container organizzato attraverso un BorderLayout.
    Tuttavia non sono ancora riuscito a trovare un modo per superare quest'ostacolo: sempre nello stesso tutorial ho letto che un modo per ovviare ciò è annidare il pannello nel quale sono contenuti i bottoni come componente Nord di un altro pannello formattato a BorderLayout; tuttavia i bottoni continuano lo stesso ad occupare tutto lo spazio a disposizione, se il pannello che contiene i bottoni è impostato come GridLayout, o a posizionarli su di una sola riga, se impostato come FlowLayout.
    Soluzioni alternative?

  4. #4
    Utente di HTML.it
    Registrato dal
    Jan 2009
    Messaggi
    9
    Guarda..siccome ce l'ho fresco fresco, ke anke io sto facendo ste cose ti do dei piccoli suggerimenti:

    innanzi tutto fai in modo ke ogni bottone abbia il suo pannello,
    così quando fai

    panel.add(button)

    il bottone si attacca al pannello così come tu lo imposti.

    poi col Gridlayout dividi il pannello sottostante al quale attaccherai tutti gli altri piccoli pannelli....così saranno i piccoli pannelli ad "adattarsi" alle dimensioni della griglia, e non il bottone, xkè in questo modo il bottone non è a stretto contatto con la griglia.

    L'annidamento dei pannelli è la soluzione ideale.

    se ho capito bene il tuo problema, questo è un metodo a prova di bomba, altrimenti scusa l'intrusione!

  5. #5
    Utente di HTML.it L'avatar di ZannaZ
    Registrato dal
    May 2006
    Messaggi
    82
    Grande!! Era proprio la soluzione che cercavo! Grazie!
    Non è che conosci una guida che elenchi tutta questa serie di "trucchetti" ?

    Poi avrei un'altra domanda... ho formattato il frame principale attraverso il BorderLayout. Al centro ci ho piazzato un pannello che contiene due JButton; tuttavia questi bottoni sono allineati al centro orizzontalmente, ma non verticalmente; io vorrei che fossero proprio al centro del pannello, sia orizzontalmente che verticalmente. Come posso fare?

    Ehm... ho ancora un'altra domanda un po' puntigliosa, e che credo rimarrà senza risposta, ma ci provo comunque: ritornando al pannello che contiene i JButton (quello per cui ho aperto il topic), se i JButton vengono eliminati, il GridLayout tende ad occupare comunque tutte le righe che può occupare; nel senso: io ho impostato il Grid 2x4, quando mi rimangono 4 bottoni, il GridLayout ne posizionerà 2 su di una riga e 2 sull'altra; non c'è la possibilità di in quel caso posizionarli tutti su una riga?

    Grazie ancora.

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da ZannaZ
    Grande!! Era proprio la soluzione che cercavo! Grazie!
    Non è che conosci una guida che elenchi tutta questa serie di "trucchetti" ?
    Non è che sono trucchetti ... basta conoscere come si comportano i vari layout manager e realizzare una interfaccia utente "impacchettando" componenti dentro contenitori dentro altri contenitori ecc.... Questo è il "trucco".

    Originariamente inviato da ZannaZ
    Poi avrei un'altra domanda... ho formattato il frame principale attraverso il BorderLayout. Al centro ci ho piazzato un pannello che contiene due JButton; tuttavia questi bottoni sono allineati al centro orizzontalmente, ma non verticalmente; io vorrei che fossero proprio al centro del pannello, sia orizzontalmente che verticalmente. Come posso fare?
    Nella parte CENTER hai sicuramente messo un qualche "contenitore" (es. JPanel) non certo direttamente i due JButton. JPanel per default ha un FlowLayout con align CENTER, quindi in tal caso sono centrati orizzontalmente. Non lo sono verticalment perchè ovviamente non è una funzionalità di FlowLayout!!

    Soluzioni? Diverse ovviamente. Usare un GridBagLayout con dei constraint tali per cui un JPanel (con dentro i 2 JButton) stia al centro. Oppure usare un BoxLayout orientato verticalmente che contiene in sequenza un "glue" verticale (Box.createVerticalGlue()), poi un JPanel con FlowLayout CENTER (con dentro 2 JButton) e un altro glue verticale. (i due glue si spartiscono a metà lo spazio rimanente)
    O altro.

    Originariamente inviato da ZannaZ
    se i JButton vengono eliminati, il GridLayout tende ad occupare comunque tutte le righe che può occupare; nel senso: io ho impostato il Grid 2x4, quando mi rimangono 4 bottoni, il GridLayout ne posizionerà 2 su di una riga e 2 sull'altra; non c'è la possibilità di in quel caso posizionarli tutti su una riga?
    Imposta righe e/o colonne ... GridLayout ha setRows()/setColumns().
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  7. #7
    Utente di HTML.it L'avatar di ZannaZ
    Registrato dal
    May 2006
    Messaggi
    82
    @andbin: grazie per i suggerimenti! Il GridBagLayout non lo conosco e da quanto ho letto sembra piuttosto complicato da utilizzare; credo che utilizzerò il BoxLayout.

    Originariamente inviato da andbin
    Imposta righe e/o colonne ... GridLayout ha setRows()/setColumns().
    Il problema è che mi piacerebbe evitare un controllo del numero di JButton per settare le necessarie righe; sarebbe bello se i componenti potessero "fluire" su più righe a seconda del loro numero; mi sono accorto anch'io che questa è proprio la funzionalità del FlowLayout, ma non potendolo utilizzare annidato in un altro pannello proprio per i motivi che mi hanno indotto ad aprire questo topic...

  8. #8
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da ZannaZ
    mi sono accorto anch'io che questa è proprio la funzionalità del FlowLayout, ma non potendolo utilizzare annidato in un altro pannello proprio per i motivi che mi hanno indotto ad aprire questo topic...
    Se un contenitore X ha un FlowLayout, allora X non dovrebbe essere messo in un contenitore Y il cui layout manager rispetta il "preferred height" (è quello che succede nelle parti NORTH e SOUTH di BorderLayout). Questo perché il preferred height di FlowLayout è sempre solo quello di 1 riga.
    Altrimenti non ci sono problemi (es. in CENTER di BorderLayout "fluisce" bene).
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  9. #9
    Utente di HTML.it L'avatar di ZannaZ
    Registrato dal
    May 2006
    Messaggi
    82
    Originariamente inviato da andbin
    Se un contenitore X ha un FlowLayout, allora X non dovrebbe essere messo in un contenitore Y il cui layout manager rispetta il "preferred height" (è quello che succede nelle parti NORTH e SOUTH di BorderLayout). Questo perché il preferred height di FlowLayout è sempre solo quello di 1 riga.
    Altrimenti non ci sono problemi (es. in CENTER di BorderLayout "fluisce" bene).
    No, infatti... tutto questo era spiegato molto bene nella guida che mi hai linkato. Il problema è che il flow layout mi servirebbe proprio in NORTH e SOUTH, ma poco importa.
    Per i due bottoni centrali ho seguito le tue indicazioni e ho utilizzato un BoxLayout e tutto ora funziona proprio come volevo

  10. #10
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Originariamente inviato da ZannaZ
    Il problema è che il flow layout mi servirebbe proprio in NORTH e SOUTH
    Si potrebbe realizzare un layout manager specifico simile al FlowLayout ma che fornisca un preferred height corretto, cioè che metta in conto tutte le "righe" di componenti.

    Ed è proprio quello che ho fatto nel mio seguente esempio. Prova a ridimensionare orizzontalmente la finestra e vedrai che i pulsanti fluiscono bene e la parte CENTER si modifica per fare più o meno spazio alla parte NORTH.

    codice:
    import java.awt.*;
    import javax.swing.*;
    
    public class TestFrame extends JFrame {
        public TestFrame() {
            super ("Test");
    
            setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
            setSize(300, 300);
    
            Container contentPane = getContentPane();
    
            JPanel panel = new JPanel(new ExpandableFlowLayout());
    
            for (int i = 1; i <= 12; i++) {
                panel.add(new JButton("" + i));
            }
    
            contentPane.add(panel, BorderLayout.NORTH);
            contentPane.add(new JButton("ABC"), BorderLayout.CENTER);
        }
    
        public static void main(String[] args) {
            SwingUtilities.invokeLater(new Runnable() {
                public void run() {
                    TestFrame f = new TestFrame();
                    f.setVisible(true);
                }
            });
        }
    }
    
    
    class ExpandableFlowLayout implements LayoutManager {
        private Dimension dimension;
    
        public void addLayoutComponent(String name, Component comp) { /* no, uso getComponents */ }
        public void removeLayoutComponent(Component comp) { /* no, uso getComponents */ }
    
        public Dimension minimumLayoutSize(Container parent) {
            return preferredLayoutSize(parent);
        }
    
        public Dimension preferredLayoutSize(Container parent) {
            if (dimension == null || dimension.width != parent.getSize().width) {
                calcDimension(parent);
            }
    
            return dimension;
        }
    
        public void layoutContainer(Container parent) {
            Component[] components = parent.getComponents();
    
            Dimension parentSize = parent.getSize();
    
            int maxHeight = 0;
            int x = 0;
            int y = 0;
    
            for (int i = 0; i < components.length; i++) {
                Component c = components[i];
    
                if (c.isVisible()) {
                    Dimension size = c.getPreferredSize();
    
                    if (x + size.width > parentSize.width) {
                        x = 0;
                        y += maxHeight;
                        maxHeight = 0;
                    }
    
                    c.setSize(size);
                    c.setLocation(x, y);
    
                    x += size.width;
    
                    if (size.height > maxHeight) {
                        maxHeight = size.height;
                    }
                }
            }
    
            dimension = new Dimension(parentSize.width, y + maxHeight);
        }
    
    
        private void calcDimension(Container parent) {
            Component[] components = parent.getComponents();
    
            Dimension parentSize = parent.getSize();
    
            int maxHeight = 0;
            int x = 0;
            int y = 0;
    
            for (int i = 0; i < components.length; i++) {
                Component c = components[i];
    
                if (c.isVisible()) {
                    Dimension size = c.getPreferredSize();
    
                    if (x + size.width > parentSize.width) {
                        x = 0;
                        y += maxHeight;
                        maxHeight = 0;
                    }
    
                    x += size.width;
    
                    if (size.height > maxHeight) {
                        maxHeight = size.height;
                    }
                }
            }
    
            dimension = new Dimension(parentSize.width, y + maxHeight);
        }
    }
    È molto "grezzo" come layout manager, non gestisce dei hgap/vgap come FlowLayout e nemmeno un alignment. E non prende in considerazione gli "insets" (se presenti) del container. In meno di 100 righe di codice non è che si possa fare granchè ....

    Però vedi che è possibile, basterebbe solo avere un po' più di tempo (e voglia) e si potrebbe realizzare un layout manager più completo. Chiaro ... ci sarebbero da fare molti più calcoli e controlli.
    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 © 2025 vBulletin Solutions, Inc. All rights reserved.