2012-11-25 20 views
5

Possiedo un JScrollPane con un incremento di blocco moderatamente alto (125). Vorrei applicare lo scorrimento morbido/lento ad esso in modo che non salti (o salti) durante lo scorrimento. Come posso fare questo?JScrollPane - Scorrimento uniforme

Stavo pensando di scorrimento come Windows 8.

Qualsiasi aiuto sarebbe molto apprezzato!

risposta

1

È possibile utilizzare uno javax.swing.Timer durante lo scorrimento per ottenere l'effetto di scorrimento uniforme. Se si sta attivando questo dall'esterno del componente, somthing come questo funzionerà (dove component è il componente all'interno del JScrollPane):

final int target = visible.y; 
final Rectangle current = component.getVisibleRect(); 
final int start = current.y; 
final int delta = target - start; 
final int msBetweenIterations = 10; 

Timer scrollTimer = new Timer(msBetweenIterations, new ActionListener() { 
    int currentIteration = 0; 
    final long animationTime = 150; // milliseconds 
    final long nsBetweenIterations = msBetweenIterations * 1000000; // nanoseconds 
    final long startTime = System.nanoTime() - nsBetweenIterations; // Make the animation move on the first iteration 
    final long targetCompletionTime = startTime + animationTime * 1000000; 
    final long targetElapsedTime = targetCompletionTime - startTime; 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     long timeSinceStart = System.nanoTime() - startTime; 
     double percentComplete = Math.min(1.0, (double) timeSinceStart/targetElapsedTime); 

     double factor = getFactor(percentComplete); 
     current.y = (int) Math.round(start + delta * factor); 
     component.scrollRectToVisible(current); 
     if (timeSinceStart >= targetElapsedTime) { 
      ((Timer) e.getSource()).stop(); 
     } 
    } 
}); 
scrollTimer.setInitialDelay(0); 
scrollTimer.start(); 

Il metodo getFactor è una conversione da lineare a una funzione di alleggerimento e sarebbe implementata come uno di questi a seconda di come si vuole sentire:

private double snap(double percent) { 
    return 1; 
} 

private double linear(double percent) { 
    return percent; 
} 

private double easeInCubic(double percent) { 
    return Math.pow(percent, 3); 
} 

private double easeOutCubic(double percent) { 
    return 1 - easeInCubic(1 - percent); 
} 

private double easeInOutCubic(double percent) { 
    return percent < 0.5 
      ? easeInCubic(percent * 2)/2 
      : easeInCubic(percent * -2 + 2)/-2 + 1; 
} 

Questo potrebbe probabilmente essere adattati per lavorare all'interno di un componente troppo così quando l'utente scorre fa qualcosa in questo senso.

Oppure, se possibile, è possibile utilizzare JavaFX che ha un supporto molto migliore per l'animazione rispetto a Swing.

Problemi correlati