Pagina 1 di 2 1 2 ultimoultimo
Visualizzazione dei risultati da 1 a 10 su 16

Discussione: JPanel con scrool

  1. #1
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    81

    JPanel con scrool

    Salve, come da oggetto avrei l'esigenza di scrollare un JPanel all'interno di JScroolPane.
    La cosa non è ardua. In linea di massima è semplice se consideriamo il codice (non è il codice del mio programma, riporto questo perchè è molto più semplice):

    import javax.swing.*;
    import java.awt.*;
    public class Frame01 {
    public static void main(String[] args){
    JFrame frame = new JFrame("panel demo");
    JPanel panel = new JPanel();
    Container c = frame.getContentPane();
    panel.setSize(100,100);
    panel.setLayout(new GridLayout(1000,1));
    for(int i = 0; i<1000;i++)
    panel.add(new JLabel("JLabel "+i));

    JScrollPane jsp = new JScrollPane(panel);
    c.add(jsp);
    frame.setSize(100,100);
    frame.setVisible(true);

    }
    }


    ecco ma io nel mio lavoro devo praticamente fare quello che c'è nel codice utilizzando perà "null" come layoutmanager al posto del GridLayout. Perchè?

    Ho un Pannello contenitore che deve essere scrollato.
    All'interno devo mettere dei piccoli pannelli di dimensione fissa (150x100)
    Il gridlayout non va bene perchè mi ridimensiona i pannelli secondo lo spazio possibile e tramite altri layout manager non riesco a fare questo lavoro.

    Ma in un Layout null, mi calcolo le varie coordinate dei pannelli e li inserisco. Piano piano questi pannelli vanno aumentando e finche sono un tot, ci entrano nel pannello contenitore. Quando non ci entrano più, sono sempre aggiunti al pannello ma non più visualizzati.

    Ecco perchè ho bisogno di scrollare quel pannello.

    Con layoutmanager settato a null, il JScroolPane non vuole saperne. E' come se non capisse la dimensione del pannello al suo interno.

    Qualcuno può aiutarmi? grazie

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    JPanel non è un componente scrollabile... non implementa l'interfaccia "Scrollable", quindi, inserirlo all'interno di un JScrollPane non ha alcun effetto.

    Se vuoi rendere scrollabile un pannello, devi gestire tutto a mano: ridimensionamenti e notifiche al JScrollPane.

    Fai una ricerca in questo forum... se ne è parlato molte volte negli ultimi mesi.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    81
    Originariamente inviato da LeleFT
    JPanel non è un componente scrollabile... non implementa l'interfaccia "Scrollable", quindi, inserirlo all'interno di un JScrollPane non ha alcun effetto.

    Se vuoi rendere scrollabile un pannello, devi gestire tutto a mano: ridimensionamenti e notifiche al JScrollPane.

    Fai una ricerca in questo forum... se ne è parlato molte volte negli ultimi mesi.


    Ciao.
    eppure se vedi quel codice che ho messo sopra, quello funziona e diventa scrollabile...
    volevo cmw capire come fare tutto a mano

  4. #4
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Per fare tutto a mano hai due strade, essenzialmente:

    1) Estendere la classe JPanel in modo da farle implementare Scrollable (e, di conseguenza, implementarne tutti i metodi + getPreferredSize() )

    2) Tenere traccia, ad ogni add sul pannello, della posizione e dimensione del nuovo oggetto aggiunto, mantenendo le informazioni sulla dimensione minima che il pannello deve avere per poter contenere tutti gli oggetti aggiunti, quindi notificando il ViewPort del JScrollPane di questa dimensione.

    La prima strada è più semplice e pulita... questo è un esempio banale di un pannello scrollabile, in cui gli oggetti possono essere posizionati in modo assoluto (il LayoutManager è nullo):

    codice:
    public class ScrollablePanel extends JPanel implements Scrollable {
       private Dimension minDimension;
    
       public ScrollablePanel() {
          this( new Dimension(0, 0) );
       }
    
       public ScrollablePanel(Dimension minDimension) {
          this.minDimension = minDimension;
          setLayout( null );
       }
       
       @Override
       public Dimension getPreferredSize() { return getPreferredScrollableViewportSize(); }
    
       @Override
       public Dimension getPreferredScrollableViewportSize() {
          Dimension ret = (minDimension != null) ? minDimension : new Dimension(0, 0);
    
          Component[] content = getComponents();
          for(Component c : content) {
             Point loc = c.getLocation();
             Dimension dim = c.getSize();
             if ((loc.x + dim.width) > ret.width) ret.width = loc.x + dim.width;
             if ((loc.y + dim.height) > ret.height) ret.height = loc.y + dim.height;
          }
    
          return ret;
       }
    
       @Override
       public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
           return 10;
       }
       
       @Override
       public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
           return 1;
       }
       
       @Override
       public boolean getScrollableTracksViewportHeight() { return false; }
       
       @Override
       public boolean getScrollableTracksViewportWidth() { return false; }
       
    }
    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  5. #5
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    81
    grazie tante, ci studierò un po e vedo cosa posso buttare giù.
    Ti faccio sapere.

    Domanda? come mai con i layoutmanager il panel diventa scrollabile? sono i lm che implementano quella interfaccia?

  6. #6
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    Originariamente inviato da foralobo
    Domanda? come mai con i layoutmanager il panel diventa scrollabile? sono i lm che implementano quella interfaccia?
    I LayoutManager non c'entrano nulla. Servono solo a decidere come disporre e dimensionare i componenti all'interno dei contenitori.

    Ciò che rende "scrollabile" un componente è l'implementazione dell'interfaccia Scrollable.
    Tale interfaccia viene usata dai componenti che sono in grado di "scrollare" gli oggetti (come JScrollPane).

    Quindi... JScrollPane è il componente che si occupa di scrollare gli oggetti "scrollabili".
    Gli oggetti scrollabili sono tutti quelli che implementano l'interfaccia Scrollable.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  7. #7
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    81
    perdonami ancora lele ma il codice che ho postato io rende scrollabile il jpanel (e funziona).
    Come è possibile se implementa l'interfaccia "scollable"?

  8. #8
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,326
    In realtà il tuo codice crea un pannello di dimensione fissa. La dimensione del tuo pannello è data dall'uso del GridLayout. GridLayout, che si occupa appunto del posizionamento e dimensionamento dei suoi componenti, prende il preferredSize di ciascuno dei suoi componenti e lo confronta con la dimensione del contenitore (la finestra).

    Siccome 1000 Label occunao molto più di 100 pixel (dimensione che tu hai impostato per la finestra), allora il GridLayout impone al pannello una dimensione tale da poter contenere tutte le label. Questo fa sì che il JScrollPane sia costretto a scrollare.

    Ma cosa accade, invece, se al posto di avere 1000 label ne hai solo 2? Prova e vedrai che il pannello non sarà più "scrollabile", ma si adatterà alla dimensione della finestra, allargando le Label man mano che ne aumenti la dimensione... non è esattamente il comportamento di un oggetto scrollabile. Un oggetto scrollabile, non fa aumentare le dimensioni del suo contenuto.

    Questo perchè il GridLayout funziona esattamente così: prende il preferredSize delle due label, verifica che la dimensione della finestra è maggiore di quella necessaria per visualizzarle di conseguenza adatta il contenuto (le due label) al contenitore.

    PS: JPanel NON implementa l'interfaccia Scrolalble.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  9. #9
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    81
    Se vuoi rendere scrollabile un pannello, devi gestire tutto a mano: ridimensionamenti e notifiche al JScrollPane.
    Sto facendo delle prove. Ho preso anche come codice di esempio un tuo codice di un post:

    codice:
    import java.awt.*;
    import javax.swing.*;
    import java.awt.event.*;
    
    public class ProvaPannelli extends JFrame implements ActionListener {
    
       private JPanel pannello;
       private JScrollPane scroller;
       private JButton cmdAggiungi;
       private int count;
    
       public ProvaPannelli() {
          count = 0;
    
          Container c = getContentPane();
          c.setLayout( new BorderLayout() );
    
          pannello = new JPanel();
          pannello.setLayout( null );
    
          scroller = new JScrollPane( pannello );
    
          cmdAggiungi = new JButton("Aggiungi Label");
          cmdAggiungi.addActionListener( this );
    
          JPanel jpCmd = new JPanel( new FlowLayout(FlowLayout.CENTER, 10, 10) );
          jpCmd.add( cmdAggiungi );
    
          c.add(scroller, BorderLayout.CENTER);
          c.add(jpCmd, BorderLayout.SOUTH);
    
          setDefaultCloseOperation( EXIT_ON_CLOSE );
          setTitle("Prova Pannelli");
          setResizable( true );
          setSize(800, 600);
          setVisible( true );
       }
    
       public void actionPerformed(ActionEvent ae) {
          JLabel lbl = new JLabel("Label numero " + (count+1));
          lbl.setBounds(10, (count * 20)+1, 100, 20);
          count++;
          pannello.add( lbl );
          Dimension d = pannello.getSize();
          if (d.height < (count * 20)) {
             // Devo ridimensionare il pannello
             d.height = (count * 20);
             pannello.setPreferredSize( d );
             pannello.repaint();
             pannello.doLayout();
             scroller.getViewport().doLayout();
          }
          repaint();
          doLayout();
       }
    
       public static void main(String[] args) {
          ProvaPannelli pp = new ProvaPannelli();
       }
    }
    che funziona perfettamente.

    Tuttavia non riesco a far funzionare un mio codice (questa è solo una parte):




    codice:
     private void VisualizzaSchermi() {
    	   if (!Schermi.isEmpty()){
    		   		   
    		   int larghezzaSchermo = Schermi.get(0).getWidth();
    		   int altezzaSchermo = Schermi.get(0).getHeight();
    		   int nCol = panelScreens.getWidth() / larghezzaSchermo;
    
    		   int spazio = (panelScreens.getWidth() - (nCol * larghezzaSchermo)) / (nCol + 2) ;
    		   		   
    		   int cont = 0;
    		   int x = spazio;
    		   int y = 5;
    		   
    		   double altezzaPannello = (Schermi.size() / nCol) * altezzaSchermo;
    		   txtdebug2.setText(String.valueOf(altezzaPannello));
    		   
    		   
    		   //panelScreens.setBackground(Color.BLUE);
    		   
    		   for (int i = 0 ; i < Schermi.size(); i++) {
    			   //Sposta coordinata x
    			   if (cont > 0 && cont <= nCol) {
    				  x += larghezzaSchermo + spazio;
    			   }   
    			   
    			   //Va a capo e sposta coordinata y
    			   if ( cont == nCol ) {
    				   x  = spazio;
    				   y += altezzaSchermo + 5;		
    				   cont = 0;
    			   }
    			   //Stampa il pannello
    			   Schermi.get(i).setLocation(x, y);
    			   panelScreens.add(Schermi.get(i));
    			   cont++;
    		   }
    		   
    		   panelScreens.repaint();
    		   panelScreens.setPreferredSize( new Dimension( 800 , 1000));
    		   panelScreens.doLayout();
    		   scrollInfo.getViewport().doLayout();
    		   
    		   
    		   repaint();
    		   doLayout();
    		   
    		  txtdebug.setText( String.valueOf(Schermi.size() ));	   
    	   }
    	   
    	   
    	   
       }
    E' questa la parte in questione, puoi dargli un'occhiata?
    Queste prove sono per studiarci un po' su ma credo farò un panel scrollabile come mi8hai suggerito

    grazie

  10. #10
    Utente di HTML.it
    Registrato dal
    Feb 2011
    Messaggi
    81
    Originariamente inviato da LeleFT
    Per fare tutto a mano hai due strade, essenzialmente:

    1) Estendere la classe JPanel in modo da farle implementare Scrollable (e, di conseguenza, implementarne tutti i metodi + getPreferredSize() )

    2) Tenere traccia, ad ogni add sul pannello, della posizione e dimensione del nuovo oggetto aggiunto, mantenendo le informazioni sulla dimensione minima che il pannello deve avere per poter contenere tutti gli oggetti aggiunti, quindi notificando il ViewPort del JScrollPane di questa dimensione.

    La prima strada è più semplice e pulita... questo è un esempio banale di un pannello scrollabile, in cui gli oggetti possono essere posizionati in modo assoluto (il LayoutManager è nullo):

    codice:
    public class ScrollablePanel extends JPanel implements Scrollable {
       private Dimension minDimension;
    
       public ScrollablePanel() {
          this( new Dimension(0, 0) );
       }
    
       public ScrollablePanel(Dimension minDimension) {
          this.minDimension = minDimension;
          setLayout( null );
       }
       
       @Override
       public Dimension getPreferredSize() { return getPreferredScrollableViewportSize(); }
    
       @Override
       public Dimension getPreferredScrollableViewportSize() {
          Dimension ret = (minDimension != null) ? minDimension : new Dimension(0, 0);
    
          Component[] content = getComponents();
          for(Component c : content) {
             Point loc = c.getLocation();
             Dimension dim = c.getSize();
             if ((loc.x + dim.width) > ret.width) ret.width = loc.x + dim.width;
             if ((loc.y + dim.height) > ret.height) ret.height = loc.y + dim.height;
          }
    
          return ret;
       }
    
       @Override
       public int getScrollableBlockIncrement(Rectangle visibleRect, int orientation, int direction) {
           return 10;
       }
       
       @Override
       public int getScrollableUnitIncrement(Rectangle visibleRect, int orientation, int direction) {
           return 1;
       }
       
       @Override
       public boolean getScrollableTracksViewportHeight() { return false; }
       
       @Override
       public boolean getScrollableTracksViewportWidth() { return false; }
       
    }
    Ciao.
    Ciao ho provato ad usare questo codice ma quando lo inserisco all'interno di un frame mi scompare tutto..

    pur vedendo la documentazione non riesco a capire a cosa servono tutti metodi che l'interfaccia scrollable implemanta.

    potresti spiegarmeli brevemente?

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.