Visualizzazione dei risultati da 1 a 8 su 8
  1. #1
    Utente di HTML.it
    Registrato dal
    May 2007
    Messaggi
    14

    problema con il repaint() in Java

    ragazzi ho un problema quando effettuo il repaint del mio frame in java il layout degli oggetti viene completamente stravolto mentre vorrei mantenere il layout identico come posso fare??

    In pratica è un programma che quando schiaccio sul pulsante mi dovrebbe scambiare la prima immagine con la seconda

    Posto il codice :

    import javax.swing.*;
    import java.awt.*;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;

    public class MyPanel extends JPanel
    {

    public MyPanel(MyFrame p_frame)
    {
    frame = p_frame;

    //inizializziamo gli oggetti grafici (varibili istanza)
    homer1= new JLabel("<html>[b]Homer1[b]
    </html>");
    homer2= new JLabel("<html>[b]Homer2[b]
    </html>");
    immagine1 = new JLabel(new ImageIcon("1_Homer.jpg"));
    immagine2 = new JLabel(new ImageIcon("2_Homer.jpg"));
    bottone = new JButton("<html>[b]Start[b]
    </html>");
    this.disegna();



    //registriamo il Listener (Ascoltatore) alla sorgente (bottone)
    // relativamente all'evento ActionListener (pressione del pulsante)

    bottone.addActionListener(new Ascoltatore(this));

    }

    private class Ascoltatore implements ActionListener
    {

    public Ascoltatore(MyPanel p_panel)
    {
    panel = p_panel;

    }

    public void actionPerformed(ActionEvent e)
    {

    JLabel immagine3 = immagine1;
    immagine1 = immagine2;
    immagine2 = immagine3;
    panel.disegna();
    frame.validate();
    frame.repaint();
    }

    private MyPanel panel;
    }

    public void disegna()
    {

    this.setLayout(layout);
    //inseriamo gli oggetti grafici nel pannello utilizzando il LayoutManger

    //inseriamo la prima JLabel (0,0)
    lim.gridx = 0;
    lim.gridy = 0;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(homer1, lim);
    this.add(homer1);

    //inseriamo la seconda JLabel (0,1)
    lim.gridx = 1;
    lim.gridy = 0;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(homer2, lim);
    this.add(homer2);


    //inseriamo la prima immagine (1,0)
    lim.gridx = 0;
    lim.gridy = 1;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(immagine1, lim);
    this.add(immagine1);

    //inseriamo la seconda immagine (1,1)
    lim.gridx = 1;
    lim.gridy = 1;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(immagine2, lim);
    this.add(immagine2);

    //inseriamo il JButton (2,0) e (2,1)
    lim.gridx = 0;
    lim.gridy = 2;
    lim.gridwidth =2;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(bottone, lim);
    this.add(bottone);

    }





    private MyFrame frame;
    private GridBagLayout layout = new GridBagLayout();
    private GridBagConstraints lim = new GridBagConstraints();
    private JButton bottone;
    private JLabel homer1;
    private JLabel homer2;
    private JLabel immagine1;
    private JLabel immagine2;


    }

    ecco cosa esce :

    PRIMA : http://a.imagehost.org/view/0095/prima
    DOPO : http://a.imagehost.org/view/0346/dopo

    Grazie a tutti.

  2. #2
    Non so....potresti provare a fare il repaint solo del componente che devi aggiornare.

    oppure potresti vedere se con il metodo pack() ottieni risultati migliori

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

    Re: problema con il repaint() in Java

    Originariamente inviato da niko82
    ragazzi ho un problema quando effettuo il repaint del mio frame in java il layout degli oggetti viene completamente stravolto mentre vorrei mantenere il layout identico come posso fare??
    Direi che è abbastanza inutile (e contorto) fare di nuovo tutto quel "giro" di impostazioni dei componenti nel layout.

    Volevi semplicemente cambiare le immagini nei JLabel? Tieniti gli ImageIcon da qualche parte e cambia semplicemente la proprietà icon del JLabel:

    label.setIcon(....);
    Andrea, andbin.devSenior Java developerSCJP 5 (91%) • SCWCD 5 (94%)
    java.util.function Interfaces Cheat SheetJava Versions Cheat Sheet

  4. #4
    Utente di HTML.it
    Registrato dal
    May 2007
    Messaggi
    14

    Grazie

    Andbin si effettivamente cambiano il metodo in :

    public void actionPerformed(ActionEvent e)
    {

    Icon img1 = immagine1.getIcon();
    Icon img2 = immagine2.getIcon();

    immagine1.setIcon(img2);
    immagine2.setIcon(img1);

    frame.validate();
    frame.repaint();
    }

    tutto funziona a meraviglia. Però siccome ti vedo molto preparato sapresti spiegarmi perchè la soluzione proposta da me prima anche se poco efficiente non funzionava?? Perchè fare dei passi inutili non significa che siano sbagliati giusto? In realtà quello che non capisco è : siccome nel costruttore chiamo il metodo disegna() e nel metodo actionPerformed chiamavo lo stesso metodo (disegna()) perchè il layout non veniva mantenuto??

    Cioè se premendo il Jbutton voglio ad esempio cambiare il layout della mia applicazione a questo punto non sono più certo che cambiando le impostazioni del GridBagLayout e ridisegnando il frame funzioni.. cmq ora provo a scambiare non solo le immagini tra loro ma anche il posto delle JLabel iniziali con il posto delle Immagini e vedo che succede.

  5. #5
    Utente di HTML.it
    Registrato dal
    May 2007
    Messaggi
    14

    Infatti come pensavo

    infatti se voglio cambiare il layout del frame corrente si sballa tutto e non capisco il perchè :

    Ti posto il codice del metodo :

    private class Ascoltatore implements ActionListener
    {
    public Ascoltatore(MyPanel pannello)
    {
    panel = pannello;
    }



    public void actionPerformed(ActionEvent e)
    {

    //scambio le immagini
    Icon img1 = immagine1.getIcon();
    Icon img2 = immagine2.getIcon();
    immagine1.setIcon(img2);
    immagine2.setIcon(img1);

    //scambio i posti
    lim.gridx = 0;
    lim.gridy = 0;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(immagine1, lim);
    panel.add(immagine1);

    //inseriamo la seconda JLabel (0,1)
    lim.gridx = 1;
    lim.gridy = 0;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(immagine2, lim);
    panel.add(immagine2);


    //inseriamo la prima immagine (1,0)
    lim.gridx = 0;
    lim.gridy = 1;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(homer1, lim);
    panel.add(homer1);

    //inseriamo la seconda immagine (1,1)
    lim.gridx = 1;
    lim.gridy = 1;
    lim.gridwidth =1;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(homer2, lim);
    panel.add(homer2);

    //inseriamo il JButton (2,0) e (2,1)
    lim.gridx = 0;
    lim.gridy = 2;
    lim.gridwidth =2;
    lim.gridheight=1;
    lim.weightx=0;
    lim.weighty=0;
    lim.fill = GridBagConstraints.NONE;
    layout.setConstraints(bottone, lim);
    panel.add(bottone);





    //ridisegno tutto

    /* non funziona nemmeno così
    Container pannello = frame.getContentPane();
    pannello.add(panel);
    */
    frame.validate();
    frame.repaint();
    }


    Secondo te come devo fare a ridisegnare il layout di un frame ??
    Ciao Grazie.

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

    Re: Grazie

    Originariamente inviato da niko82
    frame.validate();
    frame.repaint();
    Se cambi solo la proprietà "icon" dei JLabel, allora validate()/repaint() non servono affatto. È già il JLabel che internamente "sa" come/dove/quando ridisegnarsi!!

    Originariamente inviato da niko82
    sapresti spiegarmi perchè la soluzione proposta da me prima anche se poco efficiente non funzionava??
    GridBagLayout è un layout manager abbastanza complesso (meno complicato di altri comunque ) e non è certo "perfetto" .... anzi le sue pecche le ha!

    E come spiega bene qui, GridBagLayout ha delle "noie" quando si cerca di aggiungere/rimuovere componenti dopo che è già visibile.

    In passato ho provato anche io a cambiare/stravolgere il layout in un GridBagLayout dopo che era già visibile ed ero incappato anch'io nello stesso problema. E il validate() non funziona, nemmeno un repaint(), nemmeno se combinati insieme.

    Quindi generalmente sarebbe preferibile non "toccare" un GridBagLayout dopo che è già visibile. Insomma... crei la tua interfaccia con GridBagLayout, la rendi visibile e basta.

    Se proprio vuoi provare a cambiare il layout di un GridBagLayout si potrebbero provare i seguenti stratagemmi, prova in sequenza:

    a) Rimuovere tutti i componenti (removeAll()) e poi reinserirli tutti reimpostando i constraints e facendo alla fine un validate() sul contenitore.

    oppure

    b) Istanziare un nuovo GridBagLayout, risettarlo nel contenitore e risettare i constraints e fare alla fine un validate() sul contenitore.

    oppure

    c) Usare un JPanel "in mezzo", ovvero tutta la tua interfaccia è in un JPanel con il GridBagLayout che sta dentro, a sua volta, un altro contenitore (es. il content pane con BorderLayout di un JFrame).
    Ricrei da zero un JPanel con tutto nuovo (GridBagLayout, componenti, ecc...), rimuovi il vecchio JPanel dal content pane e inserisci il nuovo, facendo il validate() sul content pane.

    Non so se e quale dei tre approcci può funzionare .... dovrei provare. Se nessuno di questi funziona ... dovrei pensarci.

    E comunque, come ho detto prima, se la tua intenzione era solo quella di scambiare le immagini, basta setIcon.
    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 2007
    Messaggi
    14

    grazie

    wow quante informazioni utili ti ringrazio.
    Peccato pensavo di aver trovato il paradiso con il GridBagLayout perchè tra tutti i layout sembra quello più flessibile...cmq in ogni caso appena possibile proverò tutte e 3 le soluzioni proposte da te e ti faccio sapere se e quali funzionano. A presto.

    In caso che non riusciamo a risolvere questo problema.. che LayoutManager mi consigli di usare..io miro ad imparare un LayoutManager da utilizzare sempre in tutte le occasioni quindi (Flow,Grid e Border li vedo troppo special purpose). Non esiste un LayoutManager che ti permette di dare le coordinate relative rispetto ad un altro componente (ad esempio questo bottone è 50px a nord di quest'altro) parlando con un ragazzo ieri ho scoperto che in SWT qualcosa del genere esiste.

    Grazie.

    Saluti.

  8. #8
    Utente di HTML.it
    Registrato dal
    May 2007
    Messaggi
    14
    ah ecco quello che dicevi :
    There are a few bugs in GridBagLayout that evidence themselves after components are added to or removed from the GridBagLayout after the GridBagLayout has been displayed
    Note: GridBagLayout maintains some internal state that sometimes gets confused when components are added and removed.

    Però addirittura non mi aspettavo che la Sun stessa ne sconsiglia l'uso :
    Without a GUI builder like VisualAge for Java or JBuilder, you should avoid GridBagLayout if at all possible.

    A dire il vero per quello che ho capito di questo Layout Manager mi sembrava il più completo e con il quale davvero puoi disegnare il layout che vuoi senza compromessi..peccato per i bugs e mi chiedo anche perchè non li risolvano

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.