mirror of
https://github.com/openjdk/jdk.git
synced 2026-07-23 17:40:35 +00:00
297 lines
9.7 KiB
Java
297 lines
9.7 KiB
Java
/*
|
|
* Copyright (c) 1999, 2016, 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();
|
|
|
|
/**
|
|
* Returns a new instance of {@code BasicRootPaneUI}.
|
|
*
|
|
* @param c a component
|
|
* @return a new instance of {@code 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);
|
|
}
|
|
|
|
/**
|
|
* Installs default properties.
|
|
*
|
|
* @param c an instance of {@code JRootPane}
|
|
*/
|
|
protected void installDefaults(JRootPane c){
|
|
LookAndFeel.installProperty(c, "opaque", Boolean.FALSE);
|
|
}
|
|
|
|
/**
|
|
* Installs components.
|
|
*
|
|
* @param root an instance of {@code JRootPane}
|
|
*/
|
|
protected void installComponents(JRootPane root) {
|
|
}
|
|
|
|
/**
|
|
* Registers listeners.
|
|
*
|
|
* @param root an instance of {@code JRootPane}
|
|
*/
|
|
protected void installListeners(JRootPane root) {
|
|
root.addPropertyChangeListener(this);
|
|
}
|
|
|
|
/**
|
|
* Registers keyboard actions.
|
|
*
|
|
* @param root an instance of {@code JRootPane}
|
|
*/
|
|
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);
|
|
}
|
|
|
|
/**
|
|
* Uninstalls default properties.
|
|
*
|
|
* @param root an instance of {@code JRootPane}
|
|
*/
|
|
protected void uninstallDefaults(JRootPane root) {
|
|
}
|
|
|
|
/**
|
|
* Unregisters components.
|
|
*
|
|
* @param root an instance of {@code JRootPane}
|
|
*/
|
|
protected void uninstallComponents(JRootPane root) {
|
|
}
|
|
|
|
/**
|
|
* Unregisters listeners.
|
|
*
|
|
* @param root an instance of {@code JRootPane}
|
|
*/
|
|
protected void uninstallListeners(JRootPane root) {
|
|
root.removePropertyChangeListener(this);
|
|
}
|
|
|
|
/**
|
|
* Unregisters keyboard actions.
|
|
*
|
|
* @param root an instance of {@code JRootPane}
|
|
*/
|
|
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);
|
|
}
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public boolean accept(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 instanceof JRootPane) {
|
|
JButton owner = ((JRootPane)sender).getDefaultButton();
|
|
return (owner != null && owner.getModel().isEnabled() && owner.isShowing());
|
|
}
|
|
return true;
|
|
}
|
|
}
|
|
|
|
@SuppressWarnings("serial") // JDK-implementation class
|
|
private static class RootPaneInputMap extends ComponentInputMapUIResource {
|
|
public RootPaneInputMap(JComponent c) {
|
|
super(c);
|
|
}
|
|
}
|
|
}
|