1 /* 2 * @(#)QuaquaTextAreaUI.java 1.4 2007-01-16 3 * 4 * Copyright (c) 2004-2007 Werner Randelshofer 5 * Staldenmattweg 2, Immensee, CH-6405, Switzerland. 6 * All rights reserved. 7 * 8 * The copyright of this software is owned by Werner Randelshofer. 9 * You may not use, copy or modify this software, except in 10 * accordance with the license agreement you entered into with 11 * Werner Randelshofer. For details see accompanying license terms. 12 */ 13 14 package ch.randelshofer.quaqua; 15 16 import ch.randelshofer.quaqua.util.*; 17 import ch.randelshofer.quaqua.util.Debug; 18 import java.awt.*; 19 import java.awt.event.*; 20 import java.beans.*; 21 22 import javax.swing.*; 23 import javax.swing.plaf.*; 24 import javax.swing.plaf.basic.*; 25 import javax.swing.text.*; 26 import javax.swing.border.*; 27 28 29 /** 30 * QuaquaTextAreaUI. 31 * 32 * @author Werner Randelshofer 33 * @version 1.4 2007-01-16 Factored focus listener out into QuaquaViewportView. 34 * <br>1.3 2006-04-24 Added support for .popupHandler UIManager property. 35 * <br>1.2 2005-07-17 Adapted to changes in interface VisuallyLayoutable. 36 * <br>1.1.1 2005-06-30 Fixed NPE in method getVisualBounds. 37 * <br>1.1 2004-12-02 Use QuaquaTextEditorKit instead of 38 * DefaulTextEditorKit. 39 * <br>1.0 July 4, 2004 Created. 40 */ 41 public class QuaquaTextAreaUI extends BasicTextAreaUI implements VisuallyLayoutable { 42 boolean oldDragState = false; 43 private MouseListener popupListener; 44 createUI(JComponent jcomponent)45 public static ComponentUI createUI(JComponent jcomponent) { 46 return new QuaquaTextAreaUI(); 47 } 48 installDefaults()49 protected void installDefaults() { 50 if (! QuaquaUtilities.isHeadless()) { 51 oldDragState = Methods.invokeGetter(getComponent(),"getDragEnabled", true); 52 Methods.invokeIfExists(getComponent(),"setDragEnabled", true); 53 } 54 super.installDefaults(); 55 } 56 uninstallDefaults()57 protected void uninstallDefaults() { 58 if (QuaquaUtilities.isHeadless()) { 59 Methods.invokeIfExists(getComponent(),"setDragEnabled", oldDragState); 60 } 61 super.uninstallDefaults(); 62 } 63 installListeners()64 protected void installListeners() { 65 popupListener = createPopupListener(); 66 if (popupListener != null) { 67 getComponent().addMouseListener(popupListener); 68 } 69 super.installListeners(); 70 } 71 uninstallListeners()72 protected void uninstallListeners() { 73 if (popupListener != null) { 74 getComponent().removeMouseListener(popupListener); 75 popupListener = null; 76 } 77 super.uninstallListeners(); 78 } 79 createPopupListener()80 protected MouseListener createPopupListener() { 81 return (MouseListener) UIManager.get(getPropertyPrefix()+".popupHandler"); 82 } 83 84 85 /** 86 * Fetches the EditorKit for the UI. 87 * 88 * @param tc the text component for which this UI is installed 89 * @return the editor capabilities 90 * @see TextUI#getEditorKit 91 */ getEditorKit(JTextComponent tc)92 public EditorKit getEditorKit(JTextComponent tc) { 93 return QuaquaTextFieldUI.defaultKit; 94 } 95 propertyChange(PropertyChangeEvent event)96 public void propertyChange(PropertyChangeEvent event) { 97 String name = event.getPropertyName(); 98 if (name.equals("Frame.active")) { 99 QuaquaUtilities.repaintBorder(getComponent()); 100 } else if (name.equals("JComponent.sizeVariant")) { 101 QuaquaUtilities.applySizeVariant(getComponent()); 102 } else { 103 super.propertyChange(event); 104 } 105 } 106 paintSafely(Graphics g)107 protected void paintSafely(Graphics g) { 108 Object oldHints = QuaquaUtilities.beginGraphics((Graphics2D) g); 109 super.paintSafely(g); 110 QuaquaUtilities.endGraphics((Graphics2D) g, oldHints); 111 Debug.paint(g, getComponent(), this); 112 } 113 /* 114 protected HierarchyListener createHierarchyListener() { 115 return new ComponentActivationHandler(getComponent()); 116 }*/ 117 createCaret()118 protected Caret createCaret() { 119 Window window = SwingUtilities.getWindowAncestor(getComponent()); 120 QuaquaCaret caret = new QuaquaCaret(window, getComponent()); 121 return caret; 122 } 123 createHighlighter()124 protected Highlighter createHighlighter() { 125 return new QuaquaHighlighter(); 126 } 127 getBaseline(JComponent c, int width, int height)128 public int getBaseline(JComponent c, int width, int height) { 129 JTextComponent tc = (JTextComponent) c; 130 Insets insets = tc.getInsets(); 131 FontMetrics fm = tc.getFontMetrics(tc.getFont()); 132 return insets.top + fm.getAscent(); 133 } 134 getVisualBounds(JComponent c, int type, int width, int height)135 public Rectangle getVisualBounds(JComponent c, int type, int width, int height) { 136 Rectangle bounds = new Rectangle(0,0,width,height); 137 if (type == VisuallyLayoutable.CLIP_BOUNDS) { 138 return bounds; 139 } 140 141 JTextComponent b = (JTextComponent) c; 142 if (type == VisuallyLayoutable.COMPONENT_BOUNDS 143 && b.getBorder() != null) { 144 Border border = b.getBorder(); 145 if (border instanceof UIResource) { 146 //InsetsUtil.subtractInto(getVisualMargin(b), bounds); 147 // FIXME - Should derive this value from border 148 // FIXME - If we had layout managers that supported baseline alignment, 149 // we wouldn't have to subtract one here 150 bounds.height -= 1; 151 } 152 } else { 153 bounds = getVisibleEditorRect(); 154 FontMetrics fm = c.getFontMetrics(c.getFont()); 155 156 int baseline = getBaseline(c, width, height); 157 Rectangle textBounds = Fonts.getPerceivedBounds(b.getText(), b.getFont(), c); 158 if (bounds == null) { 159 bounds = textBounds; 160 bounds.y += baseline; 161 } else { 162 bounds.y = baseline + textBounds.y; 163 bounds.height = textBounds.height; 164 } 165 bounds.x += 1; 166 bounds.width -= 2; 167 } 168 return bounds; 169 } 170 } 171