1/* 2 * Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26package com.apple.laf; 27 28import java.awt.*; 29 30import javax.swing.plaf.*; 31import javax.swing.text.JTextComponent; 32 33import apple.laf.JRSUIConstants.*; 34 35import com.apple.laf.AquaUtilControlSize.*; 36import com.apple.laf.AquaUtils.*; 37 38public class AquaTextFieldBorder extends AquaBorder { 39 private static final RecyclableSingleton<AquaTextFieldBorder> instance = new RecyclableSingletonFromDefaultConstructor<AquaTextFieldBorder>(AquaTextFieldBorder.class); 40 public static AquaTextFieldBorder getTextFieldBorder() { 41 return instance.get(); 42 } 43 44 public AquaTextFieldBorder() { 45 this(new SizeDescriptor(new SizeVariant().alterMargins(6, 7, 6, 7).alterInsets(3, 3, 3, 3))); 46 painter.state.set(Widget.FRAME_TEXT_FIELD); 47 painter.state.set(FrameOnly.YES); 48 painter.state.set(Size.LARGE); 49 } 50 51 public AquaTextFieldBorder(final SizeDescriptor sizeDescriptor) { 52 super(sizeDescriptor); 53 } 54 55 public AquaTextFieldBorder(final AquaTextFieldBorder other) { 56 super(other); 57 } 58 59 protected void setSize(final Size size) { 60 super.setSize(size); 61 painter.state.set(Size.LARGE); 62 } 63 64 public void paintBorder(final Component c, final Graphics g, int x, int y, int width, int height) { 65// g.setColor(Color.MAGENTA); 66// g.drawRect(x, y, width - 1, height - 1); 67 68 if (!(c instanceof JTextComponent)) { 69 painter.state.set(State.ACTIVE); 70 painter.state.set(Focused.NO); 71 painter.paint(g, c, x, y, width, height); 72 return; 73 } 74 75 final JTextComponent jc = (JTextComponent)c; 76 final State state = getStateFor(jc); 77 painter.state.set(state); 78 painter.state.set(State.ACTIVE == state && jc.hasFocus() ? Focused.YES : Focused.NO); 79 80 if (jc.isOpaque()) { 81 painter.paint(g, c, x, y, width, height); 82 return; 83 } 84 85 final int shrinkage = getShrinkageFor(jc, height); 86 final Insets subInsets = getSubInsets(shrinkage); 87 x += subInsets.left; 88 y += subInsets.top; 89 width -= (subInsets.left + subInsets.right); 90 height -= (subInsets.top + subInsets.bottom); 91 92 if (shrinkage > 0) { 93 final Rectangle clipBounds = g.getClipBounds(); 94 clipBounds.x += shrinkage; 95 clipBounds.width -= shrinkage * 2; 96 g.setClip(clipBounds); 97 } 98 99 painter.paint(g, c, x, y, width, height); 100// g.setColor(Color.ORANGE); 101// g.drawRect(x, y, width - 1, height - 1); 102 } 103 104 static int getShrinkageFor(final JTextComponent jc, final int height) { 105 if (jc == null) return 0; 106 final TextUI ui = jc.getUI(); 107 if (ui == null) return 0; 108 final Dimension size = ui.getPreferredSize(jc); 109 if (size == null) return 0; 110 final int shrinkage = size.height - height; 111 return (shrinkage < 0) ? 0 : (shrinkage > 3) ? 3 : shrinkage; 112 } 113 114 // this determines the rect that we should draw inset to our existing bounds 115 protected Insets getSubInsets(final int shrinkage) { 116 final Insets insets = sizeVariant.insets; 117 118 if (shrinkage > 0) { 119 return new InsetsUIResource(insets.top - shrinkage, insets.left, insets.bottom - shrinkage, insets.right); 120 } 121 122 return insets; 123 } 124 125 public Insets getBorderInsets(final Component c) { 126 if (!(c instanceof JTextComponent) || c.isOpaque()) return new InsetsUIResource(3, 7, 3, 7); 127 return new InsetsUIResource(5, 5, 5, 5); 128 } 129 130 protected static State getStateFor(final JTextComponent jc) { 131 if (!AquaFocusHandler.isActive(jc)) { 132 return State.INACTIVE; 133 } 134 135 if (!jc.isEnabled()) { 136 return State.DISABLED; 137 } 138 139 if (!jc.isEditable()) { 140 return State.DISABLED; 141 } 142 143 return State.ACTIVE; 144 } 145} 146