[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