Scrollen per mouseDragged (JScrollPane)

Status
Nicht offen für weitere Antworten.
G

Guest

Gast
Servus aus Coburg,

gibt es in java Swing eine Möglichkeit per Drag & Drop das Scrollen in einem JScrollPane nachzubilden. Angenommen es wird ein langes Dokument in einem Scrollpane angezeigt, dann soll das vertikale und horizontale Scrollen eben nicht über den herkömmlichen Weg möglich sein, sondern auch per Maus, dh. ich befinde mich mit der Maus an einer Stelle im Dokument und kann bei gedrückter Maustaste dann genauso "scrollen". Ein paar Tips wären hilfreich. Danke im voraus!
 

0001001

Bekanntes Mitglied
Ja das sollte funktionieren.

Du brauchst einen MouseListener, der dir die aktuelle Position der Maus liefert. Dann prüfst du die Größe des Fensters. Falls die Maus gedrückt ist und sich nahe am Rand des Fensters befindet, setzt du die entspechende(n) Scrollbars auf einen bestimmten Wert, so dass das Dokument wieder mehr in die Mitte rückt.
 
G

Gelöschtes Mitglied 9001

Gast
Ich vermute, dem Fragesteller ging es nicht darum, daß der Inhalt automatisch scrollt, wenn man mit der Maus an den Rand kommt. Ich glaube, gesucht ist eine Lösung dafür, wie man den Inhalt mit der Maus anfassen und dann verschieben kann. Ich selbst suche auch gerade danach.

Idealerweise sollte die scrollbare Komponente von der Realisierung unbehelligt bleiben. Das Problem ist nur: wo setze ich einen MouseListener richtig an, der zunächst alle Mausereignisse abfängt und prüft, ob diese das Verschieben des Inhaltes initiieren könnten. Falls sie das tun, so dürften sie nicht auch noch von der Komponente bearbeitet werden. Falls sie das nicht tun, müßten sie an die Komponente weitergereicht werden.

Bislang habe ich MouseListener bei der JScrollPane, beim JViewport und bei der Komponente angemeldet, bei JViewport und JScrollPane auch mal processMouseEvents überschrieben. Hat bis lang alles noch nicht zum Ziel geführt: in jedem Fall reagierte die Komponente auf alle Mausereignisse. Und nur, wenn ich den MouseListener bei der Komponente direkt angemeldet habe, konnte ich auch wirklich an alle Mausereignisse kommen.

Wer hat dazu noch Ideen?
 

Ebenius

Top Contributor
Hier meine JXScrollPane. Unterstützt view dragging, standardmäßig auf dem rechten mouse button (kann man ändern mit setViewDragModifierMask(int)). Sicher kannst Du darauf aufbauen. Die MouseEvents werden nur verarbeitet, wenn keines der Kinder den Event konsumiert. Diesen Weg halte ich für sinnvoller, als den Kindern den Event zu verstecken, wenn ihn sich die JScrollPane krallt.

ebenius.widget.JXScrollPane

Ebenius
 
G

Gelöschtes Mitglied 9001

Gast
Danke Ebenius!
Ich habe Deinen Code probiert, funktionierte bei mir leider nicht. Die Mouse-Events kamen gar nicht erst bei processMouseEvents an. Hinzu kommt, daß meine Anwendung für einen Touchscreen bestimmt ist. Dort kann ich nicht zwischen rechter und linker Maustaste unterscheiden. Trotzdem gibt es in der Komponente, die gescrollt werden soll, Elemente, die angeklickt und auch per Drag&Drop verschoben werden können müssen. Ich habe, noch bevor ich Deinen Post las, mich heute Vormittag hingesetzt und weitergebastelt. Folgender Code ist dabei herausgekommen.
Die durchaus kontrovers diskutierbare Strategie ist, dass über den Viewport eine Pane gelegt wird, die zunächst alle MouseEvents abfängt. Drückt der Benutzer die Maustaste und beginnt innerhalb einer zehntel Sekunde den Dragvorgang, interpretiert die Pane dies als Anweisung zum Scrollen. In allen anderen Fällen werden die MouseEvents einfach weitergereicht.

Code:
/**
 * ScrollPane, bei welcher der Inhalt durch Anfassen mit der Maus verschoben werden kann.
 *
 */
public class DraggableScrollPane extends JScrollPane {
	
	/**
	 * Diese Komponente wird ueber den Viewport gelegt und faengt die Mausereignisse zunaechst ab.
	 * Koennen die Mausereignisse interpretiert werden als Anweisung, den Inhalt zu verschieben, wird
	 * selbiges getan. Ansonsten werden die Ereignisse weiter an den Inhalt gereicht.
	 *
	 */
	class MyGlassPane extends JComponent implements MouseListener, MouseMotionListener, MouseWheelListener {
		
		final static int MOUSEPRESSDELAY = 100; // ein Mausdruck wird nach soviel Millisekunden an den Inhalt weitergereicht, 
												// sofern nichts anderes passiert 
		
		protected javax.swing.Timer MousePressTimer;
		protected Point pressedPoint;           // nach jedem mousePressed stehen hier die Koordinaten drin
		protected Point pressedViewPos;         // und hier, bei welcher Position der Inhalt stand.
		protected boolean dragging = false;     // ist true, wenn der Benutzer den Inhalt gerade verschiebt 
		
		public MyGlassPane() {
			super();
			addMouseListener(this);
			addMouseMotionListener(this);
			addMouseWheelListener(this);
			setFocusable(false);
		}

		boolean MouseLocked = false;
		@Override
		/**
		 * Wenn MouseLocked true ist, dann wird hier false zurueckgegeben und so sichergestellt, 
		 * dass die GlassPane bei der Zuordnung von MouseEvents nicht beruecksichtigt wird
		 */
		public boolean contains(int x, int y) {
			return !MouseLocked && super.contains(x,y);
		}

		/**
		 * Uebergibt ein MouseWheelEvent an die JScrollPane.
		 */
		protected void delegateMouseEvent(MouseWheelEvent e) {
			getParent().dispatchEvent(e);
		}
		
		/**
		 * Uebergibt ein MouseEvent an darunterliegende Komponenten
		 */
		protected void delegateMouseEvent(MouseEvent e) {				
			 Container container = getParent();
			 Point containerPoint = SwingUtilities.convertPoint(this, e.getPoint(), container);
			 
			 MouseLocked = true;  // damit nicht die GlassPane gefunden wird
			 Component C = container.findComponentAt(containerPoint.x, containerPoint.y); // jetzt die Komponente suchen, die den Punkt beinhaltet
			 MouseLocked = false; // jetzt wieder anschalten
			 
			 if (C != null && C != this) {   // C != this zur Sicherheit
				 Point destP = SwingUtilities.convertPoint(this, containerPoint, C);  // Punkt konvertieren in Koordinaten der Komponente
				 MouseEvent newe = new MouseEvent(C, e.getID(), e.getWhen(), e.getModifiers()+e.getModifiersEx(),      
	                     destP.x, destP.y, e.getClickCount(), e.isPopupTrigger(), e.getButton());  // neues MouseEvent erzeugen
				 
	             C.dispatchEvent(newe);   // und der Komponente uebergeben
			 }
		}

		public void startTimer(final MouseEvent EventToDelegate) {
			MousePressTimer = new Timer(MOUSEPRESSDELAY, new ActionListener() {
				public void actionPerformed(ActionEvent e) {
					delegateMouseEvent(EventToDelegate);
				}
			});
			MousePressTimer.setRepeats(false);
			MousePressTimer.start();
		}
		
		public void stopTimer() {
			if (MousePressTimer != null && MousePressTimer.isRunning()) {
				MousePressTimer.stop();
			}
		}
		
		public boolean isTimerRunning() {
			return MousePressTimer != null && MousePressTimer.isRunning();
		}
		
		public void scrollTo(Point p) {
			JViewport v = ((JScrollPane) getParent()).getViewport();
			Dimension ext = v.getExtentSize();
			Dimension D = v.getView().getSize();
			
			if (p.x < 0) p.x = 0;
			if (p.y < 0) p.y = 0;
			if (p.x > D.width-ext.width) p.x = D.width-ext.width;
			if (p.y > D.height-ext.height) p.y = D.height-ext.height;
			
			v.setViewPosition(p);
		}
		
		public Point getViewPos() {
			return ((JScrollPane) getParent()).getViewport().getViewPosition();
		}

		
		public void mouseClicked(MouseEvent e) {
			delegateMouseEvent(e);
		}

		public void mouseEntered(MouseEvent e) {
			delegateMouseEvent(e);
			
		}

		public void mouseExited(MouseEvent e) {
			delegateMouseEvent(e);
			
		}

		public void mousePressed(MouseEvent e) {
			pressedPoint = e.getPoint();
			pressedViewPos = getViewPos();
			
			startTimer(e);
		}
		
		public void mouseReleased(MouseEvent e) {
			if (dragging) {					// lief gerade ein Dragging-Vorgang
				dragging = false;           // dann beenden
			} else {
				delegateMouseEvent(e);      // ansonsten das Event weiterreichen
			} 
		}

