Visualizzazione dei risultati da 1 a 7 su 7
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11

    [JAVA] Come usare SwingUtilities.invokeLater

    Salve a tutti, ho creato un programma di prova per cercare di capire come usare, appunto, il metodo invokeLater con le informazioni che sono riuscito a estrapolare da varie fonti in rete. Tuttavia non mi è ancora riuscito di capire DOVE chiamare il metodo invokeLater.

    Posto il codice:
    1.Questa classe (che contiene anche il main) è la sopraclasse di quella seguente: in sostanza, qui preparo lo schema base di una dialog con un pannello, con il titolo, in cima; un pannello centrale (chiamato panel) VUOTO in cui poter aggiungere, nelle sottoclassi, ciò che si desidera; un pannello con due JButton sul fondo.
    codice:
    public class JDialogSiNo extends JDialog{
        
        private int WIDTH, HEIGHT, HEIGHTBASE;
        private float rapporto;
        
        private JLabel titolo;
    
    
        private JPanel pantitle, panbutton, sfondo;
        protected JPanel panel;
        private JButton si, no;
        
        private JFrame frame;
        private Color background, line;
        
        private GridBagLayout GBL;
        private GridBagConstraints GBC;
        
        public JDialogSiNo(JFrame f, String title, String yesButton, String noButton, int width, int height, int heightBase, float rapporto_heightBase_heightTitolo,Color backColor, Color lineColor){
    
    
            WIDTH = width;
            HEIGHT = height;
            HEIGHTBASE = heightBase;
            frame = f;
            background = backColor;
            line = lineColor;
            rapporto = rapporto_heightBase_heightTitolo;
            
            GBL = new GridBagLayout();
            GBC = new GridBagConstraints();    
            
            sfondo = new JPanel();
            pantitle = new JPanel();
            panel = new JPanel();
            panbutton = new JPanel();
            titolo = new JLabel(title);
            si = new JButton(yesButton);
            no = new JButton(noButton);
            
            SwingUtilities.invokeLater(new Runnable() {
                
                @Override
                public void run() {
                    // TODO Auto-generated method stub
                    
                    posiziona_al_centro(frame);
                    setSize(WIDTH, HEIGHT);
                    setUndecorated(true);
                    setModal(true);
                    setBackground(background);
                    
                    sfondo.setBackground(getBackground());
                    sfondo.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
                    sfondo.setLayout(GBL);    
                    
                    GBC.gridx = 0;
                    GBC.gridy = 0;
                    GBC.weightx = 1;
                    GBC.weighty = 1;
                    GBC.fill = GridBagConstraints.BOTH;
                    
                    pantitle.setLayout(new GridBagLayout());
                    pantitle.setBackground(getBackground());
                    pantitle.setPreferredSize(titolo.getPreferredSize());
                    pantitle.setMinimumSize(titolo.getMinimumSize());
                    pantitle.setMaximumSize(titolo.getMaximumSize());
                    pantitle.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, line));
                    sfondo.add(pantitle, GBC);
                        
                    GridBagConstraints gbc2 = new GridBagConstraints();
                    gbc2.gridx = 0;
                    gbc2.gridy = 0;
                    gbc2.fill = GridBagConstraints.BOTH;
                    titolo.setFont(new Font("Tahoma", Font.BOLD, 18));
                    titolo.setHorizontalAlignment(JLabel.CENTER);
                    titolo.setPreferredSize(new Dimension(WIDTH, (int)(HEIGHTBASE/rapporto)));
                    titolo.setMinimumSize(new Dimension(WIDTH, (int)(HEIGHTBASE/rapporto)));
                    titolo.setMaximumSize(new Dimension(WIDTH, (int)(HEIGHTBASE/rapporto)));
                    pantitle.add(titolo, gbc2);
                    
                    GBC.gridx = 0;
                    GBC.gridy = 0;
                    GBC.weightx = 1;
                    GBC.weighty = 1;
                    GBC.fill = GridBagConstraints.BOTH;
                    
                    pantitle.setBackground(getBackground());
                    pantitle.setPreferredSize(titolo.getPreferredSize());
                    pantitle.setMinimumSize(titolo.getMinimumSize());
                    pantitle.setMaximumSize(titolo.getMaximumSize());
                    pantitle.setBorder(BorderFactory.createMatteBorder(0, 0, 1, 0, line));
                    sfondo.add(pantitle, GBC);
                             
                    GBC.gridx = 0;
                    GBC.gridy = 1;
                    GBC.weightx = 1;
                    GBC.weighty = 1;
                            
                    panel.setBackground(getBackground());
                    int heightPanel = HEIGHT - 2*(int)(HEIGHTBASE/rapporto);
                    panel.setPreferredSize(new Dimension(WIDTH, heightPanel));
                    panel.setMinimumSize(new Dimension(WIDTH, heightPanel));
                    sfondo.add(panel, GBC);
               
                    panbutton.setLayout(new GridLayout(0,2));
                    panbutton.setBackground(getBackground());
                    
                    no.setBackground(getBackground());
                    no.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 1, line));
                    panbutton.add(no);
    
                    si.setBackground(getBackground());
                    si.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, line));
                    panbutton.add(si);
    
    
                    
                    GBC.gridx = 0;
                    GBC.gridy = 2;
                    GBC.anchor = GridBagConstraints.SOUTH;
    
                    panbutton.setPreferredSize(new Dimension(WIDTH, (int)(HEIGHTBASE/rapporto)));
                    panbutton.setMinimumSize(new Dimension(WIDTH, (int)(HEIGHTBASE/rapporto)));
                    panbutton.setMaximumSize(new Dimension(WIDTH, (int)(HEIGHTBASE/rapporto)));
                    sfondo.add(panbutton, GBC);
    
                    add(sfondo);
    //                pack();
    
                    sfondo.setVisible(true);
                    setVisible(true);
                }
            });   
        }
        
        public void posiziona_al_centro(JFrame f){
            setLocation(f.getX()+((f.getWidth()-WIDTH)/2), f.getY()+((f.getHeight()-HEIGHT)/2));
        }
        public void posiziona_al_centro(JDialog d){
            setLocation(d.getX()+((d.getWidth()-WIDTH)/2), d.getY()+((d.getHeight()-HEIGHT)/2));
        }
        public void posiziona_al_centro(JWindow w){
            setLocation(w.getX()+((w.getWidth()-WIDTH)/2), w.getY()+((w.getHeight()-HEIGHT)/2));
        }    
        
        public static void main(String[] arg0){
            
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(1200, 700);
            f.setLocation(150, 100);
            f.setVisible(true);
            
            DialogNomiGiocatori d = DialogNomiGiocatori.crea(f, "ERRORE", "Vai", "Indietro", 300, 220, 5, Color.LIGHT_GRAY, Color.CYAN, 6);
    //        d.pack();
            d.posiziona_al_centro(f);
        }
        
        public JPanel getPanel() {
            return panel;
        }
        public JButton getYesButton(){
            return si;
        }
        public JButton getNoButton(){
            return no;
        }
    }

    2. Questa invece è sottoclasse della classe JDialogSiNo (postata sopra): qui aggiungo un certo numero di righe label-textfield al panel centrale della classe madre.
    codice:
    public class DialogNomiGiocatori extends JDialogSiNo{
    
    
        private static final String NOMI_GIOCATORI = "Inserisci i nomi dei giocatori";
        
        private static int HEIGHT;
        private String[] nomi;
        private JLabel[] labels;
        private JTextField[] textfields;
        private int n_giocatori;
        
        private GridBagLayout GBL;
        private GridBagConstraints GBC;
            
        private DialogNomiGiocatori(JFrame f, String title, String yesButton, String noButton, int width, int height, int heightBase, float rapporto_height_heightTitolo, Color back, Color lines, int n_giocat) {
            super(f, title, yesButton, noButton, width, height, heightBase, rapporto_height_heightTitolo, back, lines);
            
            n_giocatori = n_giocat;
    
    
                    // TODO Auto-generated method stub
                    nomi = new String[n_giocatori];
                    labels = new JLabel[n_giocatori];
                    textfields = new JTextField[n_giocatori];
                    GBL = new GridBagLayout();
                    GBC = new GridBagConstraints();
                                
                    panel.setLayout(GBL);
                    GBC.anchor = GridBagConstraints.WEST;
                    GBC.gridx = 0;
                    GBC.gridwidth = 1;
                    GBC.insets.top = 2;
                    GBC.insets.bottom = 0;
                    GBC.weighty = 1;
                    GBC.insets.left = 7;
                    GBC.insets.right = GBC.insets.left;
                    for(int i=0; i<n_giocatori; i++){
                        labels[i] = new JLabel("Giocatore "+(i+1));
                        GBC.gridy = i;
                        panel.add(labels[i],GBC);
                        labels[i].setVisible(true);
                    }
                    
                    GBC.gridx = 1;
                    GBC.weightx = 1;
    
    
                    GBC.fill = GridBagConstraints.HORIZONTAL;
                    for(int j=0; j<n_giocatori; j++){
                        textfields[j] = new JTextField();
                        GBC.gridy = j;
                        panel.add(textfields[j], GBC);
                        textfields[j].setVisible(true);
                    }
                    
                    panel.setVisible(true);            
        }
        public static DialogNomiGiocatori crea(JFrame f, String title, String yesButton, String noButton, int width, int heightBase, float rapporto_height_heightTitolo, Color back, Color lines, int n_giocatori){
            
            float coeff = rapporto_height_heightTitolo/(rapporto_height_heightTitolo-2);
            int gioc_che_ci_stanno = (int)((heightBase/coeff)/23);
            
            if(n_giocatori<gioc_che_ci_stanno)
                HEIGHT = heightBase;
            else 
                HEIGHT = heightBase+21*(n_giocatori-gioc_che_ci_stanno+1);
            
            return new DialogNomiGiocatori(f, title, yesButton, noButton, width, HEIGHT, heightBase, rapporto_height_heightTitolo, back, lines, n_giocatori);
        }
    }
    Ora, nel codice riportato (che funziona correttamente), invokeLater è chiamato nel costruttore della CLASSE MADRE soltanto. Ho provato a chiamarlo anche nel costruttore della sottoclasse, ma in quel caso il panel centrale resta vuoto. Ho provato a chiamarlo SOLO nella sottoclasse, ma ancora nulla. Dunque non capisco: DOVE va chiamato (sto parlando più in generale, non solo per questo caso specifico) il metodo invokeLater?

  2. #2
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Pafi Visualizza il messaggio
    Salve a tutti, ho creato un programma di prova per cercare di capire come usare, appunto, il metodo invokeLater con le informazioni che sono riuscito a estrapolare da varie fonti in rete. Tuttavia non mi è ancora riuscito di capire DOVE chiamare il metodo invokeLater.
    SwingUtilities.invokeLater fa eseguire un "lavoro" (nel run() di un Runnable) nel contesto del Event Dispatch Thread. Il primo e più tipico uso è nel main() (dove sei nel "main" thread e non nel EDT) per far partire tutta la creazione della interfaccia grafica già fin da subito nel EDT.

    Es.:

    codice:
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new Runnable() {
            public void run() {
                new TuoFramePrincipale().setVisible(true);
            }
        });
    }

    Un altro uso è quando, a seguito di un evento, fai partire un thread a parte per lavori in background. Se da quel thread vuoi aggiornare la interfaccia, allora devi usare invokeLater.
    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
    Registrato dal
    May 2015
    Messaggi
    11
    Dunque, in linea di massima, lo chiamo un'unica volta quando creo il frame principale, non nei costruttori dai vari elementi grafici.Più chiaro di così
    Grazie mille

  4. #4
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Pafi Visualizza il messaggio
    Dunque, in linea di massima, lo chiamo un'unica volta quando creo il frame principale, non nei costruttori dai vari elementi grafici.
    Sì, esatto. Una volta che nel EDT hai creato il tuo primo frame (o dialog che sia), da quel momento tutta la interfaccia grafica andrà avanti per "eventi", che sono dispacciati sempre nel contesto del EDT.
    Il invokeLater torna di nuovo necessario solo quando sei in un thread a parte (es. per lavori pesanti in background, che non vanno fatti nel EDT altrimenti blocchi la interfaccia) e vuoi aggiornare la interfaccia (es. tipico una progressbar).

    Quote Originariamente inviata da Pafi Visualizza il messaggio
    Grazie mille
    Prego, son qui apposta.
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2015
    Messaggi
    11
    Emh...mi spiace doverti contraddire...Ho provato a togliere l'invokeLater dal costruttore e a metterlo nel main()...ma così facendo il pannello centrale resta vuoto...

  6. #6
    Utente di HTML.it L'avatar di andbin
    Registrato dal
    Jan 2006
    residenza
    Italy
    Messaggi
    18,284
    Quote Originariamente inviata da Pafi Visualizza il messaggio
    Emh...mi spiace doverti contraddire...Ho provato a togliere l'invokeLater dal costruttore e a metterlo nel main()...ma così facendo il pannello centrale resta vuoto...
    Ci sarà un altro motivo .... quanto ho detto è giusto. Puoi postare il codice completo attuale?
    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
    Registrato dal
    May 2015
    Messaggi
    11
    Quelle due classi costituiscono l'intero codice del programmino di prova (creo sempre dei piccoli programmi per provare i costrutti che non conosco, per essere più tranquillo riguardo agli errori causati da parti che non riguardano il "nuovo codice"). Non metto in dubbio ciò che hai detto, magari sono io che ho sbagliato a chiamare invokeLater nel main, anche se non saprei proprio come...

Tag per questa discussione

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.