Path: blob/master/src/java.desktop/macosx/classes/com/apple/laf/AquaFocusHandler.java
41154 views
/*1* Copyright (c) 2011, 2012, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package com.apple.laf;2627import java.awt.*;28import java.awt.event.*;29import java.beans.*;3031import javax.swing.*;32import javax.swing.plaf.UIResource;3334/**35* This class is used by the text components, AquaEditorPaneUI, AquaTextAreaUI, AquaTextFieldUI and AquaTextPaneUI to control painting of the36* component's border. NOTE: It is assumed that this handler is added to components that extend JComponent.37*/38public class AquaFocusHandler implements FocusListener, PropertyChangeListener {39// Flag to help focusGained() determine whether the origin focus loss was due to a temporary focus loss or not.40private boolean wasTemporary = false;4142// Flag to track when a border needs a repaint due to a window becoming activate/inactive.43private boolean repaintBorder = false;4445protected static final String FRAME_ACTIVE_PROPERTY = "Frame.active";4647public void focusGained(final FocusEvent ev) {48// If we gained focus and it wasn't due to a previous temporary focus loss49// or the frame became active again, then repaint the border on the component.50if (!wasTemporary || repaintBorder) {51AquaBorder.repaintBorder((JComponent)ev.getSource());52repaintBorder = false;53}54wasTemporary = false;55}5657public void focusLost(final FocusEvent ev) {58wasTemporary = ev.isTemporary();5960// If we lost focus due to a permanent focus loss then repaint the border on the component.61if (!wasTemporary) {62AquaBorder.repaintBorder((JComponent)ev.getSource());63}64}6566public void propertyChange(final PropertyChangeEvent ev) {67if (!FRAME_ACTIVE_PROPERTY.equals(ev.getPropertyName())) return;6869if (Boolean.TRUE.equals(ev.getNewValue())) {70// The FRAME_ACTIVE_PROPERTY change event is sent before a component gains focus.71// We set a flag to help the focusGained() determine when they should be repainting72// the components focus.73repaintBorder = true;74} else if (wasTemporary) {75// The FRAME_ACTIVE_PROPERTY change event is sent after a component loses focus.76// We use the wasTemporary flag to determine if we need to repaint the border.77AquaBorder.repaintBorder((JComponent)ev.getSource());78}79}8081protected static boolean isActive(final JComponent c) {82if (c == null) return true;83final Object activeObj = c.getClientProperty(AquaFocusHandler.FRAME_ACTIVE_PROPERTY);84if (Boolean.FALSE.equals(activeObj)) return false;85return true;86}8788static final PropertyChangeListener REPAINT_LISTENER = new PropertyChangeListener() {89public void propertyChange(final PropertyChangeEvent evt) {90final Object source = evt.getSource();91if (source instanceof JComponent) {92((JComponent)source).repaint();93}94}95};9697protected static void install(final JComponent c) {98c.addPropertyChangeListener(FRAME_ACTIVE_PROPERTY, REPAINT_LISTENER);99}100101protected static void uninstall(final JComponent c) {102c.removePropertyChangeListener(FRAME_ACTIVE_PROPERTY, REPAINT_LISTENER);103}104105static void swapSelectionColors(final String prefix, final JTree c, final Object value) {106// <rdar://problem/8166173> JTree: selection color does not dim when window becomes inactive107// TODO inject our colors into the DefaultTreeCellRenderer108}109110static void swapSelectionColors(final String prefix, final JTable c, final Object value) {111if (!isComponentValid(c)) return;112113final Color bg = c.getSelectionBackground();114final Color fg = c.getSelectionForeground();115if (!(bg instanceof UIResource) || !(fg instanceof UIResource)) return;116117if (Boolean.FALSE.equals(value)) {118setSelectionColors(c, "Table.selectionInactiveForeground", "Table.selectionInactiveBackground");119return;120}121122if (Boolean.TRUE.equals(value)) {123setSelectionColors(c, "Table.selectionForeground", "Table.selectionBackground");124return;125}126}127128static void setSelectionColors(final JTable c, final String fgName, final String bgName) {129c.setSelectionForeground(UIManager.getColor(fgName));130c.setSelectionBackground(UIManager.getColor(bgName));131}132133static void swapSelectionColors(final String prefix, final JList<?> c, final Object value) {134if (!isComponentValid(c)) return;135136final Color bg = c.getSelectionBackground();137final Color fg = c.getSelectionForeground();138if (!(bg instanceof UIResource) || !(fg instanceof UIResource)) return;139140if (Boolean.FALSE.equals(value)) {141setSelectionColors(c, "List.selectionInactiveForeground", "List.selectionInactiveBackground");142return;143}144145if (Boolean.TRUE.equals(value)) {146setSelectionColors(c, "List.selectionForeground", "List.selectionBackground");147return;148}149}150151static void setSelectionColors(final JList<?> c, final String fgName, final String bgName) {152c.setSelectionForeground(UIManager.getColor(fgName));153c.setSelectionBackground(UIManager.getColor(bgName));154}155156static boolean isComponentValid(final JComponent c) {157if (c == null) return false;158final Window window = SwingUtilities.getWindowAncestor(c);159if (window == null) return false;160return true;161}162}163164165