📄 原始 -swingutilities.java
字号:
} /** * Compute and return the location of the icons origin, the * location of origin of the text baseline, and a possibly clipped * version of the compound labels string. Locations are computed * relative to the viewR rectangle. * This layoutCompoundLabel() does not know how to handle LEADING/TRAILING * values in horizontalTextPosition (they will default to RIGHT) and in * horizontalAlignment (they will default to CENTER). * Use the other version of layoutCompoundLabel() instead. */ private static String layoutCompoundLabelImpl( JComponent c, FontMetrics fm, String text, Icon icon, int verticalAlignment, int horizontalAlignment, int verticalTextPosition, int horizontalTextPosition, Rectangle viewR, Rectangle iconR, Rectangle textR, int textIconGap) { /* Initialize the icon bounds rectangle iconR. */ if (icon != null) { iconR.width = icon.getIconWidth(); iconR.height = icon.getIconHeight(); } else { iconR.width = iconR.height = 0; } /* Initialize the text bounds rectangle textR. If a null * or and empty String was specified we substitute "" here * and use 0,0,0,0 for textR. */ boolean textIsEmpty = (text == null) || text.equals(""); View v = null; if (textIsEmpty) { textR.width = textR.height = 0; text = ""; } else { v = (c != null) ? (View) c.getClientProperty("html") : null; if (v != null) { textR.width = (int) v.getPreferredSpan(View.X_AXIS); textR.height = (int) v.getPreferredSpan(View.Y_AXIS); } else { textR.width = computeStringWidth(fm,text); textR.height = fm.getHeight(); } } /* Unless both text and icon are non-null, we effectively ignore * the value of textIconGap. The code that follows uses the * value of gap instead of textIconGap. */ int gap = (textIsEmpty || (icon == null)) ? 0 : textIconGap; if (!textIsEmpty) { /* If the label text string is too wide to fit within the available * space "..." and as many characters as will fit will be * displayed instead. */ int availTextWidth; if (horizontalTextPosition == CENTER) { availTextWidth = viewR.width; } else { availTextWidth = viewR.width - (iconR.width + gap); } if (textR.width > availTextWidth) { if (v != null) { textR.width = availTextWidth; } else { String clipString = "..."; int totalWidth = computeStringWidth(fm,clipString); int nChars; for(nChars = 0; nChars < text.length(); nChars++) { totalWidth += fm.charWidth(text.charAt(nChars)); if (totalWidth > availTextWidth) { break; } } text = text.substring(0, nChars) + clipString; textR.width = computeStringWidth(fm,text); } } } /* Compute textR.x,y given the verticalTextPosition and * horizontalTextPosition properties */ if (verticalTextPosition == TOP) { if (horizontalTextPosition != CENTER) { textR.y = 0; } else { textR.y = -(textR.height + gap); } } else if (verticalTextPosition == CENTER) { textR.y = (iconR.height / 2) - (textR.height / 2); } else { // (verticalTextPosition == BOTTOM) if (horizontalTextPosition != CENTER) { textR.y = iconR.height - textR.height; } else { textR.y = (iconR.height + gap); } } if (horizontalTextPosition == LEFT) { textR.x = -(textR.width + gap); } else if (horizontalTextPosition == CENTER) { textR.x = (iconR.width / 2) - (textR.width / 2); } else { // (horizontalTextPosition == RIGHT) textR.x = (iconR.width + gap); } /* labelR is the rectangle that contains iconR and textR. * Move it to its proper position given the labelAlignment * properties. * * To avoid actually allocating a Rectangle, Rectangle.union * has been inlined below. */ int labelR_x = Math.min(iconR.x, textR.x); int labelR_width = Math.max(iconR.x + iconR.width, textR.x + textR.width) - labelR_x; int labelR_y = Math.min(iconR.y, textR.y); int labelR_height = Math.max(iconR.y + iconR.height, textR.y + textR.height) - labelR_y; int dx, dy; if (verticalAlignment == TOP) { dy = viewR.y - labelR_y; } else if (verticalAlignment == CENTER) { dy = (viewR.y + (viewR.height / 2)) - (labelR_y + (labelR_height / 2)); } else { // (verticalAlignment == BOTTOM) dy = (viewR.y + viewR.height) - (labelR_y + labelR_height); } if (horizontalAlignment == LEFT) { dx = viewR.x - labelR_x; } else if (horizontalAlignment == RIGHT) { dx = (viewR.x + viewR.width) - (labelR_x + labelR_width); } else { // (horizontalAlignment == CENTER) dx = (viewR.x + (viewR.width / 2)) - (labelR_x + (labelR_width / 2)); } /* Translate textR and glypyR by dx,dy. */ textR.x += dx; textR.y += dy; iconR.x += dx; iconR.y += dy; return text; } /** * Paint a component c on an abitrary graphics g in the * specified rectangle, specifying the rectangle's upper left corner * and size. The component is reparented to a private * container (whose parent becomes p) which prevents c.validate() and * and c.repaint() calls from propogating up the tree. The intermediate * container has no other effect. * * @param g the Graphics object to draw on * @param c the Component to draw * @param p the intermedate Container * @param x an int specifying the left side of the area draw in, in pixels, * measured from the left edge of the graphics context * @param y an int specifying the top of the area to draw in, in pixels * measured down from the top edge of the graphics context * @param w an int specifying the width of the area draw in, in pixels * @param h an int specifying the height of the area draw in, in pixels */ public static void paintComponent(Graphics g, Component c, Container p, int x, int y, int w, int h) { getCellRendererPane(c, p).paintComponent(g, c, p, x, y, w, h,false); } /** * Paint a component c on an abitrary graphics g in the * specified rectangle, specifying a Rectangle object. The component is reparented to a private * container (whose parent becomes p) which prevents c.validate() and * and c.repaint() calls from propogating up the tree. The intermediate * container has no other effect. * * @param g the Graphics object to draw on * @param c the Component to draw * @param p the intermedate Container * @param r the Rectangle to draw in */ public static void paintComponent(Graphics g, Component c, Container p, Rectangle r) { paintComponent(g, c, p, r.x, r.y, r.width, r.height); } /* * Ensure that cell renderer c has a ComponentShell parent and that * the shells parent is p. */ private static CellRendererPane getCellRendererPane(Component c, Container p) { Container shell = c.getParent(); if (shell instanceof CellRendererPane) { if (shell.getParent() != p) { p.add(shell); } } else { shell = new CellRendererPane(); shell.add(c); p.add(shell); } return (CellRendererPane)shell; } /** * A simple minded look and feel change: ask each node in the tree * to updateUI(), i.e. to initialize its UI property with the * current look and feel. */ public static void updateComponentTreeUI(Component c) { updateComponentTreeUI0(c); c.invalidate(); c.validate(); c.repaint(); } private static void updateComponentTreeUI0(Component c) { if (c instanceof JComponent) { ((JComponent) c).updateUI(); } Component[] children = null; if (c instanceof JMenu) { children = ((JMenu)c).getMenuComponents(); } else if (c instanceof Container) { children = ((Container)c).getComponents(); } if (children != null) { for(int i = 0; i < children.length; i++) { updateComponentTreeUI0(children[i]); } } } /** * Causes <i>doRun.run()</i> to be executed asynchronously on the * AWT event dispatching thread. This will happen after all * pending AWT events have been processed. This method should * be used when an application thread needs to update the GUI. * In the following example the invokeAndWait() calls queues * the doHelloWorld Runnable for the event dispatching thread and * then prints a message. * <pre> * Runnable doHelloWorld = new Runnable() { * public void run() { * System.out.println("Hello World on " + Thread.currentThread()); * } * }; * * SwingUtilities.invokeAndWait(doHelloWorld); * System.out.println("Waiting ... "); * </pre> * If invokeAndWait is called from the event dispatching thread, * e.g. from a JButtons ActionListener, the <i>doRun.run()</i> will * still be deferred till all pending events have been processed. * Note that if the <i>doRun.run()</i> throws an uncaught exception * the event dispatching thread will unwind (not the current thread). * <p> * Additional documentation and examples for this method can be * found in <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">. * * @see #invokeAndWait */ public static void invokeLater(Runnable doRun) { SystemEventQueueUtilities.postRunnable(doRun, null); } /** * Causes <i>doRun.run()</i> to be executed synchronously on the * AWT event dispatching thread. This call will block until * all pending AWT events have been processed and (then) * <i>doRun.run()</i> returns. This method should * be used when an application thread needs to update the GUI. * It should not be called from the EventDispatchThread. * Here's an example that creates a new application thread * that uses invokeAndWait() to print a string from the event * dispatching thread and then, when that's finished, print * a string from the application thread. * <pre> * final Runnable doHelloWorld = new Runnable() { * public void run() { * System.out.println("Hello World on " + Thread.currentThread()); * } * }; * * Thread appThread = new Thread() { * public void run() { * try { * SwingUtilities.invokeAndWait(doHelloWorld); * } * catch (Exception e) { * e.printStackTrace(); * } * System.out.println("Finished on " + Thread.currentThread()); * } * }; * appThread.start(); * </pre> * Note that if the Runnable.run() method throws an uncaught exception * (on the event dispatching thread) it's caught and rethrown, as * an InvocationTargetException, on the callers thread. * <p> * Additional documentation and examples for this method can be * found in <A HREF="http://java.sun.com/products/jfc/swingdoc-archive/threads.html">. * * @exception InterruptedException If we're interrupted while waiting for * the event dispatching thread to finish excecuting <i>doRun.run()</i> * @exception InvocationTargetException If <i>doRun.run()</i> throws * * @see #invokeLater */ public static void invokeAndWait(final Runnable doRun) throws InterruptedException, InvocationTargetException { if(isEventDispatchThread ()) { throw new Error("Cannot call invokeAndWait from the event dispatcher thread"); } Object lock = new Object() { public String toString() { return "SwingUtilities.invokeAndWait() lock for " + doRun; } }; Exception exc = null; synchronized(lock) { exc = SystemEventQueueUtilities.postRunnable(doRun, lock); lock.wait(); } if (exc != null) { throw new InvocationTargetException(exc); } } private static Class eventDispatchThreadClass = null; /** * Returns true if the current thread is an AWT event dispatching thread. * @return true if the current thread is an AWT event dispatching thread */ public static boolean isEventDispatchThread() { Thread currentThread = Thread.currentThread(); /* The first time we're called on what appears to be the event * dispatching thread, we stash the threads class in * eventDispatchThreadClass. Subsequently we effectively * return eventDispatchThreadClass instanceof Thread.currentThread(). */ if (eventDispatchThreadClass == null) { Class currentThreadClass = currentThread.getClass(); /* This test is a crock. It's known to work on all of the popular * JDK1.1 implementations available as of January 1998. */ if((currentThreadClass.getName().indexOf("EventDispatchThread") >= 0) || (currentThreadClass.getName().indexOf("JMEventQueue") >= 0)) { eventDispatchThreadClass = currentThreadClass; return true; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -