Größenänderung mittels Maus - selbst implementieren?

Status
Nicht offen für weitere Antworten.

-frank

Bekanntes Mitglied
Ich würde diverse Components gerne per Maus resizen, ähnlich einem normalen JFrame (also wenn man am Rand des JComponents ist, soll ein entsprechender Vergrößerungs-Mauscursor kommen und dann soll man durch klick + drag vergrößern/verkleinen können).
ich habe bisher wenig diesbezüglich gefunden (was vermutlich daran liegt, dass ich nicht weiß, wie man die entsprechenden mauscursor-icons bezeichnet). ich nehme an, dass die Swing Api aber schon alles notwenidge dafür bieten müsste (oder ist das die Aufgabe des Betriebssystem (bzw. der grafischen Oberfläche) und Java stellt nur GUI-Objekt bereit (zb JInternalFrame), die resize per Maus unterstützen?)
 

kleiner_held

Top Contributor
Der Resize Mechanismus von JInternalFrame ist in der Klasse BasicInternalFrameUI implementiert, ich glaube nicht, dass Swing noch anderswo entsprechende Util-Methoden bereitstellt.
Ich habe auf alle Faelle sowas schon mal per Hand gebaut, also mittels MouseListener, setCursor() und setBounds().
Ich kann ja heute abend mal zu Hause schauen, ob ich noch ein Beispiel finde.
 

The_S

Top Contributor
@kleiner_held

hast dus auch geschafft das nervige Flackern der Komponenten vollständig zu entfernen? Falls ja, wäre ich auch mal interessiert :)
 

kleiner_held

Top Contributor
Es ist zwar noch nicht abend und ich bin auch noch net zu Hause, aber schliesslich gibts ja I-Net und SSH ;-)

Code:
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.util.HashMap;
import java.util.Map;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import javax.swing.border.EtchedBorder;
import javax.swing.event.MouseInputAdapter;

public class ResizeTest
{

	/**
	 * Main with a JFrame and 2 sample components.
	 * 
	 * @param args
	 */
	public static void main(String[] args)
	{
		JFrame frame = new JFrame();
		frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
		frame.getContentPane().setLayout(null);

		ResizableAndMoveableComponent component = new ResizableAndMoveableComponent(3);
		frame.getContentPane().add(component);
		component.setBounds(20, 20, 100, 50);
		component.getContentPane().setLayout(new GridLayout(1, 1, 0, 0));
		component.getContentPane().add(new JButton("Test"));

		ResizableAndMoveableComponent component2 = new ResizableAndMoveableComponent(3);
		frame.getContentPane().add(component2);
		component2.setBounds(140, 20, 100, 50);
		component2.getContentPane().setLayout(new FlowLayout());
		component2.getContentPane().add(new JComboBox(new String[]
		{ "eins", "zwo", "drei" }));

		frame.setSize(200, 200);
		frame.setVisible(true);
	}

	/**
	 * Component which manages the resize. Do not add or remove components to it but use getContentPane().add(..)
	 */
	public static class ResizableAndMoveableComponent extends JComponent
	{
		private static final long serialVersionUID = 1L;
		
		private int insets;
		// current mode of resize or move
		private Mode mode = Mode.NONE;
		// offsets of the start of the current resize or move mode
		private int offsetLeft = 0;
		private int offsetRight = 0;
		private int offsetTop = 0;
		private int offsetBottom = 0;

