2012-10-16 6 views
5

Mi piacerebbe sapere se c'è un modo per sapere quando un JScrollBar (verticale nel mio caso) ha raggiunto il fondo del suo contenente JScrollPane.Come sapere se una JScrollBar ha raggiunto il fondo di JScrollPane?

In un primo momento ho però di utilizzare un AdjustmentListener sulla barra di scorrimento, ma non so come interpretare l'attributo value dello JScrollBar. Inoltre non sono sicuro di capire correttamente cosa rappresenta il maximum e se posso usare il valore per ottenere le informazioni di cui ho bisogno.

Edit:

scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
    @Override 
    public void adjustmentValueChanged(AdjustmentEvent ae) { 
     System.out.println("Value: " + scrollPane.getVerticalScrollBar().getValue() + " Max: " + scrollPane.getVerticalScrollBar().getMaximum()); 
    } 
} 
+1

cosa vuoi ottenere? – kleopatra

+0

@kleopatra fa qualcosa ogni volta che la barra di scorrimento raggiunge la parte inferiore del riquadro. – nathan

+1

Fai cosa? Per favore sii più specifico quando qualcuno fa domande del genere. –

risposta

9

È necessario aggiungere l'estensione della barra di scorrimento per il calcolo. Ho aggiunto il codice al tuo codice nell'esempio seguente.

scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 
    @Override 
    public void adjustmentValueChanged(AdjustmentEvent ae) { 
     int extent = scrollPane.getVerticalScrollBar().getModel().getExtent(); 
     System.out.println("Value: " + (scrollPane.getVerticalScrollBar().getValue()+extent) + " Max: " + scrollPane.getVerticalScrollBar().getMaximum()); 
    } 
} 

Due implementazioni alternative (parzialmente reagire a Kleopatra)

scrollPane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 

    @Override 
    public void adjustmentValueChanged(AdjustmentEvent event) { 
     JScrollBar scrollBar = (JScrollBar) event.getAdjustable(); 
     int extent = scrollBar.getModel().getExtent(); 
     System.out.println("1. Value: " + (scrollBar.getValue() + extent) + " Max: " + scrollBar.getMaximum()); 

    } 
}); 

o tramite il modello di

scrollPane.getVerticalScrollBar().getModel().addChangeListener(new ChangeListener() { 

    @Override 
    public void stateChanged(ChangeEvent event) { 
     BoundedRangeModel model = (BoundedRangeModel) event.getSource(); 
     int extent = model.getExtent(); 
     int maximum = model.getMaximum(); 
     int value = model.getValue(); 

     System.out.println("2. Value: " + (value + extent) + " Max: " + maximum); 

    } 
}); 
+0

sostanzialmente corretto :-) Nitpicking all'accesso al scrollPane e all'immersione profonda nei suoi campi quando si posso ottenere lo stesso interrogando l'evento ... – kleopatra

+0

@kleopatra Sono d'accordo, ho solo cercato di essere coerente con lo stile di codifica che Nathan stava usando. – JeroenWarmerdam

+0

@kleopatra potresti fornire la tua risposta? :) – nathan

-1
scrollBar.getValue()==scrollBar.getMaximum() 
+1

Hum. Ho già provato a visualizzare il valore della proprietà * value * quando viene attivato un evento di regolazione e non raggiunge mai il valore massimo. Quindi penso che le tue condizioni non saranno mai verificate. – nathan

+0

Modificato la mia domanda. – nathan

+1

utilizzando questa riga di codice [non è necessaria per implementare AdjustmentListener] (http://stackoverflow.com/a/12707995/714968) – mKorbel

1

Utilizzando la finestra del JScrollPane è possibile calcolare se la finestra è guardando la fine del componente.

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


public class ViewPortDemo extends JPanel{ 

    public ViewPortDemo(){ 
     super(); 
     JTree tree = new JTree(); 
     for(int i =0; i < tree.getRowCount(); i++){ 
      tree.expandRow(i); 
     } 

     final JScrollPane pane = new JScrollPane(tree){ 
      Dimension prefSize = new Dimension(200,150); 
      public Dimension getPreferredSize(){ 
       return prefSize; 
      } 
     }; 

     pane.getVerticalScrollBar().addAdjustmentListener(new AdjustmentListener() { 

      @Override 
      public void adjustmentValueChanged(AdjustmentEvent e) { 
       JViewport vp = pane.getViewport(); 
       if(vp.getView().getHeight() <= vp.getHeight() + vp.getViewPosition().y){ 
        System.out.println("End"); 
       } 
      } 
     }); 

     add(pane); 
    } 


    public static void main(String[] args){ 
     final JFrame frame = new JFrame(); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.add(new ViewPortDemo()); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 
} 
+0

non c'è bisogno di calcolare qualcosa dalle dimensioni - regolabile ha tutte le informazioni necessarie ;-) – kleopatra

3

@StanislavL ha quasi avuto la risposta corretta.

Prova scrollBar.getValue() == scrollBar.getMaximum() - scrollBar.getVisibleAmount().

Per capire perché è necessaria la chiamata getVisibleAmount(), è necessario innanzitutto capire come funziona JScrollBars. Un JScrollBar ha 4 valori: minimo, massimo, valore ed estensione. value è la parte superiore della maniglia di scorrimento stessa e extent è la lunghezza effettiva della maniglia di scorrimento. value non sarà mai uguale a maximum a meno che la maniglia di scorrimento non abbia una lunghezza pari a 0. Per compensare, dobbiamo regolare il valore con cui confrontiamo sottraendo la lunghezza della maniglia di scorrimento per ottenere il massimo effettivo.

Questo effetto è documentato here, il che rende il suono come erroneamente getMaximum() rettifica il valore come dovrebbe, ma guardando da vicino la implementation of JScrollBar mostra che getMaximum() in realtà ci dà la vera massima, non il massimo efficace.

+1

Questo meraviglioso one-liner dovrebbe sicuramente essere la risposta! Una risposta semplice senza Viewport, ecc. Grazie mille dopo quasi 2 anni! – geisterfurz007

Problemi correlati