/* * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code 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 * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package com.apple.laf; import java.awt.*; import javax.swing.*; import javax.swing.border.Border; import javax.swing.plaf.UIResource; import javax.swing.text.JTextComponent; import apple.laf.*; import apple.laf.JRSUIConstants.*; import com.apple.laf.AquaUtilControlSize.*; public abstract class AquaBorder implements Border, UIResource { protected final AquaPainter painter; protected final SizeDescriptor sizeDescriptor; protected SizeVariant sizeVariant; protected AquaBorder(final SizeDescriptor sizeDescriptor) { this.sizeDescriptor = sizeDescriptor; this.sizeVariant = sizeDescriptor.get(Size.REGULAR); this.painter = createPainter(); } protected AquaPainter createPainter() { final AquaPainter painter = AquaPainter.create(JRSUIState.getInstance()); painter.state.set(AlignmentVertical.CENTER); painter.state.set(AlignmentHorizontal.CENTER); return painter; } protected AquaBorder(final AquaBorder other) { this.sizeDescriptor = other.sizeDescriptor; this.sizeVariant = other.sizeVariant; this.painter = AquaPainter.create(other.painter.state.derive()); painter.state.set(AlignmentVertical.CENTER); painter.state.set(AlignmentHorizontal.CENTER); } protected void setSize(final Size size) { sizeVariant = sizeDescriptor.get(size); painter.state.set(size); } @Override public Insets getBorderInsets(final Component c) { return (Insets) sizeVariant.margins.clone(); } protected AquaBorder deriveBorderForSize(final Size size) { try { final Class clazz = getClass(); @SuppressWarnings("deprecation") final AquaBorder border = clazz.getConstructor(new Class[] { clazz }).newInstance(new Object[] { this }); border.setSize(size); return border; } catch (final Throwable e) { return null; } } public static void repaintBorder(final JComponent c) { JComponent borderedComponent = c; Border border = c.getBorder(); if (border == null) { // See if it's inside a JScrollpane or something final Container p = c.getParent(); if (p instanceof JViewport) { borderedComponent = (JComponent)p.getParent(); if (borderedComponent != null) border = borderedComponent.getBorder(); } } // If we really don't have a border, then bail // It might be a compound border with a ThemeBorder inside // The check for that case is tricky, so we just go ahead and repaint any border if (border == null || borderedComponent == null) return; final int width = borderedComponent.getWidth(); final int height = borderedComponent.getHeight(); final Insets i = borderedComponent.getInsets(); borderedComponent.repaint(0, 0, width, i.top); // Top edge borderedComponent.repaint(0, 0, i.left, height); // Left edge borderedComponent.repaint(0, height - i.bottom, width, i.bottom); // Bottom edge borderedComponent.repaint(width - i.right, 0, i.right, height); // Right edge } // The JScrollPane doesn't let us know if its viewport view has focus protected boolean isFocused(final Component c) { // Being really paranoid in case this Component isn't a Swing component Component focusable = c; if (c instanceof JScrollPane) { final JViewport vp = ((JScrollPane)c).getViewport(); if (vp != null) { focusable = vp.getView(); // Lists, Tables & Trees get focus rings, TextAreas don't (JBuilder puts TextField border on TextAreas) if (focusable instanceof JTextComponent) return false; } } else if (focusable instanceof JTextComponent) { // non-editable text areas don't draw the focus ring if (!((javax.swing.text.JTextComponent)focusable).isEditable()) return false; } return (focusable != null && focusable instanceof JComponent && ((JComponent)focusable).hasFocus()); } @Override public boolean isBorderOpaque() { return false; } @Override public void paintBorder(final Component c, final Graphics g, final int x, final int y, final int w, final int h) { painter.paint(g, c, x, y, w, h); } static class Default extends AquaBorder { Default() { super(new SizeDescriptor(new SizeVariant())); } } }