blob: 9fa579b24f42595e0412e8f957ac9f15cfbfeaa9 [file] [log] [blame]
/*
* Copyright (c) 1999, 2006, 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 javax.swing.plaf.basic;
import java.awt.event.ActionEvent;
import java.awt.KeyboardFocusManager;
import java.awt.Component;
import java.awt.Point;
import java.awt.Rectangle;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
import javax.swing.plaf.*;
import sun.swing.DefaultLookup;
import sun.swing.UIAction;
/**
* Basic implementation of RootPaneUI, there is one shared between all
* JRootPane instances.
*
* @author Scott Violet
* @since 1.3
*/
public class BasicRootPaneUI extends RootPaneUI implements
PropertyChangeListener {
private static RootPaneUI rootPaneUI = new BasicRootPaneUI();
public static ComponentUI createUI(JComponent c) {
return rootPaneUI;
}
public void installUI(JComponent c) {
installDefaults((JRootPane)c);
installComponents((JRootPane)c);
installListeners((JRootPane)c);
installKeyboardActions((JRootPane)c);
}
public void uninstallUI(JComponent c) {
uninstallDefaults((JRootPane)c);
uninstallComponents((JRootPane)c);
uninstallListeners((JRootPane)c);
uninstallKeyboardActions((JRootPane)c);
}
protected void installDefaults(JRootPane c){
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
}
protected void installComponents(JRootPane root) {
}
protected void installListeners(JRootPane root) {
root.addPropertyChangeListener(this);
}
protected void installKeyboardActions(JRootPane root) {
InputMap km = getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW, root);
SwingUtilities.replaceUIInputMap(root,
JComponent.WHEN_IN_FOCUSED_WINDOW, km);
km = getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,
root);
SwingUtilities.replaceUIInputMap(root,
JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT, km);
LazyActionMap.installLazyActionMap(root, BasicRootPaneUI.class,
"RootPane.actionMap");
updateDefaultButtonBindings(root);
}
protected void uninstallDefaults(JRootPane root) {
}
protected void uninstallComponents(JRootPane root) {
}
protected void uninstallListeners(JRootPane root) {
root.removePropertyChangeListener(this);
}
protected void uninstallKeyboardActions(JRootPane root) {
SwingUtilities.replaceUIInputMap(root, JComponent.
WHEN_IN_FOCUSED_WINDOW, null);
SwingUtilities.replaceUIActionMap(root, null);
}
InputMap getInputMap(int condition, JComponent c) {
if (condition == JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT) {
return (InputMap)DefaultLookup.get(c, this,
"RootPane.ancestorInputMap");
}
if (condition == JComponent.WHEN_IN_FOCUSED_WINDOW) {
return createInputMap(condition, c);
}
return null;
}
ComponentInputMap createInputMap(int condition, JComponent c) {
return new RootPaneInputMap(c);
}
static void loadActionMap(LazyActionMap map) {
map.put(new Actions(Actions.PRESS));
map.put(new Actions(Actions.RELEASE));
map.put(new Actions(Actions.POST_POPUP));
}
/**
* Invoked when the default button property has changed. This reloads
* the bindings from the defaults table with name
* <code>RootPane.defaultButtonWindowKeyBindings</code>.
*/
void updateDefaultButtonBindings(JRootPane root) {
InputMap km = SwingUtilities.getUIInputMap(root, JComponent.
WHEN_IN_FOCUSED_WINDOW);
while (km != null && !(km instanceof RootPaneInputMap)) {
km = km.getParent();
}
if (km != null) {
km.clear();
if (root.getDefaultButton() != null) {
Object[] bindings = (Object[])DefaultLookup.get(root, this,
"RootPane.defaultButtonWindowKeyBindings");
if (bindings != null) {
LookAndFeel.loadKeyBindings(km, bindings);
}
}
}
}
/**
* Invoked when a property changes on the root pane. If the event
* indicates the <code>defaultButton</code> has changed, this will
* reinstall the keyboard actions.
*/
public void propertyChange(PropertyChangeEvent e) {
if(e.getPropertyName().equals("defaultButton")) {
JRootPane rootpane = (JRootPane)e.getSource();
updateDefaultButtonBindings(rootpane);
if (rootpane.getClientProperty("temporaryDefaultButton") == null) {
rootpane.putClientProperty("initialDefaultButton", e.getNewValue());
}
}
}
static class Actions extends UIAction {
public static final String PRESS = "press";
public static final String RELEASE = "release";
public static final String POST_POPUP = "postPopup";
Actions(String name) {
super(name);
}
public void actionPerformed(ActionEvent evt) {
JRootPane root = (JRootPane)evt.getSource();
JButton owner = root.getDefaultButton();
String key = getName();
if (key == POST_POPUP) { // Action to post popup
Component c = KeyboardFocusManager
.getCurrentKeyboardFocusManager()
.getFocusOwner();
if(c instanceof JComponent) {
JComponent src = (JComponent) c;
JPopupMenu jpm = src.getComponentPopupMenu();
if(jpm != null) {
Point pt = src.getPopupLocation(null);
if(pt == null) {
Rectangle vis = src.getVisibleRect();
pt = new Point(vis.x+vis.width/2,
vis.y+vis.height/2);
}
jpm.show(c, pt.x, pt.y);
}
}
}
else if (owner != null
&& SwingUtilities.getRootPane(owner) == root) {
if (key == PRESS) {
owner.doClick(20);
}
}
}
public boolean isEnabled(Object sender) {
String key = getName();
if(key == POST_POPUP) {
MenuElement[] elems = MenuSelectionManager
.defaultManager()
.getSelectedPath();
if(elems != null && elems.length != 0) {
return false;
// We shall not interfere with already opened menu
}
Component c = KeyboardFocusManager
.getCurrentKeyboardFocusManager()
.getFocusOwner();
if(c instanceof JComponent) {
JComponent src = (JComponent) c;
return src.getComponentPopupMenu() != null;
}
return false;
}
if (sender != null && sender instanceof JRootPane) {
JButton owner = ((JRootPane)sender).getDefaultButton();
return (owner != null && owner.getModel().isEnabled());
}
return true;
}
}
private static class RootPaneInputMap extends ComponentInputMapUIResource {
public RootPaneInputMap(JComponent c) {
super(c);
}
}
}