		public void mouseDragged(MouseEvent e) {
			if (isTimerRunning()) {         // ist die Zeit noch nicht abgelaufen
				stopTimer();                // dann Timer abbrechen
				dragging = true;            // und denn Dragging-Vorgang starten
			}
			
			if (dragging) {                // wenn Dragging-Vorgang laeuft
				Point sp = new Point(pressedPoint.x-e.getX()+pressedViewPos.x,pressedPoint.y-e.getY()+pressedViewPos.y);
				scrollTo(sp);              // an entsprechende Stelle scrollen
			} else {
				delegateMouseEvent(e);     // ansonsten Event weiterreichen
			}
		}

		public void mouseMoved(MouseEvent e) {
			delegateMouseEvent(e);
		}

		public void mouseWheelMoved(MouseWheelEvent e) {
			delegateMouseEvent(e);
		}		
	}
	
	/**
	 * Dieses Layout erweitert das normale ScrollPaneLayout und sorgt dafuer,
	 * dass meine GlassPane ueber den Viewport gelegt wird.
	 */
	class MyScrollPaneLayout extends ScrollPaneLayout {
		MyGlassPane GP;
		final static String GLASSPANE = "GlassPane";
		
		@Override
		public void addLayoutComponent(String s, Component c) {
			if (s.equals(GLASSPANE)) {
				GP = (MyGlassPane) addSingletonComponent(GP, c);
			} else {
				super.addLayoutComponent(s, c);
			}
		}

		@Override
		public void layoutContainer(Container parent) {
			super.layoutContainer(parent);
			JViewport v = getViewport();
			if (v != null && GP != null) {
				GP.setBounds(v.getBounds());            // passgenaue Position und Groesse setzen
				parent.setComponentZOrder(GP, 0);       // und sicherstellen, dass die GlassPane obendrauf liegt
			}
		}
	}
	
	/********** DraggableScrollPane-Konstruktoren ********************/
	public DraggableScrollPane() {
		super();
		addmythings();
	}

	public DraggableScrollPane(Component view) {
		super(view);
		addmythings();
	}

	public DraggableScrollPane(int vsbPolicy, int hsbPolicy) {
		super(vsbPolicy, hsbPolicy);
		addmythings();
	}

	public DraggableScrollPane(Component view, int vsbPolicy, int hsbPolicy) {
		super(view, vsbPolicy, hsbPolicy);
		addmythings();
	}
	
	/**
	 * Setzt mein eigenes Layout ein und fuegt meine GlassPane hinzu
	 */
	protected void addmythings() {
		setLayout(new MyScrollPaneLayout());
		add(new MyGlassPane(), MyScrollPaneLayout.GLASSPANE);
		doLayout();
	}
}
 

Ebenius

Top Contributor
Dann hab ich mal meine JXScrollPane erweitert. Jetzt werden auch die Events der Kinder genommen die die Events schlucken wollen. :) Ohne GlassPane. Vielleicht gefällt Dir ja der Ansatz...

ebenius.widget.JXScrollPane

