| /* |
| * Copyright (c) 2011, 2012, 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 java.awt.event.*; |
| import java.beans.*; |
| |
| import javax.swing.*; |
| import javax.swing.plaf.UIResource; |
| |
| /** |
| * This class is used by the text components, AquaEditorPaneUI, AquaTextAreaUI, AquaTextFieldUI and AquaTextPaneUI to control painting of the |
| * component's border. NOTE: It is assumed that this handler is added to components that extend JComponent. |
| */ |
| public class AquaFocusHandler implements FocusListener, PropertyChangeListener { |
| // Flag to help focusGained() determine whether the origin focus loss was due to a temporary focus loss or not. |
| private boolean wasTemporary = false; |
| |
| // Flag to track when a border needs a repaint due to a window becoming activate/inactive. |
| private boolean repaintBorder = false; |
| |
| protected static final String FRAME_ACTIVE_PROPERTY = "Frame.active"; |
| |
| public void focusGained(final FocusEvent ev) { |
| // If we gained focus and it wasn't due to a previous temporary focus loss |
| // or the frame became active again, then repaint the border on the component. |
| if (!wasTemporary || repaintBorder) { |
| AquaBorder.repaintBorder((JComponent)ev.getSource()); |
| repaintBorder = false; |
| } |
| wasTemporary = false; |
| } |
| |
| public void focusLost(final FocusEvent ev) { |
| wasTemporary = ev.isTemporary(); |
| |
| // If we lost focus due to a permanent focus loss then repaint the border on the component. |
| if (!wasTemporary) { |
| AquaBorder.repaintBorder((JComponent)ev.getSource()); |
| } |
| } |
| |
| public void propertyChange(final PropertyChangeEvent ev) { |
| if (!FRAME_ACTIVE_PROPERTY.equals(ev.getPropertyName())) return; |
| |
| if (Boolean.TRUE.equals(ev.getNewValue())) { |
| // The FRAME_ACTIVE_PROPERTY change event is sent before a component gains focus. |
| // We set a flag to help the focusGained() determine when they should be repainting |
| // the components focus. |
| repaintBorder = true; |
| } else if (wasTemporary) { |
| // The FRAME_ACTIVE_PROPERTY change event is sent after a component loses focus. |
| // We use the wasTemporary flag to determine if we need to repaint the border. |
| AquaBorder.repaintBorder((JComponent)ev.getSource()); |
| } |
| } |
| |
| protected static boolean isActive(final JComponent c) { |
| if (c == null) return true; |
| final Object activeObj = c.getClientProperty(AquaFocusHandler.FRAME_ACTIVE_PROPERTY); |
| if (Boolean.FALSE.equals(activeObj)) return false; |
| return true; |
| } |
| |
| static final PropertyChangeListener REPAINT_LISTENER = new PropertyChangeListener() { |
| public void propertyChange(final PropertyChangeEvent evt) { |
| final Object source = evt.getSource(); |
| if (source instanceof JComponent) { |
| ((JComponent)source).repaint(); |
| } |
| } |
| }; |
| |
| protected static void install(final JComponent c) { |
| c.addPropertyChangeListener(FRAME_ACTIVE_PROPERTY, REPAINT_LISTENER); |
| } |
| |
| protected static void uninstall(final JComponent c) { |
| c.removePropertyChangeListener(FRAME_ACTIVE_PROPERTY, REPAINT_LISTENER); |
| } |
| |
| static void swapSelectionColors(final String prefix, final JTree c, final Object value) { |
| // <rdar://problem/8166173> JTree: selection color does not dim when window becomes inactive |
| // TODO inject our colors into the DefaultTreeCellRenderer |
| } |
| |
| static void swapSelectionColors(final String prefix, final JTable c, final Object value) { |
| if (!isComponentValid(c)) return; |
| |
| final Color bg = c.getSelectionBackground(); |
| final Color fg = c.getSelectionForeground(); |
| if (!(bg instanceof UIResource) || !(fg instanceof UIResource)) return; |
| |
| if (Boolean.FALSE.equals(value)) { |
| setSelectionColors(c, "Table.selectionInactiveForeground", "Table.selectionInactiveBackground"); |
| return; |
| } |
| |
| if (Boolean.TRUE.equals(value)) { |
| setSelectionColors(c, "Table.selectionForeground", "Table.selectionBackground"); |
| return; |
| } |
| } |
| |
| static void setSelectionColors(final JTable c, final String fgName, final String bgName) { |
| c.setSelectionForeground(UIManager.getColor(fgName)); |
| c.setSelectionBackground(UIManager.getColor(bgName)); |
| } |
| |
| static void swapSelectionColors(final String prefix, final JList<?> c, final Object value) { |
| if (!isComponentValid(c)) return; |
| |
| final Color bg = c.getSelectionBackground(); |
| final Color fg = c.getSelectionForeground(); |
| if (!(bg instanceof UIResource) || !(fg instanceof UIResource)) return; |
| |
| if (Boolean.FALSE.equals(value)) { |
| setSelectionColors(c, "List.selectionInactiveForeground", "List.selectionInactiveBackground"); |
| return; |
| } |
| |
| if (Boolean.TRUE.equals(value)) { |
| setSelectionColors(c, "List.selectionForeground", "List.selectionBackground"); |
| return; |
| } |
| } |
| |
| static void setSelectionColors(final JList<?> c, final String fgName, final String bgName) { |
| c.setSelectionForeground(UIManager.getColor(fgName)); |
| c.setSelectionBackground(UIManager.getColor(bgName)); |
| } |
| |
| static boolean isComponentValid(final JComponent c) { |
| if (c == null) return false; |
| final Window window = SwingUtilities.getWindowAncestor(c); |
| if (window == null) return false; |
| return true; |
| } |
| } |