2012-11-25 12 views
5

Ich habe eine JScrollPane mit einem mäßig hohen Blockinkrement (125). Ich möchte glattes/langsames Scrollen darauf anwenden, damit es beim Scrollen nicht springt (oder überspringt). Wie kann ich das machen?JScrollPane - Smooth Scrolling

Ich dachte, wie Windows Scrollen 8.

Jede Hilfe wäre sehr dankbar!

Antwort

1

Sie könnten während des Scrollens einen javax.swing.Timer verwenden, um den reibungslosen Scroll-Effekt zu erzielen. Wenn Sie diese von außerhalb der Komponente auslösen, somthing wie dies funktionieren wird (wo component ist die Komponente innerhalb des 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(); 

Die getFactor Methode ist eine Umwandlung von linear zu einer Lockerung Funktion und würde umgesetzt werden einer von ihnen je nachdem, wie Sie es wollen fühlen:

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; 
} 

Dies ist wahrscheinlich angepasst werden könnte auch so innerhalb einer Komponente zu arbeiten, wenn der Benutzer blättert es etwas in dieser Richtung tut.

Oder, wenn möglich, könnten Sie JavaFX verwenden, das viel bessere Unterstützung für Animationen als Swing bietet.