Viel Spaß! Ebenius
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
volcanos Scrollen: JScrollPane mit Graphics g und Java-Fonts extends Frame ? AWT, Swing, JavaFX & SWT 5
P kein Scrollen nach affinertransformation bei mouse dragged AWT, Swing, JavaFX & SWT 2
S JavaFX JavaFX TableView scrollen färbt falsche Zeilen AWT, Swing, JavaFX & SWT 1
S Nach scrollen verschwindet das zuvor im JPanel gezeichnete AWT, Swing, JavaFX & SWT 2
J JList scrollen AWT, Swing, JavaFX & SWT 3
Bluedaishi JTextArea gefundene Zeile nach Oben Scrollen AWT, Swing, JavaFX & SWT 13
P Swing Horizontales Scrollen mit Shift-Mausrad AWT, Swing, JavaFX & SWT 2
N Swing Problem beim Scrollen mit JScrollPane AWT, Swing, JavaFX & SWT 6
W JavaFX Scrollpane elementweise scrollen AWT, Swing, JavaFX & SWT 4
Thallius Automatisches Scrollen zum aktiven JTextView klappt nicht AWT, Swing, JavaFX & SWT 2
J Swing JTextPane mit JScrollPane auf JPanel scrollen nicht AWT, Swing, JavaFX & SWT 6
W Swing Zum Ende einer Scrollpane scrollen AWT, Swing, JavaFX & SWT 2
S JScrollPane --> Programm hängt sich beim scrollen auf AWT, Swing, JavaFX & SWT 2
S JavaFX Mehrere TreeTableView's synchron scrollen AWT, Swing, JavaFX & SWT 0
O Tabelle "animiert" Scrollen AWT, Swing, JavaFX & SWT 1
O Swing JTable per Scrollen füllen! AWT, Swing, JavaFX & SWT 7
J AWT choice mit viel Auswahl aktualisiert sich nicht korrekt beim scrollen?! AWT, Swing, JavaFX & SWT 3
P Durch Bilder Scrollen AWT, Swing, JavaFX & SWT 2
U Swing JPane und JScrollpane in JSplitpane-Seite: Scrollen funktioniert nicht AWT, Swing, JavaFX & SWT 3
J JTable wird bei scrollen falsch gezeichnet AWT, Swing, JavaFX & SWT 3
N Touchscreen-Scrollen, wo liegt der Fehler? AWT, Swing, JavaFX & SWT 3
S Swing Scrollpanes: wie kann ich durch Java-Code an den "Anfang" scrollen AWT, Swing, JavaFX & SWT 8
G JTable zentriert scrollen AWT, Swing, JavaFX & SWT 2
D SWING - Ein Composite scrollen AWT, Swing, JavaFX & SWT 6
S Canvas in ScrollPane wird beim scrollen immer neu gezeichnet AWT, Swing, JavaFX & SWT 3
D Swing JScrollbar ganz nach unten scrollen AWT, Swing, JavaFX & SWT 2
K SWT treeviewer scrollen AWT, Swing, JavaFX & SWT 8
F Swing Mehrere Textfelder in Scrollpane einfügen und dann zum Scrollen bringen? AWT, Swing, JavaFX & SWT 4
J Lazy Loading eine JTree während Scrollen AWT, Swing, JavaFX & SWT 11
A Swing Scrollen über JPane AWT, Swing, JavaFX & SWT 20
Dit_ JTextArea zu Zeile X scrollen AWT, Swing, JavaFX & SWT 4
S SWT Zwei Tabellen gleichzeitig Scrollen AWT, Swing, JavaFX & SWT 3
Dragonfire Swing JPanel nur vertikal scrollen AWT, Swing, JavaFX & SWT 4
hdi SWT ScrolledComposite -> Nix mit Scrollen? AWT, Swing, JavaFX & SWT 8
T In einem Label scrollen AWT, Swing, JavaFX & SWT 3
A Swing JScrollPane ans ende Scrollen AWT, Swing, JavaFX & SWT 9
W SwingX Problem mit Scrollen von 2 JXTaskPaneContainer AWT, Swing, JavaFX & SWT 3
S Swing Scrollen ohne Leiste? AWT, Swing, JavaFX & SWT 2
J wie Scrollen? AWT, Swing, JavaFX & SWT 3
R Zu selektiertem Column in JTable scrollen? AWT, Swing, JavaFX & SWT 2
P Drei Scrollpanes gleichzeitig scrollen AWT, Swing, JavaFX & SWT 3
H jScrollPane ohne Scrollen AWT, Swing, JavaFX & SWT 2
G Mehrere JScrollPanes gekoppelt scrollen AWT, Swing, JavaFX & SWT 2
G JTable in JScrollPane - nach unten scrollen AWT, Swing, JavaFX & SWT 11
S JList automatisch scrollen AWT, Swing, JavaFX & SWT 8
D JScrollPane incl. thumbnails, soll fluessig scrollen! AWT, Swing, JavaFX & SWT 3
J JScrollPane soll automatisch zu einem punkt scrollen AWT, Swing, JavaFX & SWT 4
P JPopupMenu scrollen AWT, Swing, JavaFX & SWT 2
J JList Scrollen AWT, Swing, JavaFX & SWT 8
M PerformanceProbleme(Beim Scrollen ruckelt es) AWT, Swing, JavaFX & SWT 16
Z JTable automatisch zu einer Zeile scrollen AWT, Swing, JavaFX & SWT 4
D JScrollPane mit Grafiken scrollen lassen AWT, Swing, JavaFX & SWT 2
G 3 oder mehr JTable nebeneinander gleichzeitig vert. scrollen AWT, Swing, JavaFX & SWT 4
R JTextPane scrollen vermeiden AWT, Swing, JavaFX & SWT 2
S JScrollPane > JPanel - automatisch scrollen AWT, Swing, JavaFX & SWT 2
R Einstellen der Maus Rad Geschwindigkeit beim Scrollen AWT, Swing, JavaFX & SWT 3
I In JPopupMenu scrollen AWT, Swing, JavaFX & SWT 4
S Scrollen AWT, Swing, JavaFX & SWT 2
Q ||| Scrollen mal anders - Console mitscrollender Text??? AWT, Swing, JavaFX & SWT 6
G Problem mit horizontal und vertikal scrollen AWT, Swing, JavaFX & SWT 2
M Scrollen - Geschwindigkeit - Scrollgeschwindigkeit AWT, Swing, JavaFX & SWT 2
G JScrollPane - scrollen mit Pfeiltasten AWT, Swing, JavaFX & SWT 3
J Wie kann man beim BoxLayout scrollen? Keine Scrollleiste!:-( AWT, Swing, JavaFX & SWT 7
R JTable zu einem bestimmten Eintrag automatisch scrollen? AWT, Swing, JavaFX & SWT 2
A Scrollpane verschmiert beim scrollen AWT, Swing, JavaFX & SWT 5
S Position von Labels, Buttons, etc. festsetzen und Scrollen AWT, Swing, JavaFX & SWT 4
N JTable scrollen AWT, Swing, JavaFX & SWT 4
F 3 JTextAreas zusammen scrollen AWT, Swing, JavaFX & SWT 5
O JScrollPane beinhaltet JPanel mit null Layout kein Scrollen AWT, Swing, JavaFX & SWT 3
G Scrollen ohne scrolleisten AWT, Swing, JavaFX & SWT 5
T JTextPane in JScrollPane NICHT autom. nach unten scrollen AWT, Swing, JavaFX & SWT 3
M JScrollPane immer bis ganz nach unten scrollen lassen AWT, Swing, JavaFX & SWT 5
J Streifen beim Scrollen AWT, Swing, JavaFX & SWT 3
F Scrollen bei JTextArea in einem Null-Layout? Unmöglich? AWT, Swing, JavaFX & SWT 4
M JScrollPane soll automatisch scrollen AWT, Swing, JavaFX & SWT 5
N JScrollPane schneller scrollen AWT, Swing, JavaFX & SWT 3
V Automatisches Scrollen bei JScrollPane AWT, Swing, JavaFX & SWT 10
N Scrollen in einem Panel AWT, Swing, JavaFX & SWT 5
S jScrollPane ganz nach unten scrollen AWT, Swing, JavaFX & SWT 4
B In JScrollPane eingebettetes JEditorPane scrollen AWT, Swing, JavaFX & SWT 2
M Scrollprobleme - Panelinhalte bleiben beim Scrollen AWT, Swing, JavaFX & SWT 2
Z JTextArea in JScrollPane automatisch scrollen AWT, Swing, JavaFX & SWT 2
K JPanle scrollen . AWT, Swing, JavaFX & SWT 2
V Probleme beim Scrollen ein JPanels mit JScrollPane AWT, Swing, JavaFX & SWT 2
G JTable automatisch scrollen AWT, Swing, JavaFX & SWT 4
S Automatisches Scrollen in einer JTextArea AWT, Swing, JavaFX & SWT 6
A Scrollen von Fenster geht nicht AWT, Swing, JavaFX & SWT 4
M JavaFX javafx mousedragged klappt nicht AWT, Swing, JavaFX & SWT 2
Z Bildervorschau, MouseDragged das Bild verschieben AWT, Swing, JavaFX & SWT 1
M mouseDragged im MouseMotionListener AWT, Swing, JavaFX & SWT 1
S 2D-Grafik MouseDragged Linien zeichnen AWT, Swing, JavaFX & SWT 4
P JFrame manuell Grösse verändern durch 'mouseDragged' AWT, Swing, JavaFX & SWT 3
R Swing Verschieben eines jButtons mittels MouseDragged AWT, Swing, JavaFX & SWT 4
Landei Swing MouseDragged auf Containerebene? AWT, Swing, JavaFX & SWT 7
H Ich kann MouseDragged nicht abfangen AWT, Swing, JavaFX & SWT 3
R JLayeredPane - Drag&Drop - mouseDragged AWT, Swing, JavaFX & SWT 6
J mouseDragged und MouseMotionListener AWT, Swing, JavaFX & SWT 3
H MouseMotionListener#mouseDragged() in großen Abständen AWT, Swing, JavaFX & SWT 7
M gezeichnete Punkte dynamisch verschieben mit mousedragged AWT, Swing, JavaFX & SWT 4
P JDialog mit mouseDragged(), verschieben ? AWT, Swing, JavaFX & SWT 14

Ähnliche Java Themen

Neue Themen


Oben