[Schmitzm-commits] r2182 - in trunk/schmitzm-core/src/main/java/de/schmitzm: lang swing swing/event
scm-commit at wald.intevation.org
scm-commit at wald.intevation.org
Sun Dec 30 17:44:14 CET 2012
Author: mojays
Date: 2012-12-30 17:44:14 +0100 (Sun, 30 Dec 2012)
New Revision: 2182
Added:
trunk/schmitzm-core/src/main/java/de/schmitzm/swing/event/DockingListener.java
Modified:
trunk/schmitzm-core/src/main/java/de/schmitzm/lang/LangUtil.java
trunk/schmitzm-core/src/main/java/de/schmitzm/swing/OkCancelDialog.java
Log:
LangUtil: method to replace umlauts
OkCancelDialog: bug fix, dialog initialization ignored modal flag, dialog was always modal
NEW (and very smart) DockingListener
Modified: trunk/schmitzm-core/src/main/java/de/schmitzm/lang/LangUtil.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/lang/LangUtil.java 2012-12-23 18:17:50 UTC (rev 2181)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/lang/LangUtil.java 2012-12-30 16:44:14 UTC (rev 2182)
@@ -199,7 +199,24 @@
return getSignumStr(value, "");
}
- /**
+ /**
+ * Replaces all umlaut occurrences (and 'ß') by 'ae', 'oe' or 'ue'.
+ */
+ public static String replaceUmlauts(String str) {
+ if ( str == null )
+ return null;
+ boolean upcase = str.equals( str.toUpperCase() );
+ str = str.replaceAll("ä", "ae");
+ str = str.replaceAll("ö", "oe");
+ str = str.replaceAll("ü", "ue");
+ str = str.replaceAll("ß", "ss");
+ str = str.replaceAll("Ä", upcase ? "AE" : "Ae");
+ str = str.replaceAll("Ö", upcase ? "OE" : "Oe");
+ str = str.replaceAll("Ü", upcase ? "UE" : "Ue");
+ return str;
+ }
+
+ /**
* Returns "+" for positive values and "-" for negative values.
*
* @param value
Modified: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/OkCancelDialog.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/OkCancelDialog.java 2012-12-23 18:17:50 UTC (rev 2181)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/OkCancelDialog.java 2012-12-30 16:44:14 UTC (rev 2182)
@@ -130,7 +130,7 @@
* dialog.
*/
protected void init() {
- setModal(true);
+// setModal(true);
setPreferredSize( new Dimension(500,300) );
setLayout( new BorderLayout() );
Added: trunk/schmitzm-core/src/main/java/de/schmitzm/swing/event/DockingListener.java
===================================================================
--- trunk/schmitzm-core/src/main/java/de/schmitzm/swing/event/DockingListener.java (rev 0)
+++ trunk/schmitzm-core/src/main/java/de/schmitzm/swing/event/DockingListener.java 2012-12-30 16:44:14 UTC (rev 2182)
@@ -0,0 +1,462 @@
+/**
+ * Copyright (c) 2009 Martin O. J. Schmitz.
+ *
+ * This file is part of the SCHMITZM library - a collection of utility
+ * classes based on Java 1.6, focusing (not only) on Java Swing
+ * and the Geotools library.
+ *
+ * The SCHMITZM project is hosted at:
+ * http://wald.intevation.org/projects/schmitzm/
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public License
+ * as published by the Free Software Foundation; either version 3
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License (license.txt)
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ * or try this link: http://www.gnu.org/licenses/lgpl.html
+ *
+ * Contributors:
+ * Martin O. J. Schmitz - initial API and implementation
+ * Stefan A. Tzeggai - additional utility classes
+ */
+package de.schmitzm.swing.event;
+
+import java.awt.AWTException;
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.MouseInfo;
+import java.awt.Point;
+import java.awt.Robot;
+import java.awt.event.ComponentAdapter;
+import java.awt.event.ComponentEvent;
+import java.awt.event.ComponentListener;
+import java.awt.event.InputEvent;
+
+/**
+ * This {@link ComponentListener} lets a component (frame/window) dock at another component ("main component").
+ * If the "docking component" is docked (attached exactly next to northern/southern/eastern/western border) it is
+ * relatively moved whenever the main component changes location.
+ * To help the user to place the docking component in docking location, the listener provides a
+ * "magnetic" effect, which means that the docking component is automatically placed next to the main component,
+ * when its location becomes nearer than e.g. 10px.<br>
+ * <br>
+ * <b>TODO:/b>
+ * <ul>
+ * <li>Currently docking is lost, when main component is resized.</li>
+ * </ul>
+ * @author Martin O.J. Schmitz
+ *
+ */
+public class DockingListener extends ComponentAdapter {
+ /** Main component where {@link #dockedComp} docks on and which movement also causes
+ * movement of {@link #dockedComp} */
+ protected Component mainComp;
+ /** Component which docks at {@link #mainComp} and which is moved on {@link #mainComp}
+ * movement. */
+ protected Component dockedComp;
+ /** Threshold in px for "magnetic effect" */
+ protected int borderWidth;
+ /** Location of {@link #mainComp} on previous movement or resize event. */
+ protected Point mainCompLastLoc;
+ /** Location of {@link #dockedComp} on previous movement or resize event. */
+ protected Point dockedCompLastLoc;
+ /** Size of {@link #mainComp} on previous movement or resize event. */
+ protected Dimension mainCompLastDim;
+ /** Size of {@link #dockedComp} on previous movement or resize event. */
+ protected Dimension dockedCompLastDim;
+
+ /** Flag to avoid recursive calls of {@link #componentMoved(ComponentEvent)}. */
+ protected boolean valueIsAdjusting = false;
+ /** Flag to avoid unnecessary calculations in {@link #recalcDockDistances()} */
+ protected boolean distancedUpToDate = false;
+
+ /** Internal variable for Y-coordinate of main component's northern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int mainNY;
+ /** Internal variable for Y-coordinate of main component's southern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int mainSY;
+ /** Internal variable for X-coordinate of main component's western border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int mainWX;
+ /** Internal variable for X-coordinate of main component's eastern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int mainEX;
+ /** Internal variable for Y-coordinate of docking component's northern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockedNY;
+ /** Internal variable for Y-coordinate of docking component's southern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockedSY;
+ /** Internal variable for X-coordinate of docking component's western border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockedWX;
+ /** Internal variable for X-coordinate of docking component's eastern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockedEX;
+
+
+ /** Internal variable for distance between main component's northern and
+ * docking component's southern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockDistN;
+ /** Internal variable for distance between main component's southern and
+ * docking component's northern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockDistS;
+ /** Internal variable for distance between main component's western and
+ * docking component's eastern border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockDistW;
+ /** Internal variable for distance between main component's eastern and
+ * docking component's western border.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int dockDistE;
+
+ /** Internal variable for distance between main component's northern and
+ * docking component's southern border on previous movement or resize event.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int lastDockDistN;
+ /** Internal variable for distance between main component's southern and
+ * docking component's northern border on previous movement or resize event.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int lastDockDistS;
+ /** Internal variable for distance between main component's western and
+ * docking component's eastern border on previous movement or resize event.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int lastDockDistW;
+ /** Internal variable for distance between main component's eastern and
+ * docking component's western border on previous movement or resize event.
+ * Calculated by {@link #recalcDockDistances()}. */
+ protected int lastDockDistE;
+
+
+ /**
+ * Creates new listener.
+ * @param mainComp main component whose movement causes movement of docked component
+ * @param dockedComp docked component which is moved when main component is moved
+ */
+ public DockingListener(Component mainComp, Component dockedComp) {
+ this(10,mainComp,dockedComp);
+ }
+
+ /**
+ * Creates new listener.
+ * @param border threshold (in pixels) for "magnetic effect"
+ * @param mainComp main component whose movement causes movement of docked component
+ * @param dockedComp docked component which is moved when main component is moved
+ */
+ public DockingListener(int border, Component mainComp, Component dockedComp) {
+ this.mainComp = mainComp;
+ this.dockedComp = dockedComp;
+ this.borderWidth = border;
+ initializeLastLocationAndDimension();
+ }
+
+ /**
+ * Connects this listener as {@link ComponentListener} in main component and docked
+ * component.
+ */
+ public void connect() {
+ mainComp.addComponentListener(this);
+ dockedComp.addComponentListener(this);
+ }
+
+ /**
+ * Disconnects this listener form main component and docked component.
+ */
+ public void disconnect() {
+ mainComp.removeComponentListener(this);
+ dockedComp.removeComponentListener(this);
+ }
+
+ /**
+ * Performs docking and automatic movement of docking component.
+ */
+ @Override
+ public void componentMoved(ComponentEvent e) {
+ if ( valueIsAdjusting )
+ return;
+
+ valueIsAdjusting = true;
+ if ( e.getComponent() == mainComp ) {
+ Point mainCompLoc = mainComp.getLocation();
+ distancedUpToDate = true; // check docked on PREVIOUS states!
+ final boolean docked = isDocked(dockedComp);
+ distancedUpToDate = false;
+ if ( docked && mainCompLastLoc != null ) {
+ int diffX = mainCompLastLoc.x - mainCompLoc.x;
+ int diffY = mainCompLastLoc.y - mainCompLoc.y;
+ Point newLoc = dockedComp.getLocation();
+ newLoc.x -= diffX;
+ newLoc.y -= diffY;
+ dockedComp.setLocation(newLoc);
+ }
+ mainCompLastLoc = mainCompLoc;
+ recalcDockDistances(); // let dock on main window move
+ }
+
+
+ if ( e.getComponent() == dockedComp ) {
+ final Point dockedCompLoc = dockedComp.getLocation();
+ if ( isDocking(dockedComp) ) {
+ distancedUpToDate = true;
+// final Point mainCompLoc = mainComp.getLocation();
+// final Dimension mainCompDim = mainComp.getSize();
+// final Dimension dockedCompDim = dockedComp.getSize();
+// if ( isDockingNorth(dockedComp) )
+// dockedComp.setLocation( dockedCompLoc.x, mainCompLoc.y - dockedCompDim.height );
+// if ( isDockingSouth(dockedComp) )
+// dockedComp.setLocation( dockedCompLoc.x, mainCompLoc.y + mainCompDim.height );
+// if ( isDockingWest(dockedComp) )
+// dockedComp.setLocation( mainCompLoc.x - dockedCompDim.width, dockedCompLoc.y );
+// if ( isDockingEast(dockedComp) )
+// dockedComp.setLocation( mainCompLoc.x + mainCompDim.width, dockedCompLoc.y );
+
+ Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
+ if ( isDockingNorth(dockedComp) )
+ mouseLoc.y += dockDistN;
+ if ( isDockingSouth(dockedComp) )
+ mouseLoc.y -= dockDistS;
+ if ( isDockingWest(dockedComp) )
+ mouseLoc.x += dockDistW;
+ if ( isDockingEast(dockedComp) )
+ mouseLoc.x -= dockDistE;
+
+ try {
+ final Robot robot = new Robot();
+ robot.mouseMove(mouseLoc.x, mouseLoc.y);
+ robot.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
+// robot.mousePress(InputEvent.BUTTON1_DOWN_MASK);
+ } catch (AWTException e1) {
+ e1.printStackTrace();
+ }
+ distancedUpToDate = false;
+ recalcDockDistances();
+ }
+ dockedCompLastLoc = dockedCompLoc;
+ }
+
+ initializeLastLocationAndDimension();
+ valueIsAdjusting = false;
+ }
+
+ /**
+ * Resets {@link #mainCompLastDim} and {@link #dockedCompLastDim}.
+ */
+ @Override
+ public void componentResized(ComponentEvent e) {
+ if ( e.getComponent() == mainComp ) {
+ mainCompLastDim = mainComp.getSize();
+// recalcDockDistances();
+ }
+ if ( e.getComponent() == dockedComp ) {
+ dockedCompLastDim = dockedComp.getSize();
+// recalcDockDistances();
+ }
+
+ initializeLastLocationAndDimension();
+ }
+
+ /**
+ * Initializes {@link #mainCompLastDim}, {@link #mainCompLastLoc}, {@link #dockedCompLastDim} and
+ * {@link #dockedCompLastLoc} if not yet set.
+ */
+ protected void initializeLastLocationAndDimension() {
+ if ( mainCompLastLoc == null )
+ mainCompLastLoc = mainComp.getLocation();
+ if ( mainCompLastDim == null )
+ mainCompLastDim = mainComp.getSize();
+ if ( dockedCompLastLoc == null )
+ dockedCompLastLoc = dockedComp.getLocation();
+ if ( dockedCompLastDim == null )
+ dockedCompLastDim = dockedComp.getSize();
+ }
+
+
+ /**
+ * Checks whether components overlap in east/west direction.
+ */
+ private boolean checkOverlappingEastWest() {
+ return dockedWX >= mainWX && dockedWX <= mainEX || dockedEX >= mainWX && dockedEX <= mainEX;
+ }
+
+ /**
+ * Checks whether components overlap in north/south direction.
+ */
+ private boolean checkOverlappingNorthSouth() {
+ return dockedNY >= mainNY && dockedNY <= mainSY || dockedSY >= mainNY && dockedSY <= mainSY;
+ }
+
+ /**
+ * Checks whether docking component is docked at northern border.
+ */
+ public boolean isDockedNorth(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistN == 0 && checkOverlappingEastWest();
+ }
+
+ /**
+ * Checks whether docking component is docked at southern border.
+ */
+ public boolean isDockedSouth(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistS == 0 && checkOverlappingEastWest();
+ }
+
+ /**
+ * Checks whether docking component is docked at western border.
+ */
+ public boolean isDockedWest(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistW == 0 && checkOverlappingNorthSouth();
+ }
+
+ /**
+ * Checks whether docking component is docked at eastern border.
+ */
+ public boolean isDockedEast(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistE == 0 && checkOverlappingNorthSouth();
+ }
+
+
+ /**
+ * Checks whether docking component is docked at any border.
+ */
+ public boolean isDocked(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ distancedUpToDate = true;
+ boolean docked = isDockedNorth(comp) || isDockedSouth(comp) || isDockedWest(comp) || isDockedEast(comp);
+ distancedUpToDate = false;
+ return docked;
+ }
+
+ /**
+ * Checks whether docking component is currently in docking state at northern
+ * border (0 < {@link #dockDistN} < {@link #borderWidth}).
+ */
+ public boolean isDockingNorth(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistN > 0 && dockDistN < borderWidth && dockDistN < lastDockDistN && checkOverlappingEastWest();
+ }
+
+ /**
+ * Checks whether docking component is currently in docking state at southern
+ * border (0 < {@link #dockDistS} < {@link #borderWidth}).
+ */
+ public boolean isDockingSouth(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistS > 0 && dockDistS < borderWidth && dockDistS < lastDockDistS && checkOverlappingEastWest();
+ }
+
+ /**
+ * Checks whether docking component is currently in docking state at western
+ * border (0 < {@link #dockDistW} < {@link #borderWidth}).
+ */
+ public boolean isDockingWest(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistW > 0 && dockDistW < borderWidth && dockDistW < lastDockDistW && checkOverlappingNorthSouth();
+ }
+
+ /**
+ * Checks whether docking component is currently in docking state at eastern
+ * border (0 < {@link #dockDistE} < {@link #borderWidth}).
+ */
+ public boolean isDockingEast(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ return dockDistE > 0 && dockDistE < borderWidth && dockDistE < lastDockDistE && checkOverlappingNorthSouth();
+ }
+
+ /**
+ * Checks whether docking component is currently in docking state any border.
+ */
+ public boolean isDocking(Component comp) {
+ if ( comp != dockedComp )
+ return false;
+ recalcDockDistances();
+ distancedUpToDate = true;
+ boolean docking = isDockingNorth(comp) || isDockingSouth(comp) || isDockingWest(comp) || isDockingEast(comp);
+ distancedUpToDate = false;
+ return docking;
+
+ }
+
+ /**
+ * Recalculates the internal variables for border coordinates and docking distances.
+ * For performance reasons method does nothing if {@link #distancedUpToDate} is {@code true}.
+ */
+ protected void recalcDockDistances() {
+ if ( distancedUpToDate )
+ return;
+ // Calculcate dock distance for current locations
+ Point mainCompLoc = mainComp.getLocation();
+ Dimension mainCompDim = mainComp.getSize();
+ mainNY = mainCompLoc.y;
+ mainSY = mainNY + mainCompDim.height;
+ mainWX = mainCompLoc.x;
+ mainEX = mainWX + mainCompDim.width;
+
+ Point dockedCompLoc = dockedComp.getLocation();
+ Dimension dockedCompDim = dockedComp.getSize();
+ dockedNY = dockedCompLoc.y;
+ dockedSY = dockedNY + dockedCompDim.height;
+ dockedWX = dockedCompLoc.x;
+ dockedEX = dockedWX + dockedCompDim.width;
+
+ dockDistN = mainNY - dockedSY;
+ dockDistS = dockedNY - mainSY;
+ dockDistW = mainWX - dockedEX;
+ dockDistE = dockedWX - mainEX;
+
+ // Calculcate dock distance for last locations
+ if ( mainCompLastDim != null && mainCompLastLoc != null &&
+ dockedCompLastDim != null && dockedCompLastLoc != null ) {
+ mainCompLoc = mainCompLastLoc;
+ mainCompDim = mainCompLastDim;
+ mainNY = mainCompLoc.y;
+ mainSY = mainNY + mainCompDim.height;
+ mainWX = mainCompLoc.x;
+ mainEX = mainWX + mainCompDim.width;
+
+ dockedCompLoc = dockedCompLastLoc;
+ dockedCompDim = dockedCompLastDim;
+ dockedNY = dockedCompLoc.y;
+ dockedSY = dockedNY + dockedCompDim.height;
+ dockedWX = dockedCompLoc.x;
+ dockedEX = dockedWX + dockedCompDim.width;
+
+ lastDockDistN = mainNY - dockedSY;
+ lastDockDistS = dockedNY - mainSY;
+ lastDockDistW = mainWX - dockedEX;
+ lastDockDistE = dockedWX - mainEX;
+ }
+ }
+
+}
More information about the Schmitzm-commits
mailing list