Coverage Report - net.miginfocom.swing.SwingComponentWrapper
 
Classes in this File Line Coverage Branch Coverage Complexity
SwingComponentWrapper
N/A
N/A
3.649
 
 1  
 package net.miginfocom.swing;
 2  
 /*
 3  
  * License (BSD):
 4  
  * ==============
 5  
  *
 6  
  * Copyright (c) 2004, Mikael Grev, MiG InfoCom AB. (miglayout (at) miginfocom (dot) com)
 7  
  * All rights reserved.
 8  
  *
 9  
  * Redistribution and use in source and binary forms, with or without modification,
 10  
  * are permitted provided that the following conditions are met:
 11  
  * Redistributions of source code must retain the above copyright notice, this list
 12  
  * of conditions and the following disclaimer.
 13  
  * Redistributions in binary form must reproduce the above copyright notice, this
 14  
  * list of conditions and the following disclaimer in the documentation and/or other
 15  
  * materials provided with the distribution.
 16  
  * Neither the name of the MiG InfoCom AB nor the names of its contributors may be
 17  
  * used to endorse or promote products derived from this software without specific
 18  
  * prior written permission.
 19  
  *
 20  
  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 21  
  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 22  
  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 23  
  * IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 24  
  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 25  
  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 26  
  * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 27  
  * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 28  
  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
 29  
  * OF SUCH DAMAGE.
 30  
  *
 31  
  * @version 1.0
 32  
  * @author Mikael Grev, MiG InfoCom AB
 33  
  *         Date: 2006-sep-08
 34  
  */
 35  
 import net.miginfocom.layout.ComponentWrapper;
 36  
 import net.miginfocom.layout.ContainerWrapper;
 37  
 import net.miginfocom.layout.PlatformDefaults;
 38  
 
 39  
 import javax.swing.*;
 40  
 import javax.swing.text.JTextComponent;
 41  
 import java.awt.*;
 42  
 import java.awt.geom.Rectangle2D;
 43  
 import java.lang.reflect.Method;
 44  
 import java.util.IdentityHashMap;
 45  
 
 46  
 /**
 47  
  */
 48  
 public class SwingComponentWrapper implements ComponentWrapper
 49  
 {
 50  
         private static boolean maxSet = false;
 51  
 
 52  
         private static boolean vp = true;
 53  
 
 54  
         /** Debug color for component bounds outline.
 55  
          */
 56  
         private static final Color DB_COMP_OUTLINE = new Color(0, 0, 200);
 57  
 
 58  
         private final Component c;
 59  
         private int compType = TYPE_UNSET;
 60  
         private Boolean bl = null;
 61  
         private boolean prefCalled = false;
 62  
 
 63  
         public SwingComponentWrapper(Component c)
 64  
         {
 65  
                 this.c = c;
 66  
         }
 67  
 
 68  
         public final int getBaseline(int width, int height)
 69  
         {
 70  
                 if (BL_METHOD == null)
 71  
                         return -1;
 72  
 
 73  
                 try {
 74  
                         Object[] args = new Object[] {
 75  
                                 width < 0 ? c.getWidth() : width,
 76  
                                 height < 0 ? c.getHeight() : height
 77  
                         };
 78  
 
 79  
                         return (Integer) BL_METHOD.invoke(c, args);
 80  
                 } catch (Exception e) {
 81  
                         return -1;
 82  
                 }
 83  
         }
 84  
 
 85  
         public final Object getComponent()
 86  
         {
 87  
                 return c;
 88  
         }
 89  
 
 90  
         /** Cache.
 91  
          */
 92  
         private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP = new IdentityHashMap<FontMetrics, Point.Float>(4);
 93  
         private final static Font SUBST_FONT = new Font("sansserif", Font.PLAIN, 11);
 94  
 
 95  
         public final float getPixelUnitFactor(boolean isHor)
 96  
         {
 97  
                 switch (PlatformDefaults.getLogicalPixelBase()) {
 98  
                         case PlatformDefaults.BASE_FONT_SIZE:
 99  
                                 Font font = c.getFont();
 100  
                                 FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT);
 101  
                                 Point.Float p = FM_MAP.get(fm);
 102  
                                 if (p == null) {
 103  
                                         Rectangle2D r = fm.getStringBounds("X", c.getGraphics());
 104  
                                         p = new Point.Float(((float) r.getWidth()) / 6f, ((float) r.getHeight()) / 13.27734375f);
 105  
                                         FM_MAP.put(fm, p);
 106  
                                 }
 107  
                                 return isHor ? p.x : p.y;
 108  
 
 109  
                         case PlatformDefaults.BASE_SCALE_FACTOR:
 110  
 
 111  
                                 Float s = isHor ? PlatformDefaults.getHorizontalScaleFactor() : PlatformDefaults.getVerticalScaleFactor();
 112  
                                 if (s != null)
 113  
                                         return s;
 114  
                                 return (isHor ? getHorizontalScreenDPI() : getVerticalScreenDPI()) / (float) PlatformDefaults.getDefaultDPI();
 115  
 
 116  
                         default:
 117  
                                 return 1f;
 118  
                 }
 119  
         }
 120  
 
 121  
 //        /** Cache.
 122  
 //         */
 123  
 //        private final static IdentityHashMap<FontMetrics, Point.Float> FM_MAP2 = new IdentityHashMap<FontMetrics, Point.Float>(4);
 124  
 //        private final static Font SUBST_FONT2 = new Font("sansserif", Font.PLAIN, 11);
 125  
 //
 126  
 //        public float getDialogUnit(boolean isHor)
 127  
 //        {
 128  
 //                Font font = c.getFont();
 129  
 //                FontMetrics fm = c.getFontMetrics(font != null ? font : SUBST_FONT2);
 130  
 //                Point.Float dluP = FM_MAP2.get(fm);
 131  
 //                if (dluP == null) {
 132  
 //                        float w = fm.charWidth('X') / 4f;
 133  
 //                        int ascent = fm.getAscent();
 134  
 //                        float h = (ascent > 14 ? ascent : ascent + (15 - ascent) / 3) / 8f;
 135  
 //
 136  
 //                        dluP = new Point.Float(w, h);
 137  
 //                        FM_MAP2.put(fm, dluP);
 138  
 //                }
 139  
 //                return isHor ? dluP.x : dluP.y;
 140  
 //        }
 141  
 
 142  
         public final int getX()
 143  
         {
 144  
                 return c.getX();
 145  
         }
 146  
 
 147  
         public final int getY()
 148  
         {
 149  
                 return c.getY();
 150  
         }
 151  
 
 152  
         public final int getHeight()
 153  
         {
 154  
                 return c.getHeight();
 155  
         }
 156  
 
 157  
         public final int getWidth()
 158  
         {
 159  
                 return c.getWidth();
 160  
         }
 161  
 
 162  
         public final int getScreenLocationX()
 163  
         {
 164  
                 Point p = new Point();
 165  
                 SwingUtilities.convertPointToScreen(p, c);
 166  
                 return p.x;
 167  
         }
 168  
 
 169  
         public final int getScreenLocationY()
 170  
         {
 171  
                 Point p = new Point();
 172  
                 SwingUtilities.convertPointToScreen(p, c);
 173  
                 return p.y;
 174  
         }
 175  
 
 176  
         public final int getMinimumHeight(int sz)
 177  
         {
 178  
                 if (prefCalled == false) {
 179  
                         c.getPreferredSize(); // To defeat a bug where the minimum size is different before and after the first call to getPreferredSize();
 180  
                         prefCalled = true;
 181  
                 }
 182  
                 return c.getMinimumSize().height;
 183  
         }
 184  
 
 185  
         public final int getMinimumWidth(int sz)
 186  
         {
 187  
                 if (prefCalled == false) {
 188  
                         c.getPreferredSize(); // To defeat a bug where the minimum size is different before and after the first call to getPreferredSize();
 189  
                         prefCalled = true;
 190  
                 }
 191  
                 return c.getMinimumSize().width;
 192  
         }
 193  
         public final int getPreferredHeight(int sz)
 194  
         {
 195  
                 // If the component has not gotten size yet and there is a size hint, trick Swing to return a better height.
 196  
                 if (c.getWidth() == 0 && c.getHeight() == 0 && sz != -1)
 197  
                         c.setBounds(c.getX(), c.getY(), sz, 1);
 198  
 
 199  
                 return c.getPreferredSize().height;
 200  
         }
 201  
 
 202  
         public final int getPreferredWidth(int sz)
 203  
         {
 204  
                 // If the component has not gotten size yet and there is a size hint, trick Swing to return a better height.
 205  
                 if (c.getWidth() == 0 && c.getHeight() == 0 && sz != -1)
 206  
                         c.setBounds(c.getX(), c.getY(), 1, sz);
 207  
 
 208  
                 return c.getPreferredSize().width;
 209  
         }
 210  
 
 211  
         public final int getMaximumHeight(int sz)
 212  
         {
 213  
                 if (!isMaxSet(c))
 214  
                         return Short.MAX_VALUE;
 215  
 
 216  
                 return c.getMaximumSize().height;
 217  
         }
 218  
 
 219  
         public final int getMaximumWidth(int sz)
 220  
         {
 221  
                 if (!isMaxSet(c))
 222  
                         return Short.MAX_VALUE;
 223  
 
 224  
                 return c.getMaximumSize().width;
 225  
         }
 226  
 
 227  
 
 228  
         private boolean isMaxSet(Component c)
 229  
         {
 230  
                 if (IMS_METHOD != null) {
 231  
                         try {
 232  
                                 return (Boolean) IMS_METHOD.invoke(c, (Object[]) null);
 233  
                         } catch (Exception e) {
 234  
                                 IMS_METHOD = null;  // So we do not try every time.
 235  
                         }
 236  
                 }
 237  
                 return isMaxSizeSetOn1_4();
 238  
         }
 239  
 
 240  
         public final ContainerWrapper getParent()
 241  
         {
 242  
                 Container p = c.getParent();
 243  
                 return p != null ? new SwingContainerWrapper(p) : null;
 244  
         }
 245  
 
 246  
         public final int getHorizontalScreenDPI()
 247  
         {
 248  
                 return PlatformDefaults.getDefaultDPI();
 249  
         }
 250  
 
 251  
         public final int getVerticalScreenDPI()
 252  
         {
 253  
                 return PlatformDefaults.getDefaultDPI();
 254  
         }
 255  
 
 256  
         public final int getScreenWidth()
 257  
         {
 258  
                 try {
 259  
                         return c.getToolkit().getScreenSize().width;
 260  
                 } catch (HeadlessException ex) {
 261  
                         return 1024;
 262  
                 }
 263  
         }
 264  
 
 265  
         public final int getScreenHeight()
 266  
         {
 267  
                 try {
 268  
                         return c.getToolkit().getScreenSize().height;
 269  
                 } catch (HeadlessException ex) {
 270  
                         return 768;
 271  
                 }
 272  
         }
 273  
 
 274  
         public final boolean hasBaseline()
 275  
         {
 276  
                 if (bl == null) {
 277  
                         try {
 278  
                                 if (BL_RES_METHOD == null || BL_RES_METHOD.invoke(c).toString().equals("OTHER")) {
 279  
                                         bl = Boolean.FALSE;
 280  
                                 } else {
 281  
                                         Dimension d = c.getMinimumSize();
 282  
                                         bl = getBaseline(d.width, d.height) > -1;
 283  
                                 }
 284  
                         } catch (Throwable ex) {
 285  
                                 bl = Boolean.FALSE;
 286  
                         }
 287  
                 }
 288  
                 return bl;
 289  
         }
 290  
 
 291  
         public final String getLinkId()
 292  
         {
 293  
                 return c.getName();
 294  
         }
 295  
 
 296  
         public final void setBounds(int x, int y, int width, int height)
 297  
         {
 298  
                 c.setBounds(x, y, width, height);
 299  
         }
 300  
 
 301  
         public boolean isVisible()
 302  
         {
 303  
                 return c.isVisible();
 304  
         }
 305  
 
 306  
         public final int[] getVisualPadding()
 307  
         {
 308  
                 if (vp && c instanceof JTabbedPane) {
 309  
                         if (UIManager.getLookAndFeel().getClass().getName().endsWith("WindowsLookAndFeel"))
 310  
                                 return new int[] {-1, 0, 2, 2};
 311  
                 }
 312  
 
 313  
                 return null;
 314  
         }
 315  
 
 316  
         public static boolean isMaxSizeSetOn1_4()
 317  
         {
 318  
                 return maxSet;
 319  
         }
 320  
 
 321  
         public static void setMaxSizeSetOn1_4(boolean b)
 322  
         {
 323  
                 maxSet = b;
 324  
         }
 325  
 
 326  
         public static boolean isVisualPaddingEnabled()
 327  
         {
 328  
                 return vp;
 329  
         }
 330  
 
 331  
         public static void setVisualPaddingEnabled(boolean b)
 332  
         {
 333  
                 vp = b;
 334  
         }
 335  
 
 336  
         public final void paintDebugOutline()
 337  
         {
 338  
                 if (c.isShowing() == false)
 339  
                         return;
 340  
 
 341  
                 Graphics2D g = (Graphics2D) c.getGraphics();
 342  
                 if (g == null)
 343  
                         return;
 344  
 
 345  
                 g.setPaint(DB_COMP_OUTLINE);
 346  
                 g.setStroke(new BasicStroke(1f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10f, new float[] {2f, 4f}, 0));
 347  
                 g.drawRect(0, 0, getWidth() - 1, getHeight() - 1);
 348  
         }
 349  
 
 350  
         public int getComponetType(boolean disregardScrollPane)
 351  
         {
 352  
                 if (compType == TYPE_UNSET)
 353  
                         compType = checkType(disregardScrollPane);
 354  
 
 355  
                 return compType;
 356  
         }
 357  
 
 358  
         public int getLayoutHashCode()
 359  
         {
 360  
                 Dimension d = c.getMaximumSize();
 361  
                 int hash = d.width + (d.height << 5);
 362  
 
 363  
                 d = c.getPreferredSize();
 364  
                 hash += (d.width << 10) + (d.height << 15);
 365  
 
 366  
                 d = c.getMinimumSize();
 367  
                 hash += (d.width << 20) + (d.height << 25);
 368  
 
 369  
                 if (c.isVisible())
 370  
                         hash += 1324511;
 371  
 
 372  
                 String id = getLinkId();
 373  
                 if (id != null)
 374  
                         hash += id.hashCode();
 375  
 
 376  
                 return hash;
 377  
         }
 378  
 
 379  
         private int checkType(boolean disregardScrollPane)
 380  
         {
 381  
                 Component c = this.c;
 382  
 
 383  
                 if (disregardScrollPane) {
 384  
                         if (c instanceof JScrollPane) {
 385  
                                 c = ((JScrollPane) c).getViewport().getView();
 386  
                         } else if (c instanceof ScrollPane) {
 387  
                                 c = ((ScrollPane) c).getComponent(0);
 388  
                         }
 389  
                 }
 390  
 
 391  
                 if (c instanceof JTextField || c instanceof TextField) {
 392  
                         return TYPE_TEXT_FIELD;
 393  
                 } else if (c instanceof JLabel || c instanceof Label) {
 394  
                         return TYPE_LABEL;
 395  
                 } else if (c instanceof JToggleButton || c instanceof Checkbox) {
 396  
                         return TYPE_CHECK_BOX;
 397  
                 } else if (c instanceof AbstractButton || c instanceof Button) {
 398  
                         return TYPE_BUTTON;
 399  
                 } else if (c instanceof JComboBox || c instanceof Choice) {
 400  
                         return TYPE_LABEL;
 401  
                 } else if (c instanceof JTextComponent || c instanceof TextComponent) {
 402  
                         return TYPE_TEXT_AREA;
 403  
                 } else if (c instanceof JPanel || c instanceof Canvas) {
 404  
                         return TYPE_PANEL;
 405  
                 } else if (c instanceof JList || c instanceof List) {
 406  
                         return TYPE_LIST;
 407  
                 } else if (c instanceof JTable) {
 408  
                         return TYPE_TABLE;
 409  
                 } else if (c instanceof JSeparator) {
 410  
                         return TYPE_SEPARATOR;
 411  
                 } else if (c instanceof JSpinner) {
 412  
                         return TYPE_SPINNER;
 413  
                 } else if (c instanceof JProgressBar) {
 414  
                         return TYPE_PROGRESS_BAR;
 415  
                 } else if (c instanceof JSlider) {
 416  
                         return TYPE_SLIDER;
 417  
                 } else if (c instanceof JScrollPane) {
 418  
                         return TYPE_SCROLL_PANE;
 419  
                 } else if (c instanceof JScrollBar || c instanceof Scrollbar) {
 420  
                         return TYPE_SCROLL_BAR;
 421  
                 } else if (c instanceof Container) {    // only AWT components is not containers.
 422  
                         return TYPE_CONTAINER;
 423  
                 }
 424  
                 return TYPE_UNKNOWN;
 425  
         }
 426  
 
 427  
         public final int hashCode()
 428  
         {
 429  
                 return getComponent().hashCode();
 430  
         }
 431  
 
 432  
         public final boolean equals(Object o)
 433  
         {
 434  
                 if (o instanceof ComponentWrapper == false)
 435  
                         return false;
 436  
 
 437  
                 return getComponent().equals(((ComponentWrapper) o).getComponent());
 438  
         }
 439  
 
 440  
         /** Cached method used for getting base line with reflection.
 441  
          */
 442  
         private static Method BL_METHOD = null;
 443  
         private static Method BL_RES_METHOD = null;
 444  
         static {
 445  
                 try {
 446  
                         BL_METHOD = Component.class.getDeclaredMethod("getBaseline", new Class[] {int.class, int.class});
 447  
                         BL_RES_METHOD = Component.class.getDeclaredMethod("getBaselineResizeBehavior"); // 3.7.2: Removed Class<?> null since that made the method inaccessible.
 448  
                 } catch (Throwable e) { // No such method or security exception
 449  
                 }
 450  
         }
 451  
 
 452  
         private static Method IMS_METHOD = null;
 453  
         static {
 454  
                 try {
 455  
                         IMS_METHOD = Component.class.getDeclaredMethod("isMaximumSizeSet", (Class[]) null);
 456  
                 } catch (Throwable e) { // No such method or security exception
 457  
                 }
 458  
         }
 459  
 }