		// init a map with cached cursors
		private Map<Mode, Cursor> cursors = new HashMap<Mode, Cursor>();
		{
			cursors.put(Mode.NONE, null);
			cursors.put(Mode.MOVE, Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR));
			cursors.put(Mode.RESIZE_S, Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR));
			cursors.put(Mode.RESIZE_N, Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR));
			cursors.put(Mode.RESIZE_E, Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR));
			cursors.put(Mode.RESIZE_W, Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR));
			cursors.put(Mode.RESIZE_SW, Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR));
			cursors.put(Mode.RESIZE_SE, Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR));
			cursors.put(Mode.RESIZE_NW, Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR));
			cursors.put(Mode.RESIZE_NE, Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR));
		}

		public ResizableAndMoveableComponent(int insets)
		{
			this.insets = insets;
			add(new JPanel());
			setBorder(BorderFactory.createEtchedBorder(EtchedBorder.RAISED));
			setToolTipText("Resize with left button, move with right button");
			MouseHandler handler = new MouseHandler();
			addMouseMotionListener(handler);
			addMouseListener(handler);
		}

		public JPanel getContentPane()
		{
			return (JPanel) getComponent(0);
		}

		@Override
		public Dimension getPreferredSize()
		{
			return translatePanelDimension(getContentPane().getPreferredSize());
		}

		@Override
		public Dimension getMaximumSize()
		{
			return translatePanelDimension(getContentPane().getMaximumSize());
		}

		@Override
		public Dimension getMinimumSize()
		{
			return translatePanelDimension(getContentPane().getMinimumSize());
		}

		private Dimension translatePanelDimension(Dimension d)
		{
			d.height += 2 * insets;
			d.width += 2 * insets;
			// avoid int overflow
			if (d.height < 0)
				d.height = Integer.MAX_VALUE;
			if (d.width < 0)
				d.width = Integer.MAX_VALUE;
			return d;
		}
		
		@Override
		public void setBounds(int x, int y, int width, int height)
		{
			super.setBounds(x, y, width, height);
			// delegate the bounds to our content pane 
			getContentPane().setBounds(insets, insets, width - insets - insets, height - insets - insets);
			getContentPane().doLayout();
		}

		// TODO overwrite all add(...) and remove(...) methods to delegate them to ContentPane

		/**
		 * update the cursor with the given mode
		 */
		private void updateCursor(Mode mode)
		{
			setCursor(cursors.get(mode));
		}

		/**
		 * update the cursor with the mode acording to the given point 
		 */
		private void updateCursor(Point p)
		{
			updateCursor(getModeForPoint(p));
		}

		private Mode getModeForPoint(Point p)
		{
			Rectangle bounds = getBounds();
			if (p == null || p.y < 0 || p.y >= bounds.y + bounds.height || p.x < 0 || p.x >= bounds.x + bounds.width)
			{
				return mode.NONE;
			}
			// if upper border
			else if (p.y <= insets)
			{
				// if left edge
				if (p.x <= insets)
				{
					return Mode.RESIZE_NW;
				}
				// if right edge
				else if (p.x >= bounds.width - insets)
				{
					return Mode.RESIZE_NE;
				}
				else
				{
					return Mode.RESIZE_N;
				}
			}
			// if lower border
			else if (p.y >= bounds.height - insets)
			{
				// if left edge
				if (p.x <= insets)
				{
					return Mode.RESIZE_SW;
				}
				// if right edge
				else if (p.x >= bounds.width - insets)
				{
					return Mode.RESIZE_SE;
				}
				else
				{
					return Mode.RESIZE_S;
				}
			}
			// if left border
			else if (p.x <= insets)
			{
				return Mode.RESIZE_W;
			}
			// if right border
			else if (p.x >= bounds.width - insets)
			{
				return Mode.RESIZE_E;
			}
			else
			{
				return Mode.NONE;
			}
		}

		private class MouseHandler extends MouseInputAdapter
		{
			public void mouseMoved(MouseEvent e)
			{
				if (mode == Mode.NONE)
				{
					updateCursor(e.getPoint());
				}
			}

			@Override
			public void mouseEntered(MouseEvent e)
			{
				if (mode == Mode.NONE)
				{
					updateCursor(e.getPoint());
				}
			}

			@Override
			public void mouseExited(MouseEvent e)
			{
				if (mode == Mode.NONE)
				{
					updateCursor(Mode.NONE);
				}
			}

			@Override
			public void mouseDragged(MouseEvent e)
			{
				if (mode != Mode.NONE)
				{
					updateAction(e.getPoint());
				}
			}

			@Override
			public void mousePressed(MouseEvent e)
			{
				if (mode == Mode.NONE)
				{
					if (SwingUtilities.isLeftMouseButton(e))
					{
						mode = getModeForPoint(e.getPoint());
					}
					else if (SwingUtilities.isRightMouseButton(e))
					{
						mode = Mode.MOVE;
					}
					Rectangle bounds = getBounds();
					Point p = e.getPoint();
					offsetLeft = p.x;
					offsetRight = p.x - bounds.width;
					offsetTop = p.y;
					offsetBottom = p.y - bounds.height;
					updateCursor(mode);
				}
			}

			@Override
			public void mouseReleased(MouseEvent e)
			{
				if (mode != Mode.NONE)
				{
					updateAction(e.getPoint());
					offsetLeft = 0;
					offsetRight = 0;
					offsetTop = 0;
					offsetBottom = 0;
					mode = Mode.NONE;
					updateCursor(e.getPoint());
				}
			}
		}

		private void updateAction(Point p)
		{
			if (mode == Mode.MOVE)
			{
				Rectangle newBounds = new Rectangle(getBounds());
				newBounds.x += p.x - offsetLeft;
				newBounds.y += p.y - offsetTop;
				newBounds.x = Math.max(0, newBounds.x);
				newBounds.y = Math.max(0, newBounds.y);
				setBounds(newBounds);
			}
			else
			{
				Rectangle originalBounds = getBounds();
				Rectangle newBounds = new Rectangle(originalBounds);
				Dimension minSize = getMinimumSize();
				Dimension maxSize = getMaximumSize();
				if (mode == Mode.RESIZE_N || mode == Mode.RESIZE_NE || mode == Mode.RESIZE_NW)
				{
					newBounds.y += (p.y - offsetTop);
					newBounds.y = Math.min(newBounds.y, originalBounds.y + originalBounds.height - minSize.height);
					newBounds.y = Math.max(newBounds.y, originalBounds.y + originalBounds.height - maxSize.height);

					newBounds.height = originalBounds.y + originalBounds.height - newBounds.y;
				}
				else if (mode == Mode.RESIZE_S || mode == Mode.RESIZE_SE || mode == Mode.RESIZE_SW)
				{
					newBounds.height = p.y - offsetBottom;
					newBounds.height = Math.max(minSize.height, newBounds.height);
					newBounds.height = Math.min(maxSize.height, newBounds.height);
				}
				if (mode == Mode.RESIZE_W || mode == Mode.RESIZE_NW || mode == Mode.RESIZE_SW)
				{
					newBounds.x += (p.x - offsetLeft);
					newBounds.x = Math.min(newBounds.x, originalBounds.x + originalBounds.width - minSize.width);
					newBounds.x = Math.max(newBounds.x, originalBounds.x + originalBounds.width - maxSize.width);
					newBounds.width = originalBounds.x + originalBounds.width - newBounds.x;
				}
				else if (mode == Mode.RESIZE_E || mode == Mode.RESIZE_NE || mode == Mode.RESIZE_SE)
				{
					newBounds.width = p.x - offsetRight;
					newBounds.width = Math.max(minSize.width, newBounds.width);
					newBounds.width = Math.min(maxSize.width, newBounds.width);
				}
				setBounds(newBounds);
			}
		}

		private enum Mode
		{
			NONE,
			MOVE,	
			RESIZE_E,
			RESIZE_W,
			RESIZE_S,
			RESIZE_N,
			RESIZE_SE,
			RESIZE_NE,
			RESIZE_NW,
			RESIZE_SW,
		}
	}
}

