2012-04-11 12 views
0

Ich habe eine einfache App, mit der Benutzer ein PDF-Dokument markieren können, indem sie vordefinierte Widgets in eine separate Ebene ziehen.JScrollPane-Verhalten überschreiben

Ich benutze eine JScollPane. Die Größe des Darstellungsbereichs entspricht einer einzelnen 8.5 x 11-Seite. Wenn sich die VScrollBar an der Mindestposition befindet, wird oben auf der Seite angezeigt. In der maximalen Position wird der Boden angezeigt. Ich möchte dieses Verhalten übersteuern. Die minimale Position sollte den Anfang der ersten Seite anzeigen, und die maximale Position sollte den unteren Rand der letzten Seite anzeigen.

Unter den Sackgassen, die ich getroffen habe: Ersetzen der ScrollBar in JScrollPane integriert; Abfangen des von der VScrollBar abgefeuerten AdjustmentEvent; und das ScrollDemo-Beispiel studieren. Das scheint ein einfaches Feature zu sein, aber ich stecke am Anfang fest.

Irgendwelche Vorschläge? Vielen Dank!

+0

PLease sehen, ob Sie Ihre Frage klären oder einen Code-Schnipsel erstellen, das Ihr Problem zeigt – ControlAltDel

+0

I Beispielcode geschrieben haben. Ich habe diese Frage markiert, aber tatsächlich gibt es immer noch ein kleines Problem. Irgendeine Möglichkeit, dies als "unbeantwortet" neu zu definieren? –

Antwort

1

Möchten Sie in der Lage sein, die untere Hälfte der ersten Seite und die obere Hälfte der zweiten Seite gleichzeitig anzuzeigen (und Elemente von einer Seite zur nächsten zu ziehen)? Oder nur eine ganze Seite zu der Zeit?

Für die erste benötigen Sie eine einzelne Komponente, die nur alle Seiten anzeigt und sie zu einem JScrollPane hinzufügen. Sie möchten wahrscheinlich die Scrollable-Schnittstelle implementieren, um das Blockieren von Einheiten/Blöcken fein abzustimmen.

Für die zweite können Sie nur eine einzelne (vertikale) JScrollBar neben der Komponente anzeigen und die angezeigte Seite abhängig von ihrem Wert ändern. In diesem Fall verwenden Sie eine Bildlaufleiste mehr wie ein Schieberegler und Ihre Seitenkomponente ist nicht wirklich scrollbar (kein JScrollPane verwendet).

+0

Weder beschreibt das Verhalten des PDF-Readers von Adobe. Aber die Sekunde ist näher: Die Bildlaufleiste muss die Ansicht der aktuellen Seite anpassen, zeigt aber nie mehr als eine Seite gleichzeitig an. –

1

Dies scheint den Trick zu tun:

class DocumentScroller extends JScrollPane implements ChangeListener { 
    Component view ; 
    JPanel bookPanel, bookTop ; 
    ScrollingDocumentListener listener ; 
    Dimension pageSize ; 

    public DocumentScroller (Component view) { 
      this.view = view ; 
      } 

    public DocumentScroller (Component view, 
        int vsbPolicy, int hsbPolicy) { 
      super(vsbPolicy, hsbPolicy) ; 
      this.view = view ; 
      } 

    public void setViewportView (Component view) { 
      this.view = view ; 
      } 

    public void setPageCount (int pagect) { 
      if (view == null) 
        return ; 

      pageSize = view.getPreferredSize() ; 
      Dimension bookSize = new Dimension(pageSize) ; 
      bookSize.height *= pagect ; 

      bookPanel = new JPanel() ; 
      bookPanel.setLayout(new BorderLayout()) ; 
      bookPanel.setPreferredSize(bookSize) ; 
      bookPanel.add(bookTop = new JPanel(), 
          BorderLayout.NORTH) ; 
      bookPanel.add(view, BorderLayout.CENTER) ; 

      super.setViewportView(bookPanel) ; 
      getViewport().addChangeListener(this) ; 
      } 

    public void setUnitIncrement (int unitIncrement) { 
      getVerticalScrollBar().setUnitIncrement(unitIncrement) ; 
      } 

    public void setValue (int value) { 
      getVerticalScrollBar().setValue(value) ; 
      } 

    public void setScrollingDocumentListener (
        ScrollingDocumentListener listener) { 
      this.listener = listener ; 
      } 

    public void stateChanged (ChangeEvent e) { 
      try { 
        if (e.getSource().getClass() 
            != Class.forName(
             "javax.swing.JViewport")) 
          return ; 
        } 
      catch (Exception ex) { 
        return ; 
        } 

      Rectangle rect = ((JViewport) e.getSource() 
          ).getViewRect() ; 
      int offset = rect.y %pageSize.height ; 
      int pageTop = rect.y -offset ; 
      int pos = offset *rect.height /pageSize.height ; 

      bookTop.setPreferredSize(
          new Dimension(0, pageTop +pos)) ; 
      bookPanel.doLayout() ; 

      if (listener != null) 
        listener.setPage(pageTop /pageSize.height) ; 
      } 
    } 

interface ScrollingDocumentListener { 
    void setPage (int pageno) ; 
    } 
+0

Das Problem mit diesen Codes ist ein störender Bounce-Effekt. Zunächst wird die Anzeige bei der Bildlaufleiste aktualisiert. Dann wird bei stateChanged() die "view" -Komponente leicht nach oben bewegt und die Anzeige wird aktualisiert. Die Lösung besteht darin, die erste Aktualisierung irgendwie abzufangen. –