Probleme mit Flackern gibts bei dem Beispiel eigentlich nicht, obwohl es bei riesigen ImageIcons eventuell dazu kommen koennte. Resize mit linker Maustaste, Move mit Rechter.

viel Spass damit :)
 
Status
Nicht offen für weitere Antworten.
Ähnliche Java Themen
  Titel Forum Antworten Datum
W Swing Größenänderung vom JPanel im JScrollPane und anschließendes positionieren AWT, Swing, JavaFX & SWT 2
B Vertikale Größenänderung zwischen zwei Widgets AWT, Swing, JavaFX & SWT 2
J ungewollt-automatische Größenänderung von JLabel AWT, Swing, JavaFX & SWT 5
U ToolTip Größenänderung, passt sich erst beim zweiten Mal an AWT, Swing, JavaFX & SWT 6
A JFrame Größenänderung AWT, Swing, JavaFX & SWT 3
A JFrame Größenänderung mit Maus und GridLayout AWT, Swing, JavaFX & SWT 10
A Swing JFileChooser - Größenänderung nach Aufruf von showOpenDialog() AWT, Swing, JavaFX & SWT 15
X Swing JTextPane bei Größenänderung Formatierung behalten AWT, Swing, JavaFX & SWT 11
B JFrame: Benachrichtung über Größenänderung AWT, Swing, JavaFX & SWT 4
Psypsy Swing JFrame Größenänderung Peformancefrage AWT, Swing, JavaFX & SWT 5
G Swing JScrollPane/Layoutmanger Problem bei dynamischer Größenänderung AWT, Swing, JavaFX & SWT 7
S Swing Inhalt eines Fenster bei Größenänderung anpassen (GroupLayout) AWT, Swing, JavaFX & SWT 2
T Swing Dialoginhalt automatisch anpassen während Größenänderung AWT, Swing, JavaFX & SWT 2
P TextArea Größenänderung AWT, Swing, JavaFX & SWT 4
S Panel austauschen, ohne Größenänderung des Frames AWT, Swing, JavaFX & SWT 5
C Auf Größenänderung eines Fensters (JFrame) reagieren AWT, Swing, JavaFX & SWT 2
C Event nach Größenänderung des Fensters AWT, Swing, JavaFX & SWT 3
E Größenänderung von nur EINER Seite einer SplitPane AWT, Swing, JavaFX & SWT 2
A Layoutprobleme bei Größenänderung AWT, Swing, JavaFX & SWT 2
G awt panel for größenänderung schützen AWT, Swing, JavaFX & SWT 3
T SWT - Inhalt einer Shell erst nach Größenänderung vorhanden AWT, Swing, JavaFX & SWT 5
F Welche Layout-Methode wird bei Größenänderung aufgerufen? AWT, Swing, JavaFX & SWT 4
N JPanel zeichnet Inhalt erst nach Größenänderung des JFrames AWT, Swing, JavaFX & SWT 3
S JFrame und Größenänderung AWT, Swing, JavaFX & SWT 3
U JFrame bei Größenänderung immer neu zeichnen AWT, Swing, JavaFX & SWT 4
L JavaFx Textformatierung mittels Datenbank und Funktion anpassen AWT, Swing, JavaFX & SWT 5
dtr84 JavaFX/OpenJFX mittels Apache Ivy einbinden (Java 11) AWT, Swing, JavaFX & SWT 18
P JavaFx - Progressbar - Füllen mittels mehreren Tasks AWT, Swing, JavaFX & SWT 0
G Bekomme ResultSet mittels ObservableList nicht ins TableView AWT, Swing, JavaFX & SWT 25
M Swing GUI mittels erben sowie variabler Dateninhalt AWT, Swing, JavaFX & SWT 1
JavaMachtMichFertig JavaFX Gui - Löschbutton in Tabelle anzeigen, die mittels MySQL Abfrage gefüllt wird AWT, Swing, JavaFX & SWT 5
A befüllen eines JTables mittels Methode AWT, Swing, JavaFX & SWT 10
L Ausgabe in JEditorPane mittels HTMLEditorKit zeigt auf bestimmten Systemen falsche Zeichen AWT, Swing, JavaFX & SWT 1
J Swing GUI-Einstellungen mittels Preferences AWT, Swing, JavaFX & SWT 2
J Rechtecke mittels getWidth AWT, Swing, JavaFX & SWT 1
M Repaint mittels Button richtig aufrufen klappt nicht AWT, Swing, JavaFX & SWT 1
T JFrame mittels Shortcut anzeigen AWT, Swing, JavaFX & SWT 2
E Client-Server mittels AWT AWT, Swing, JavaFX & SWT 27
A Swing Fenstergröße mittels Menü verändern AWT, Swing, JavaFX & SWT 3
U Swing JLabel bewegen mittels Thread AWT, Swing, JavaFX & SWT 3
R Swing Verschieben eines jButtons mittels MouseDragged AWT, Swing, JavaFX & SWT 4
N Wertanzeige mittels JSpinner AWT, Swing, JavaFX & SWT 3
T Daten mittels ComboBox in ein JTable adden AWT, Swing, JavaFX & SWT 7
Z Swing Mittels GUI Werte aus Property-File ändern AWT, Swing, JavaFX & SWT 5
C Swing Eine SWING-Anwendung mittels MVC AWT, Swing, JavaFX & SWT 4
M Liste mittels SwingWorker füllen klappt nicht AWT, Swing, JavaFX & SWT 10
B JLabel mittels Timer und setLocation verschieben AWT, Swing, JavaFX & SWT 3
B Grafiken in JLabel mittels html AWT, Swing, JavaFX & SWT 5
T HTML Seite neu laden mittels Applet AWT, Swing, JavaFX & SWT 2
G Zentrieren mittels setLocationRelativeTo(null);? AWT, Swing, JavaFX & SWT 14
Semox Setzen des Layout Managers mittels Override Parameter AWT, Swing, JavaFX & SWT 10
T JTable-Zelle mittels JFileChooser befüllen AWT, Swing, JavaFX & SWT 5
F JTextArea mittels Tab verlassen. AnyIdea? AWT, Swing, JavaFX & SWT 2
C Fragen zur Darstellung einer JTable mittels Renderer AWT, Swing, JavaFX & SWT 2
H Grafiken mittels Hashing vergleichen. aber wie? AWT, Swing, JavaFX & SWT 20
G Jtable mittels Liste füllen AWT, Swing, JavaFX & SWT 3
F Einlesen von text in textArea mittels for-schleife AWT, Swing, JavaFX & SWT 3
M JComboBox - Mittels FocusListener Event auslösen? AWT, Swing, JavaFX & SWT 4
B Vektorgrafik mittels Batik Tool anzeigen AWT, Swing, JavaFX & SWT 3
L Internationalisierung mittels ResourceBundle und Menu HotKey AWT, Swing, JavaFX & SWT 6
M Fenstertiteländerung mittels WindowAdapter AWT, Swing, JavaFX & SWT 5
H MouseEvent bei Drag & Drop (mittels TransferHandler) AWT, Swing, JavaFX & SWT 3
L Daten mittels ObjectInputStream ins JTable AWT, Swing, JavaFX & SWT 7
G Linie mit der Maus auswählen AWT, Swing, JavaFX & SWT 5
B mit maus Objekt bewegen AWT, Swing, JavaFX & SWT 3
R Swing Panel nur bei Maus sichtbar AWT, Swing, JavaFX & SWT 2
B mit Maus verschiebbares Panel AWT, Swing, JavaFX & SWT 2
C JTextField Inhalt mit Maus selektieren wenn disabled AWT, Swing, JavaFX & SWT 2
S JavaFX Fenster aufkommen lassen, wenn mit der Maus über bestimmten Bereich fahren AWT, Swing, JavaFX & SWT 1
F Event wenn Maus eine JList verlässt AWT, Swing, JavaFX & SWT 13
T Timer und GIF Animationen pausieren während Maus sich bewegt AWT, Swing, JavaFX & SWT 4
M Bild in JPanel mit Maus einfügen AWT, Swing, JavaFX & SWT 0
B Swing Form undecorated: Beim Bewegen geht die Maus immer automatisch zur linken Seite. AWT, Swing, JavaFX & SWT 7
L 2D-Grafik Bild in Richtung Maus drehen AWT, Swing, JavaFX & SWT 18
K Swing Maus in Panel einsperren AWT, Swing, JavaFX & SWT 8
D Swing JList keine Selektionsänderung bei "dragged-Maus" AWT, Swing, JavaFX & SWT 4
J Maus "locken" für Menü AWT, Swing, JavaFX & SWT 8
D Grafiken an Maus anhängen AWT, Swing, JavaFX & SWT 2
P Pfeilpolygon per Maus rotierbar machen - Kleine Schwierigkeiten AWT, Swing, JavaFX & SWT 29
P Event Handling Gedrückte Maus Blockiert MausEvents AWT, Swing, JavaFX & SWT 2
R Swing Per Maus JLabel resizen AWT, Swing, JavaFX & SWT 6
F Maus von alleine bewegen! AWT, Swing, JavaFX & SWT 8
G Swing JPanel per Maus verschieben AWT, Swing, JavaFX & SWT 5
A SWT Tooltip soll nicht verschwinden, solange User mit Maus auf Control ist AWT, Swing, JavaFX & SWT 5
C AWT Mausbarriere Maus fangen AWT, Swing, JavaFX & SWT 10
J "Auswahlfenster" mit Maus auf JLabel zeichnen AWT, Swing, JavaFX & SWT 4
W Swing Bild zeichnen wenn Maus an bestimmter Position ist AWT, Swing, JavaFX & SWT 4
J Inaktivität von Maus und Tastatur AWT, Swing, JavaFX & SWT 4
G AWT Images aus Imagearray an die Maus pappen und bewegen AWT, Swing, JavaFX & SWT 4
F Element anzeigen / erstellen. Maus vs Controller AWT, Swing, JavaFX & SWT 7
M 3D-Grafik Bewegung mit der Maus ohne Klicken AWT, Swing, JavaFX & SWT 10
F Swing Objekte mit Maus verschieben AWT, Swing, JavaFX & SWT 8
O Swing JButton werden richtig gewechselt aber die Maus macht die alten wieder Sichtbar?? AWT, Swing, JavaFX & SWT 5
Y AWT Maus Koordinaten abspeichern in eine Textfile AWT, Swing, JavaFX & SWT 3
Weltall 7 AWT Maus-Events werden doppelt ausgeführt AWT, Swing, JavaFX & SWT 12
C permanente aktualisierung der Koordinaten der Maus auf einem Panel AWT, Swing, JavaFX & SWT 8
J maus festlegen AWT, Swing, JavaFX & SWT 6
C paintComponent mit Maus verschieben - wie? AWT, Swing, JavaFX & SWT 2
T Swing JComboBox: Listeneinträge mit der Maus verschieben AWT, Swing, JavaFX & SWT 5
O JSlider - wie unterscheide ich mit Maus verändert und durch setValue verändert. AWT, Swing, JavaFX & SWT 16

Ähnliche Java Themen

Neue Themen


Oben