feat(jdk8): move files to new folder to avoid resources compiled.

This commit is contained in:
2025-09-07 15:25:52 +08:00
parent 3f0047bf6f
commit 8c35cfb1c0
17415 changed files with 217 additions and 213 deletions

View File

@@ -0,0 +1,319 @@
/*
* Copyright (c) 1997, 2011, 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 sun.awt.im;
import java.awt.AWTEvent;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.awt.font.FontRenderContext;
import java.awt.font.TextHitInfo;
import java.awt.font.TextLayout;
import java.awt.geom.Rectangle2D;
import java.awt.im.InputMethodRequests;
import java.text.AttributedCharacterIterator;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.LineBorder;
/**
* A composition area is used to display text that's being composed
* using an input method in its own user interface environment,
* typically in a root window.
*
* @author JavaSoft International
*/
// This class is final due to the 6607310 fix. Refer to the CR for details.
public final class CompositionArea extends JPanel implements InputMethodListener {
private CompositionAreaHandler handler;
private TextLayout composedTextLayout;
private TextHitInfo caret = null;
private JFrame compositionWindow;
private final static int TEXT_ORIGIN_X = 5;
private final static int TEXT_ORIGIN_Y = 15;
private final static int PASSIVE_WIDTH = 480;
private final static int WIDTH_MARGIN=10;
private final static int HEIGHT_MARGIN=3;
CompositionArea() {
// create composition window with localized title
String windowTitle = Toolkit.getProperty("AWT.CompositionWindowTitle", "Input Window");
compositionWindow =
(JFrame)InputMethodContext.createInputMethodWindow(windowTitle, null, true);
setOpaque(true);
setBorder(LineBorder.createGrayLineBorder());
setForeground(Color.black);
setBackground(Color.white);
// if we get the focus, we still want to let the client's
// input context handle the event
enableInputMethods(true);
enableEvents(AWTEvent.KEY_EVENT_MASK);
compositionWindow.getContentPane().add(this);
compositionWindow.addWindowListener(new FrameWindowAdapter());
addInputMethodListener(this);
compositionWindow.enableInputMethods(false);
compositionWindow.pack();
Dimension windowSize = compositionWindow.getSize();
Dimension screenSize = (getToolkit()).getScreenSize();
compositionWindow.setLocation(screenSize.width - windowSize.width-20,
screenSize.height - windowSize.height-100);
compositionWindow.setVisible(false);
}
/**
* Sets the composition area handler that currently owns this
* composition area, and its input context.
*/
synchronized void setHandlerInfo(CompositionAreaHandler handler, InputContext inputContext) {
this.handler = handler;
((InputMethodWindow) compositionWindow).setInputContext(inputContext);
}
/**
* @see java.awt.Component#getInputMethodRequests
*/
public InputMethodRequests getInputMethodRequests() {
return handler;
}
// returns a 0-width rectangle
private Rectangle getCaretRectangle(TextHitInfo caret) {
int caretLocation = 0;
TextLayout layout = composedTextLayout;
if (layout != null) {
caretLocation = Math.round(layout.getCaretInfo(caret)[0]);
}
Graphics g = getGraphics();
FontMetrics metrics = null;
try {
metrics = g.getFontMetrics();
} finally {
g.dispose();
}
return new Rectangle(TEXT_ORIGIN_X + caretLocation,
TEXT_ORIGIN_Y - metrics.getAscent(),
0, metrics.getAscent() + metrics.getDescent());
}
public void paint(Graphics g) {
super.paint(g);
g.setColor(getForeground());
TextLayout layout = composedTextLayout;
if (layout != null) {
layout.draw((Graphics2D) g, TEXT_ORIGIN_X, TEXT_ORIGIN_Y);
}
if (caret != null) {
Rectangle rectangle = getCaretRectangle(caret);
g.setXORMode(getBackground());
g.fillRect(rectangle.x, rectangle.y, 1, rectangle.height);
g.setPaintMode();
}
}
// shows/hides the composition window
void setCompositionAreaVisible(boolean visible) {
compositionWindow.setVisible(visible);
}
// returns true if composition area is visible
boolean isCompositionAreaVisible() {
return compositionWindow.isVisible();
}
// workaround for the Solaris focus lost problem
class FrameWindowAdapter extends WindowAdapter {
public void windowActivated(WindowEvent e) {
requestFocus();
}
}
// InputMethodListener methods - just forward to the current handler
public void inputMethodTextChanged(InputMethodEvent event) {
handler.inputMethodTextChanged(event);
}
public void caretPositionChanged(InputMethodEvent event) {
handler.caretPositionChanged(event);
}
/**
* Sets the text and caret to be displayed in this composition area.
* Shows the window if it contains text, hides it if not.
*/
void setText(AttributedCharacterIterator composedText, TextHitInfo caret) {
composedTextLayout = null;
if (composedText == null) {
// there's no composed text to display, so hide the window
compositionWindow.setVisible(false);
this.caret = null;
} else {
/* since we have composed text, make sure the window is shown.
This is necessary to get a valid graphics object. See 6181385.
*/
if (!compositionWindow.isVisible()) {
compositionWindow.setVisible(true);
}
Graphics g = getGraphics();
if (g == null) {
return;
}
try {
updateWindowLocation();
FontRenderContext context = ((Graphics2D)g).getFontRenderContext();
composedTextLayout = new TextLayout(composedText, context);
Rectangle2D bounds = composedTextLayout.getBounds();
this.caret = caret;
// Resize the composition area to just fit the text.
FontMetrics metrics = g.getFontMetrics();
Rectangle2D maxCharBoundsRec = metrics.getMaxCharBounds(g);
int newHeight = (int)maxCharBoundsRec.getHeight() + HEIGHT_MARGIN;
int newFrameHeight = newHeight +compositionWindow.getInsets().top
+compositionWindow.getInsets().bottom;
// If it's a passive client, set the width always to PASSIVE_WIDTH (480px)
InputMethodRequests req = handler.getClientInputMethodRequests();
int newWidth = (req==null) ? PASSIVE_WIDTH : (int)bounds.getWidth() + WIDTH_MARGIN;
int newFrameWidth = newWidth + compositionWindow.getInsets().left
+ compositionWindow.getInsets().right;
setPreferredSize(new Dimension(newWidth, newHeight));
compositionWindow.setSize(new Dimension(newFrameWidth, newFrameHeight));
// show the composed text
paint(g);
}
finally {
g.dispose();
}
}
}
/**
* Sets the caret to be displayed in this composition area.
* The text is not changed.
*/
void setCaret(TextHitInfo caret) {
this.caret = caret;
if (compositionWindow.isVisible()) {
Graphics g = getGraphics();
try {
paint(g);
} finally {
g.dispose();
}
}
}
/**
* Positions the composition window near (usually below) the
* insertion point in the client component if the client
* component is an active client (below-the-spot input).
*/
void updateWindowLocation() {
InputMethodRequests req = handler.getClientInputMethodRequests();
if (req == null) {
// not an active client
return;
}
Point windowLocation = new Point();
Rectangle caretRect = req.getTextLocation(null);
Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
Dimension windowSize = compositionWindow.getSize();
final int SPACING = 2;
if (caretRect.x + windowSize.width > screenSize.width) {
windowLocation.x = screenSize.width - windowSize.width;
} else {
windowLocation.x = caretRect.x;
}
if (caretRect.y + caretRect.height + SPACING + windowSize.height > screenSize.height) {
windowLocation.y = caretRect.y - SPACING - windowSize.height;
} else {
windowLocation.y = caretRect.y + caretRect.height + SPACING;
}
compositionWindow.setLocation(windowLocation);
}
// support for InputMethodRequests methods
Rectangle getTextLocation(TextHitInfo offset) {
Rectangle rectangle = getCaretRectangle(offset);
Point location = getLocationOnScreen();
rectangle.translate(location.x, location.y);
return rectangle;
}
TextHitInfo getLocationOffset(int x, int y) {
TextLayout layout = composedTextLayout;
if (layout == null) {
return null;
} else {
Point location = getLocationOnScreen();
x -= location.x + TEXT_ORIGIN_X;
y -= location.y + TEXT_ORIGIN_Y;
if (layout.getBounds().contains(x, y)) {
return layout.hitTestChar(x, y);
} else {
return null;
}
}
}
// Disables or enables decorations of the composition window
void setCompositionAreaUndecorated(boolean setUndecorated){
if (compositionWindow.isDisplayable()){
compositionWindow.removeNotify();
}
compositionWindow.setUndecorated(setUndecorated);
compositionWindow.pack();
}
// Proclaim serial compatibility with 1.7.0
private static final long serialVersionUID = -1057247068746557444L;
}

View File

@@ -0,0 +1,354 @@
/*
* Copyright (c) 1999, 2013, 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 sun.awt.im;
import java.awt.Component;
import java.awt.Container;
import java.awt.Rectangle;
import java.awt.event.InputMethodEvent;
import java.awt.event.InputMethodListener;
import java.awt.font.TextAttribute;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;
import java.lang.ref.WeakReference;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.text.AttributedString;
/**
* A composition area handler handles events and input method requests for
* the composition area. Typically each input method context has its own
* composition area handler if it supports passive clients or below-the-spot
* input, but all handlers share a single composition area.
*
* @author JavaSoft International
*/
class CompositionAreaHandler implements InputMethodListener,
InputMethodRequests {
private static CompositionArea compositionArea;
private static Object compositionAreaLock = new Object();
private static CompositionAreaHandler compositionAreaOwner; // synchronized through compositionArea
private AttributedCharacterIterator composedText;
private TextHitInfo caret = null;
private WeakReference<Component> clientComponent = new WeakReference<>(null);
private InputMethodContext inputMethodContext;
/**
* Constructs the composition area handler.
*/
CompositionAreaHandler(InputMethodContext context) {
inputMethodContext = context;
}
/**
* Creates the composition area.
*/
private void createCompositionArea() {
synchronized(compositionAreaLock) {
compositionArea = new CompositionArea();
if (compositionAreaOwner != null) {
compositionArea.setHandlerInfo(compositionAreaOwner, inputMethodContext);
}
// If the client component is an active client using below-the-spot style, then
// make the composition window undecorated without a title bar.
Component client = clientComponent.get();
if(client != null){
InputMethodRequests req = client.getInputMethodRequests();
if (req != null && inputMethodContext.useBelowTheSpotInput()) {
setCompositionAreaUndecorated(true);
}
}
}
}
void setClientComponent(Component clientComponent) {
this.clientComponent = new WeakReference<>(clientComponent);
}
/**
* Grabs the composition area, makes this handler its owner, and installs
* the handler and its input context into the composition area for event
* and input method request handling.
* If doUpdate is true, updates the composition area with previously sent
* composed text.
*/
void grabCompositionArea(boolean doUpdate) {
synchronized (compositionAreaLock) {
if (compositionAreaOwner != this) {
compositionAreaOwner = this;
if (compositionArea != null) {
compositionArea.setHandlerInfo(this, inputMethodContext);
}
if (doUpdate) {
// Create the composition area if necessary
if ((composedText != null) && (compositionArea == null)) {
createCompositionArea();
}
if (compositionArea != null) {
compositionArea.setText(composedText, caret);
}
}
}
}
}
/**
* Releases and closes the composition area if it is currently owned by
* this composition area handler.
*/
void releaseCompositionArea() {
synchronized (compositionAreaLock) {
if (compositionAreaOwner == this) {
compositionAreaOwner = null;
if (compositionArea != null) {
compositionArea.setHandlerInfo(null, null);
compositionArea.setText(null, null);
}
}
}
}
/**
* Releases and closes the composition area if it has been created,
* independent of the current owner.
*/
static void closeCompositionArea() {
if (compositionArea != null) {
synchronized (compositionAreaLock) {
compositionAreaOwner = null;
compositionArea.setHandlerInfo(null, null);
compositionArea.setText(null, null);
}
}
}
/**
* Returns whether the composition area is currently visible
*/
boolean isCompositionAreaVisible() {
if (compositionArea != null) {
return compositionArea.isCompositionAreaVisible();
}
return false;
}
/**
* Shows or hides the composition Area
*/
void setCompositionAreaVisible(boolean visible) {
if (compositionArea != null) {
compositionArea.setCompositionAreaVisible(visible);
}
}
void processInputMethodEvent(InputMethodEvent event) {
if (event.getID() == InputMethodEvent.INPUT_METHOD_TEXT_CHANGED) {
inputMethodTextChanged(event);
} else {
caretPositionChanged(event);
}
}
/**
* set the compositionArea frame decoration
*/
void setCompositionAreaUndecorated(boolean undecorated) {
if (compositionArea != null) {
compositionArea.setCompositionAreaUndecorated(undecorated);
}
}
//
// InputMethodListener methods
//
private static final Attribute[] IM_ATTRIBUTES =
{ TextAttribute.INPUT_METHOD_HIGHLIGHT };
public void inputMethodTextChanged(InputMethodEvent event) {
AttributedCharacterIterator text = event.getText();
int committedCharacterCount = event.getCommittedCharacterCount();
// extract composed text and prepare it for display
composedText = null;
caret = null;
if (text != null
&& committedCharacterCount < text.getEndIndex() - text.getBeginIndex()) {
// Create the composition area if necessary
if (compositionArea == null) {
createCompositionArea();
}
// copy the composed text
AttributedString composedTextString;
composedTextString = new AttributedString(text,
text.getBeginIndex() + committedCharacterCount, // skip over committed text
text.getEndIndex(), IM_ATTRIBUTES);
composedTextString.addAttribute(TextAttribute.FONT, compositionArea.getFont());
composedText = composedTextString.getIterator();
caret = event.getCaret();
}
if (compositionArea != null) {
compositionArea.setText(composedText, caret);
}
// send any committed text to the text component
if (committedCharacterCount > 0) {
inputMethodContext.dispatchCommittedText(((Component) event.getSource()),
text, committedCharacterCount);
// this may have changed the text location, so reposition the window
if (isCompositionAreaVisible()) {
compositionArea.updateWindowLocation();
}
}
// event has been handled, so consume it
event.consume();
}
public void caretPositionChanged(InputMethodEvent event) {
if (compositionArea != null) {
compositionArea.setCaret(event.getCaret());
}
// event has been handled, so consume it
event.consume();
}
//
// InputMethodRequests methods
//
/**
* Returns the input method request handler of the client component.
* When using the composition window for an active client (below-the-spot
* input), input method requests that do not relate to the display of
* the composed text are forwarded to the client component.
*/
InputMethodRequests getClientInputMethodRequests() {
Component client = clientComponent.get();
if (client != null) {
return client.getInputMethodRequests();
}
return null;
}
public Rectangle getTextLocation(TextHitInfo offset) {
synchronized (compositionAreaLock) {
if (compositionAreaOwner == this && isCompositionAreaVisible()) {
return compositionArea.getTextLocation(offset);
} else if (composedText != null) {
// there's composed text, but it's not displayed, so fake a rectangle
return new Rectangle(0, 0, 0, 10);
} else {
InputMethodRequests requests = getClientInputMethodRequests();
if (requests != null) {
return requests.getTextLocation(offset);
} else {
// passive client, no composed text, so fake a rectangle
return new Rectangle(0, 0, 0, 10);
}
}
}
}
public TextHitInfo getLocationOffset(int x, int y) {
synchronized (compositionAreaLock) {
if (compositionAreaOwner == this && isCompositionAreaVisible()) {
return compositionArea.getLocationOffset(x, y);
} else {
return null;
}
}
}
public int getInsertPositionOffset() {
InputMethodRequests req = getClientInputMethodRequests();
if (req != null) {
return req.getInsertPositionOffset();
}
// we don't have access to the client component's text.
return 0;
}
private static final AttributedCharacterIterator EMPTY_TEXT =
(new AttributedString("")).getIterator();
public AttributedCharacterIterator getCommittedText(int beginIndex,
int endIndex,
Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.getCommittedText(beginIndex, endIndex, attributes);
}
// we don't have access to the client component's text.
return EMPTY_TEXT;
}
public int getCommittedTextLength() {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.getCommittedTextLength();
}
// we don't have access to the client component's text.
return 0;
}
public AttributedCharacterIterator cancelLatestCommittedText(Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.cancelLatestCommittedText(attributes);
}
// we don't have access to the client component's text.
return null;
}
public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
InputMethodRequests req = getClientInputMethodRequests();
if(req != null) {
return req.getSelectedText(attributes);
}
// we don't have access to the client component's text.
return EMPTY_TEXT;
}
}

View File

@@ -0,0 +1,632 @@
/*
* Copyright (c) 1998, 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 sun.awt.im;
import java.awt.AWTException;
import java.awt.CheckboxMenuItem;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.PopupMenu;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.Toolkit;
import sun.awt.AppContext;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InvocationEvent;
import java.awt.im.spi.InputMethodDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.ServiceLoader;
import java.util.Vector;
import java.util.Set;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import sun.awt.InputMethodSupport;
import sun.awt.SunToolkit;
/**
* <code>ExecutableInputMethodManager</code> is the implementation of the
* <code>InputMethodManager</code> class. It is runnable as a separate
* thread in the AWT environment.&nbsp;
* <code>InputMethodManager.getInstance()</code> creates an instance of
* <code>ExecutableInputMethodManager</code> and executes it as a deamon
* thread.
*
* @see InputMethodManager
*/
class ExecutableInputMethodManager extends InputMethodManager
implements Runnable
{
// the input context that's informed about selections from the user interface
private InputContext currentInputContext;
// Menu item string for the trigger menu.
private String triggerMenuString;
// popup menu for selecting an input method
private InputMethodPopupMenu selectionMenu;
private static String selectInputMethodMenuTitle;
// locator and name of host adapter
private InputMethodLocator hostAdapterLocator;
// locators for Java input methods
private int javaInputMethodCount; // number of Java input methods found
private Vector<InputMethodLocator> javaInputMethodLocatorList;
// component that is requesting input method switch
// must be Frame or Dialog
private Component requestComponent;
// input context that is requesting input method switch
private InputContext requestInputContext;
// IM preference stuff
private static final String preferredIMNode = "/sun/awt/im/preferredInputMethod";
private static final String descriptorKey = "descriptor";
private Hashtable<String, InputMethodLocator> preferredLocatorCache = new Hashtable<>();
private Preferences userRoot;
ExecutableInputMethodManager() {
// set up host adapter locator
Toolkit toolkit = Toolkit.getDefaultToolkit();
try {
if (toolkit instanceof InputMethodSupport) {
InputMethodDescriptor hostAdapterDescriptor =
((InputMethodSupport)toolkit)
.getInputMethodAdapterDescriptor();
if (hostAdapterDescriptor != null) {
hostAdapterLocator = new InputMethodLocator(hostAdapterDescriptor, null, null);
}
}
} catch (AWTException e) {
// if we can't get a descriptor, we'll just have to do without native input methods
}
javaInputMethodLocatorList = new Vector<InputMethodLocator>();
initializeInputMethodLocatorList();
}
synchronized void initialize() {
selectInputMethodMenuTitle = Toolkit.getProperty("AWT.InputMethodSelectionMenu", "Select Input Method");
triggerMenuString = selectInputMethodMenuTitle;
}
public void run() {
// If there are no multiple input methods to choose from, wait forever
while (!hasMultipleInputMethods()) {
try {
synchronized (this) {
wait();
}
} catch (InterruptedException e) {
}
}
// Loop for processing input method change requests
while (true) {
waitForChangeRequest();
initializeInputMethodLocatorList();
try {
if (requestComponent != null) {
showInputMethodMenuOnRequesterEDT(requestComponent);
} else {
// show the popup menu within the event thread
EventQueue.invokeAndWait(new Runnable() {
public void run() {
showInputMethodMenu();
}
});
}
} catch (InterruptedException ie) {
} catch (InvocationTargetException ite) {
// should we do anything under these exceptions?
}
}
}
// Shows Input Method Menu on the EDT of requester component
// to avoid side effects. See 6544309.
private void showInputMethodMenuOnRequesterEDT(Component requester)
throws InterruptedException, InvocationTargetException {
if (requester == null){
return;
}
class AWTInvocationLock {}
Object lock = new AWTInvocationLock();
InvocationEvent event =
new InvocationEvent(requester,
new Runnable() {
public void run() {
showInputMethodMenu();
}
},
lock,
true);
AppContext requesterAppContext = SunToolkit.targetToAppContext(requester);
synchronized (lock) {
SunToolkit.postEvent(requesterAppContext, event);
while (!event.isDispatched()) {
lock.wait();
}
}
Throwable eventThrowable = event.getThrowable();
if (eventThrowable != null) {
throw new InvocationTargetException(eventThrowable);
}
}
void setInputContext(InputContext inputContext) {
if (currentInputContext != null && inputContext != null) {
// don't throw this exception until 4237852 is fixed
// throw new IllegalStateException("Can't have two active InputContext at the same time");
}
currentInputContext = inputContext;
}
public synchronized void notifyChangeRequest(Component comp) {
if (!(comp instanceof Frame || comp instanceof Dialog))
return;
// if busy with the current request, ignore this request.
if (requestComponent != null)
return;
requestComponent = comp;
notify();
}
public synchronized void notifyChangeRequestByHotKey(Component comp) {
while (!(comp instanceof Frame || comp instanceof Dialog)) {
if (comp == null) {
// no Frame or Dialog found in containment hierarchy.
return;
}
comp = comp.getParent();
}
notifyChangeRequest(comp);
}
public String getTriggerMenuString() {
return triggerMenuString;
}
/*
* Returns true if the environment indicates there are multiple input methods
*/
boolean hasMultipleInputMethods() {
return ((hostAdapterLocator != null) && (javaInputMethodCount > 0)
|| (javaInputMethodCount > 1));
}
private synchronized void waitForChangeRequest() {
try {
while (requestComponent == null) {
wait();
}
} catch (InterruptedException e) {
}
}
/*
* initializes the input method locator list for all
* installed input method descriptors.
*/
private void initializeInputMethodLocatorList() {
synchronized (javaInputMethodLocatorList) {
javaInputMethodLocatorList.clear();
try {
AccessController.doPrivileged(new PrivilegedExceptionAction<Object>() {
public Object run() {
for (InputMethodDescriptor descriptor :
ServiceLoader.loadInstalled(InputMethodDescriptor.class)) {
ClassLoader cl = descriptor.getClass().getClassLoader();
javaInputMethodLocatorList.add(new InputMethodLocator(descriptor, cl, null));
}
return null;
}
});
} catch (PrivilegedActionException e) {
e.printStackTrace();
}
javaInputMethodCount = javaInputMethodLocatorList.size();
}
if (hasMultipleInputMethods()) {
// initialize preferences
if (userRoot == null) {
userRoot = getUserRoot();
}
} else {
// indicate to clients not to offer the menu
triggerMenuString = null;
}
}
private void showInputMethodMenu() {
if (!hasMultipleInputMethods()) {
requestComponent = null;
return;
}
// initialize pop-up menu
selectionMenu = InputMethodPopupMenu.getInstance(requestComponent, selectInputMethodMenuTitle);
// we have to rebuild the menu each time because
// some input methods (such as IIIMP) may change
// their list of supported locales dynamically
selectionMenu.removeAll();
// get information about the currently selected input method
// ??? if there's no current input context, what's the point
// of showing the menu?
String currentSelection = getCurrentSelection();
// Add menu item for host adapter
if (hostAdapterLocator != null) {
selectionMenu.addOneInputMethodToMenu(hostAdapterLocator, currentSelection);
selectionMenu.addSeparator();
}
// Add menu items for other input methods
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
selectionMenu.addOneInputMethodToMenu(locator, currentSelection);
}
synchronized (this) {
selectionMenu.addToComponent(requestComponent);
requestInputContext = currentInputContext;
selectionMenu.show(requestComponent, 60, 80); // TODO: get proper x, y...
requestComponent = null;
}
}
private String getCurrentSelection() {
InputContext inputContext = currentInputContext;
if (inputContext != null) {
InputMethodLocator locator = inputContext.getInputMethodLocator();
if (locator != null) {
return locator.getActionCommandString();
}
}
return null;
}
synchronized void changeInputMethod(String choice) {
InputMethodLocator locator = null;
String inputMethodName = choice;
String localeString = null;
int index = choice.indexOf('\n');
if (index != -1) {
localeString = choice.substring(index + 1);
inputMethodName = choice.substring(0, index);
}
if (hostAdapterLocator.getActionCommandString().equals(inputMethodName)) {
locator = hostAdapterLocator;
} else {
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
String name = candidate.getActionCommandString();
if (name.equals(inputMethodName)) {
locator = candidate;
break;
}
}
}
if (locator != null && localeString != null) {
String language = "", country = "", variant = "";
int postIndex = localeString.indexOf('_');
if (postIndex == -1) {
language = localeString;
} else {
language = localeString.substring(0, postIndex);
int preIndex = postIndex + 1;
postIndex = localeString.indexOf('_', preIndex);
if (postIndex == -1) {
country = localeString.substring(preIndex);
} else {
country = localeString.substring(preIndex, postIndex);
variant = localeString.substring(postIndex + 1);
}
}
Locale locale = new Locale(language, country, variant);
locator = locator.deriveLocator(locale);
}
if (locator == null)
return;
// tell the input context about the change
if (requestInputContext != null) {
requestInputContext.changeInputMethod(locator);
requestInputContext = null;
// remember the selection
putPreferredInputMethod(locator);
}
}
InputMethodLocator findInputMethod(Locale locale) {
// look for preferred input method first
InputMethodLocator locator = getPreferredInputMethod(locale);
if (locator != null) {
return locator;
}
if (hostAdapterLocator != null && hostAdapterLocator.isLocaleAvailable(locale)) {
return hostAdapterLocator.deriveLocator(locale);
}
// Update the locator list
initializeInputMethodLocatorList();
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator candidate = javaInputMethodLocatorList.get(i);
if (candidate.isLocaleAvailable(locale)) {
return candidate.deriveLocator(locale);
}
}
return null;
}
Locale getDefaultKeyboardLocale() {
Toolkit toolkit = Toolkit.getDefaultToolkit();
if (toolkit instanceof InputMethodSupport) {
return ((InputMethodSupport)toolkit).getDefaultKeyboardLocale();
} else {
return Locale.getDefault();
}
}
/**
* Returns a InputMethodLocator object that the
* user prefers for the given locale.
*
* @param locale Locale for which the user prefers the input method.
*/
private synchronized InputMethodLocator getPreferredInputMethod(Locale locale) {
InputMethodLocator preferredLocator = null;
if (!hasMultipleInputMethods()) {
// No need to look for a preferred Java input method
return null;
}
// look for the cached preference first.
preferredLocator = preferredLocatorCache.get(locale.toString().intern());
if (preferredLocator != null) {
return preferredLocator;
}
// look for the preference in the user preference tree
String nodePath = findPreferredInputMethodNode(locale);
String descriptorName = readPreferredInputMethod(nodePath);
Locale advertised;
// get the locator object
if (descriptorName != null) {
// check for the host adapter first
if (hostAdapterLocator != null &&
hostAdapterLocator.getDescriptor().getClass().getName().equals(descriptorName)) {
advertised = getAdvertisedLocale(hostAdapterLocator, locale);
if (advertised != null) {
preferredLocator = hostAdapterLocator.deriveLocator(advertised);
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
}
return preferredLocator;
}
// look for Java input methods
for (int i = 0; i < javaInputMethodLocatorList.size(); i++) {
InputMethodLocator locator = javaInputMethodLocatorList.get(i);
InputMethodDescriptor descriptor = locator.getDescriptor();
if (descriptor.getClass().getName().equals(descriptorName)) {
advertised = getAdvertisedLocale(locator, locale);
if (advertised != null) {
preferredLocator = locator.deriveLocator(advertised);
preferredLocatorCache.put(locale.toString().intern(), preferredLocator);
}
return preferredLocator;
}
}
// maybe preferred input method information is bogus.
writePreferredInputMethod(nodePath, null);
}
return null;
}
private String findPreferredInputMethodNode(Locale locale) {
if (userRoot == null) {
return null;
}
// create locale node relative path
String nodePath = preferredIMNode + "/" + createLocalePath(locale);
// look for the descriptor
while (!nodePath.equals(preferredIMNode)) {
try {
if (userRoot.nodeExists(nodePath)) {
if (readPreferredInputMethod(nodePath) != null) {
return nodePath;
}
}
} catch (BackingStoreException bse) {
}
// search at parent's node
nodePath = nodePath.substring(0, nodePath.lastIndexOf('/'));
}
return null;
}
private String readPreferredInputMethod(String nodePath) {
if ((userRoot == null) || (nodePath == null)) {
return null;
}
return userRoot.node(nodePath).get(descriptorKey, null);
}
/**
* Writes the preferred input method descriptor class name into
* the user's Preferences tree in accordance with the given locale.
*
* @param inputMethodLocator input method locator to remember.
*/
private synchronized void putPreferredInputMethod(InputMethodLocator locator) {
InputMethodDescriptor descriptor = locator.getDescriptor();
Locale preferredLocale = locator.getLocale();
if (preferredLocale == null) {
// check available locales of the input method
try {
Locale[] availableLocales = descriptor.getAvailableLocales();
if (availableLocales.length == 1) {
preferredLocale = availableLocales[0];
} else {
// there is no way to know which locale is the preferred one, so do nothing.
return;
}
} catch (AWTException ae) {
// do nothing here, either.
return;
}
}
// for regions that have only one language, we need to regard
// "xx_YY" as "xx" when putting the preference into tree
if (preferredLocale.equals(Locale.JAPAN)) {
preferredLocale = Locale.JAPANESE;
}
if (preferredLocale.equals(Locale.KOREA)) {
preferredLocale = Locale.KOREAN;
}
if (preferredLocale.equals(new Locale("th", "TH"))) {
preferredLocale = new Locale("th");
}
// obtain node
String path = preferredIMNode + "/" + createLocalePath(preferredLocale);
// write in the preference tree
writePreferredInputMethod(path, descriptor.getClass().getName());
preferredLocatorCache.put(preferredLocale.toString().intern(),
locator.deriveLocator(preferredLocale));
return;
}
private String createLocalePath(Locale locale) {
String language = locale.getLanguage();
String country = locale.getCountry();
String variant = locale.getVariant();
String localePath = null;
if (!variant.equals("")) {
localePath = "_" + language + "/_" + country + "/_" + variant;
} else if (!country.equals("")) {
localePath = "_" + language + "/_" + country;
} else {
localePath = "_" + language;
}
return localePath;
}
private void writePreferredInputMethod(String path, String descriptorName) {
if (userRoot != null) {
Preferences node = userRoot.node(path);
// record it
if (descriptorName != null) {
node.put(descriptorKey, descriptorName);
} else {
node.remove(descriptorKey);
}
}
}
private Preferences getUserRoot() {
return AccessController.doPrivileged(new PrivilegedAction<Preferences>() {
public Preferences run() {
return Preferences.userRoot();
}
});
}
private Locale getAdvertisedLocale(InputMethodLocator locator, Locale locale) {
Locale advertised = null;
if (locator.isLocaleAvailable(locale)) {
advertised = locale;
} else if (locale.getLanguage().equals("ja")) {
// for Japanese, Korean, and Thai, check whether the input method supports
// language or language_COUNTRY.
if (locator.isLocaleAvailable(Locale.JAPAN)) {
advertised = Locale.JAPAN;
} else if (locator.isLocaleAvailable(Locale.JAPANESE)) {
advertised = Locale.JAPANESE;
}
} else if (locale.getLanguage().equals("ko")) {
if (locator.isLocaleAvailable(Locale.KOREA)) {
advertised = Locale.KOREA;
} else if (locator.isLocaleAvailable(Locale.KOREAN)) {
advertised = Locale.KOREAN;
}
} else if (locale.getLanguage().equals("th")) {
if (locator.isLocaleAvailable(new Locale("th", "TH"))) {
advertised = new Locale("th", "TH");
} else if (locator.isLocaleAvailable(new Locale("th"))) {
advertised = new Locale("th");
}
}
return advertised;
}
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,117 @@
/*
* Copyright (c) 1997, 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 sun.awt.im;
import java.awt.Component;
import java.awt.Rectangle;
import java.awt.im.spi.InputMethod;
/**
* An input method adapter interfaces with the native input methods
* on a host platform. In general, it looks to the input method
* framework like a Java input method (that may support a few more
* locales than a typical Java input method). However, since it
* often has to work in a slightly hostile environment that's not
* designed for easy integration into the Java input method
* framework, it gets some special treatment that's not available
* to Java input methods.
* <p>
* Licensees are free to modify this class as necessary to implement
* their host input method adapters.
*
* @author JavaSoft International
*/
public abstract class InputMethodAdapter implements InputMethod {
private Component clientComponent;
void setClientComponent(Component client) {
clientComponent = client;
}
protected Component getClientComponent() {
return clientComponent;
}
protected boolean haveActiveClient() {
return clientComponent != null && clientComponent.getInputMethodRequests() != null;
}
/**
* Informs the input method adapter about the component that has the AWT
* focus if it's using the input context owning this adapter instance.
*/
protected void setAWTFocussedComponent(Component component) {
// ignore - adapters can override if needed
}
/**
* Returns whether host input methods can support below-the-spot input.
* Returns false by default.
*/
protected boolean supportsBelowTheSpot() {
return false;
}
/**
* Informs the input method adapter not to listen to the native events.
*/
protected void stopListening() {
// ignore - adapters can override if needed
}
/**
* Notifies client Window location or status changes
*/
public void notifyClientWindowChange(Rectangle location) {
}
/**
* Starts reconvertion. An implementing host adapter has to override
* this method if it can support reconvert().
* @exception UnsupportedOperationException when the adapter does not override
* the method.
*/
public void reconvert() {
throw new UnsupportedOperationException();
}
/**
* Disable the native input method. This method is provided for explicitly
* turning off the native IM. The native IM is not turned off
* when the native input method is deactivated. This method is
* always called on AWT EDT. See details in bug 6226489.
*/
public abstract void disableInputMethod();
/**
* Returns a string with information about the native input method, or
* null.
*/
public abstract String getNativeInputMethodInfo();
}

View File

@@ -0,0 +1,377 @@
/*
* Copyright (c) 1997, 2011, 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 sun.awt.im;
import java.awt.AWTEvent;
import java.awt.Component;
import java.awt.GraphicsEnvironment;
import java.awt.HeadlessException;
import java.awt.Rectangle;
import java.awt.Toolkit;
import java.awt.Window;
import java.awt.event.KeyEvent;
import java.awt.event.InputMethodEvent;
import java.awt.font.TextHitInfo;
import java.awt.im.InputMethodRequests;
import java.awt.im.spi.InputMethod;
import java.security.AccessController;
import java.text.AttributedCharacterIterator;
import java.text.AttributedCharacterIterator.Attribute;
import java.text.AttributedString;
import java.text.CharacterIterator;
import javax.swing.JFrame;
import sun.awt.InputMethodSupport;
import sun.security.action.GetPropertyAction;
/**
* The InputMethodContext class provides methods that input methods
* can use to communicate with their client components.
* It is a subclass of InputContext, which provides methods for use by
* components.
*
* @author JavaSoft International
*/
public class InputMethodContext
extends sun.awt.im.InputContext
implements java.awt.im.spi.InputMethodContext {
private boolean dispatchingCommittedText;
// Creation of the context's composition area handler is
// delayed until we really need a composition area.
private CompositionAreaHandler compositionAreaHandler;
private Object compositionAreaHandlerLock = new Object();
static private boolean belowTheSpotInputRequested;
private boolean inputMethodSupportsBelowTheSpot;
static {
// check whether we should use below-the-spot input
// get property from command line
String inputStyle = AccessController.doPrivileged
(new GetPropertyAction("java.awt.im.style", null));
// get property from awt.properties file
if (inputStyle == null) {
inputStyle = Toolkit.getProperty("java.awt.im.style", null);
}
belowTheSpotInputRequested = "below-the-spot".equals(inputStyle);
}
/**
* Constructs an InputMethodContext.
*/
public InputMethodContext() {
super();
}
void setInputMethodSupportsBelowTheSpot(boolean supported) {
inputMethodSupportsBelowTheSpot = supported;
}
boolean useBelowTheSpotInput() {
return belowTheSpotInputRequested && inputMethodSupportsBelowTheSpot;
}
private boolean haveActiveClient() {
Component client = getClientComponent();
return client != null
&& client.getInputMethodRequests() != null;
}
// implements java.awt.im.spi.InputMethodContext.dispatchInputMethodEvent
public void dispatchInputMethodEvent(int id,
AttributedCharacterIterator text, int committedCharacterCount,
TextHitInfo caret, TextHitInfo visiblePosition) {
// We need to record the client component as the source so
// that we have correct information if we later have to break up this
// event into key events.
Component source;
source = getClientComponent();
if (source != null) {
InputMethodEvent event = new InputMethodEvent(source,
id, text, committedCharacterCount, caret, visiblePosition);
if (haveActiveClient() && !useBelowTheSpotInput()) {
source.dispatchEvent(event);
} else {
getCompositionAreaHandler(true).processInputMethodEvent(event);
}
}
}
/**
* Dispatches committed text to a client component.
* Called by composition window.
*
* @param client The component that the text should get dispatched to.
* @param text The iterator providing access to the committed
* (and possible composed) text.
* @param committedCharacterCount The number of committed characters in the text.
*/
synchronized void dispatchCommittedText(Component client,
AttributedCharacterIterator text,
int committedCharacterCount) {
// note that the client is not always the current client component -
// some host input method adapters may dispatch input method events
// through the Java event queue, and we may have switched clients while
// the event was in the queue.
if (committedCharacterCount == 0
|| text.getEndIndex() <= text.getBeginIndex()) {
return;
}
long time = System.currentTimeMillis();
dispatchingCommittedText = true;
try {
InputMethodRequests req = client.getInputMethodRequests();
if (req != null) {
// active client -> send text as InputMethodEvent
int beginIndex = text.getBeginIndex();
AttributedCharacterIterator toBeCommitted =
(new AttributedString(text, beginIndex, beginIndex + committedCharacterCount)).getIterator();
InputMethodEvent inputEvent = new InputMethodEvent(
client,
InputMethodEvent.INPUT_METHOD_TEXT_CHANGED,
toBeCommitted,
committedCharacterCount,
null, null);
client.dispatchEvent(inputEvent);
} else {
// passive client -> send text as KeyEvents
char keyChar = text.first();
while (committedCharacterCount-- > 0 && keyChar != CharacterIterator.DONE) {
KeyEvent keyEvent = new KeyEvent(client, KeyEvent.KEY_TYPED,
time, 0, KeyEvent.VK_UNDEFINED, keyChar);
client.dispatchEvent(keyEvent);
keyChar = text.next();
}
}
} finally {
dispatchingCommittedText = false;
}
}
public void dispatchEvent(AWTEvent event) {
// some host input method adapters may dispatch input method events
// through the Java event queue. If the component that the event is
// intended for isn't an active client, or if we're using below-the-spot
// input, we need to dispatch this event
// to the input window. Note that that component is not necessarily the
// current client component, since we may have switched clients while
// the event was in the queue.
if (event instanceof InputMethodEvent) {
if (((Component) event.getSource()).getInputMethodRequests() == null
|| (useBelowTheSpotInput() && !dispatchingCommittedText)) {
getCompositionAreaHandler(true).processInputMethodEvent((InputMethodEvent) event);
}
} else {
// make sure we don't dispatch our own key events back to the input method
if (!dispatchingCommittedText) {
super.dispatchEvent(event);
}
}
}
/**
* Gets this context's composition area handler, creating it if necessary.
* If requested, it grabs the composition area for use by this context.
* The composition area's text is not updated.
*/
private CompositionAreaHandler getCompositionAreaHandler(boolean grab) {
synchronized(compositionAreaHandlerLock) {
if (compositionAreaHandler == null) {
compositionAreaHandler = new CompositionAreaHandler(this);
}
compositionAreaHandler.setClientComponent(getClientComponent());
if (grab) {
compositionAreaHandler.grabCompositionArea(false);
}
return compositionAreaHandler;
}
}
/**
* Grabs the composition area for use by this context.
* If doUpdate is true, updates the composition area with previously sent
* composed text.
*/
void grabCompositionArea(boolean doUpdate) {
synchronized(compositionAreaHandlerLock) {
if (compositionAreaHandler != null) {
compositionAreaHandler.grabCompositionArea(doUpdate);
} else {
// if this context hasn't seen a need for a composition area yet,
// just close it without creating the machinery
CompositionAreaHandler.closeCompositionArea();
}
}
}
/**
* Releases and closes the composition area if it is currently owned by
* this context's composition area handler.
*/
void releaseCompositionArea() {
synchronized(compositionAreaHandlerLock) {
if (compositionAreaHandler != null) {
compositionAreaHandler.releaseCompositionArea();
}
}
}
/**
* Calls CompositionAreaHandler.isCompositionAreaVisible() to see
* whether the composition area is visible or not.
* Notice that this method is always called on the AWT event dispatch
* thread.
*/
boolean isCompositionAreaVisible() {
if (compositionAreaHandler != null) {
return compositionAreaHandler.isCompositionAreaVisible();
}
return false;
}
/**
* Calls CompositionAreaHandler.setCompositionAreaVisible to
* show or hide the composition area.
* As isCompositionAreaVisible method, it is always called
* on AWT event dispatch thread.
*/
void setCompositionAreaVisible(boolean visible) {
if (compositionAreaHandler != null) {
compositionAreaHandler.setCompositionAreaVisible(visible);
}
}
/**
* Calls the current client component's implementation of getTextLocation.
*/
public Rectangle getTextLocation(TextHitInfo offset) {
return getReq().getTextLocation(offset);
}
/**
* Calls the current client component's implementation of getLocationOffset.
*/
public TextHitInfo getLocationOffset(int x, int y) {
return getReq().getLocationOffset(x, y);
}
/**
* Calls the current client component's implementation of getInsertPositionOffset.
*/
public int getInsertPositionOffset() {
return getReq().getInsertPositionOffset();
}
/**
* Calls the current client component's implementation of getCommittedText.
*/
public AttributedCharacterIterator getCommittedText(int beginIndex,
int endIndex,
Attribute[] attributes) {
return getReq().getCommittedText(beginIndex, endIndex, attributes);
}
/**
* Calls the current client component's implementation of getCommittedTextLength.
*/
public int getCommittedTextLength() {
return getReq().getCommittedTextLength();
}
/**
* Calls the current client component's implementation of cancelLatestCommittedText.
*/
public AttributedCharacterIterator cancelLatestCommittedText(Attribute[] attributes) {
return getReq().cancelLatestCommittedText(attributes);
}
/**
* Calls the current client component's implementation of getSelectedText.
*/
public AttributedCharacterIterator getSelectedText(Attribute[] attributes) {
return getReq().getSelectedText(attributes);
}
private InputMethodRequests getReq() {
if (haveActiveClient() && !useBelowTheSpotInput()) {
return getClientComponent().getInputMethodRequests();
} else {
return getCompositionAreaHandler(false);
}
}
// implements java.awt.im.spi.InputMethodContext.createInputMethodWindow
public Window createInputMethodWindow(String title, boolean attachToInputContext) {
InputContext context = attachToInputContext ? this : null;
return createInputMethodWindow(title, context, false);
}
// implements java.awt.im.spi.InputMethodContext.createInputMethodJFrame
public JFrame createInputMethodJFrame(String title, boolean attachToInputContext) {
InputContext context = attachToInputContext ? this : null;
return (JFrame)createInputMethodWindow(title, context, true);
}
static Window createInputMethodWindow(String title, InputContext context, boolean isSwing) {
if (GraphicsEnvironment.isHeadless()) {
throw new HeadlessException();
}
if (isSwing) {
return new InputMethodJFrame(title, context);
} else {
Toolkit toolkit = Toolkit.getDefaultToolkit();
if (toolkit instanceof InputMethodSupport) {
return ((InputMethodSupport)toolkit).createInputMethodWindow(
title, context);
}
}
throw new InternalError("Input methods must be supported");
}
/**
* @see java.awt.im.spi.InputMethodContext#enableClientWindowNotification
*/
public void enableClientWindowNotification(InputMethod inputMethod, boolean enable) {
super.enableClientWindowNotification(inputMethod, enable);
}
/**
* Disables or enables decorations for the composition window.
*/
void setCompositionAreaUndecorated(boolean undecorated) {
if (compositionAreaHandler != null) {
compositionAreaHandler.setCompositionAreaUndecorated(undecorated);
}
}
}

View File

@@ -0,0 +1,74 @@
/*
* Copyright (c) 2001, 2011, 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 sun.awt.im;
import javax.swing.JFrame;
import javax.swing.JRootPane;
/**
* Implements a Swing based input method window that provides the minimal
* functionality as specified in
* {@link java.awt.im.spi.InputMethodContext#createInputMethodJFrame}.
*
*/
public class InputMethodJFrame
extends JFrame
implements InputMethodWindow {
InputContext inputContext = null;
/**
* Constructs a Swing based input method window.
*/
public InputMethodJFrame(String title, InputContext context) {
super(title);
//InputMethodJFrame never has LookAndFeel decoration
if(JFrame.isDefaultLookAndFeelDecorated())
{
this.setUndecorated(true);
this.getRootPane().setWindowDecorationStyle(JRootPane.NONE);
}
if (context != null) {
this.inputContext = context;
}
setFocusableWindowState(false);
}
public void setInputContext(InputContext inputContext) {
this.inputContext = inputContext;
}
public java.awt.im.InputContext getInputContext() {
if (inputContext != null) {
return inputContext;
} else {
return super.getInputContext();
}
}
// Proclaim serial compatibility with 1.7.0
private static final long serialVersionUID = -4705856747771842549L;
}

View File

@@ -0,0 +1,171 @@
/*
* Copyright (c) 1998, 1999, 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 sun.awt.im;
import java.awt.AWTException;
import java.awt.im.spi.InputMethodDescriptor;
import java.util.Locale;
/**
* Provides complete information to make and handle the selection
* of an input method and a locale. Immutable class.
*/
final class InputMethodLocator {
private InputMethodDescriptor descriptor;
// Currently `loader' is always the class loader for a
// descriptor. `loader' is provided for future extensions to be
// able to load input methods from somewhere else, and to support
// per input method name space.
private ClassLoader loader;
private Locale locale;
InputMethodLocator(InputMethodDescriptor descriptor, ClassLoader loader, Locale locale) {
if (descriptor == null) {
throw new NullPointerException("descriptor can't be null");
}
this.descriptor = descriptor;
this.loader = loader;
this.locale = locale;
}
public boolean equals(Object other) {
if (other == this) {
return true;
}
if (other == null || this.getClass() != other.getClass()) {
return false;
}
InputMethodLocator otherLocator = (InputMethodLocator) other;
if (!descriptor.getClass().equals(otherLocator.descriptor.getClass())) {
return false;
}
if (loader == null && otherLocator.loader != null
|| loader != null && !loader.equals(otherLocator.loader)) {
return false;
}
if (locale == null && otherLocator.locale != null
|| locale != null && !locale.equals(otherLocator.locale)) {
return false;
}
return true;
}
public int hashCode() {
int result = descriptor.hashCode();
if (loader != null) {
result |= loader.hashCode() << 10;
}
if (locale != null) {
result |= locale.hashCode() << 20;
}
return result;
}
InputMethodDescriptor getDescriptor() {
return descriptor;
}
ClassLoader getClassLoader() {
return loader;
}
Locale getLocale() {
return locale;
}
/**
* Returns whether support for locale is available from
* the input method.
*/
boolean isLocaleAvailable(Locale locale) {
try {
Locale[] locales = descriptor.getAvailableLocales();
for (int i = 0; i < locales.length; i++) {
if (locales[i].equals(locale)) {
return true;
}
}
} catch (AWTException e) {
// treat this as no locale available
}
return false;
}
/**
* Returns an input method locator that has locale forLocale,
* but otherwise the same data as this locator. Does not
* check whether the input method actually supports forLocale -
* use {@link #isLocaleAvailable} for that.
*/
InputMethodLocator deriveLocator(Locale forLocale) {
if (forLocale == locale) {
return this;
} else {
return new InputMethodLocator(descriptor, loader, forLocale);
}
}
/**
* Returns whether this and other describe the same input method
* engine, ignoring the locale setting.
*/
boolean sameInputMethod(InputMethodLocator other) {
if (other == this) {
return true;
}
if (other == null) {
return false;
}
if (!descriptor.getClass().equals(other.descriptor.getClass())) {
return false;
}
if (loader == null && other.loader != null
|| loader != null && !loader.equals(other.loader)) {
return false;
}
return true;
}
/**
* Returns a string that can be used as an action command string.
* The first part of the string identifies the input method; it does
* not include '\n'. If getLocale is not null, getLocale().toString()
* is appended, separated by '\n'.
*/
String getActionCommandString() {
String inputMethodString = descriptor.getClass().getName();
if (locale == null) {
return inputMethodString;
} else {
return inputMethodString + "\n" + locale.toString();
}
}
}

View File

@@ -0,0 +1,231 @@
/*
* Copyright (c) 1998, 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 sun.awt.im;
import java.awt.AWTException;
import java.awt.CheckboxMenuItem;
import java.awt.Component;
import java.awt.Dialog;
import java.awt.EventQueue;
import java.awt.Frame;
import java.awt.PopupMenu;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.Toolkit;
import sun.awt.AppContext;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InvocationEvent;
import java.awt.im.spi.InputMethodDescriptor;
import java.lang.reflect.InvocationTargetException;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.security.PrivilegedActionException;
import java.security.PrivilegedExceptionAction;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Locale;
import java.util.ServiceLoader;
import java.util.Vector;
import java.util.Set;
import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences;
import sun.awt.InputMethodSupport;
import sun.awt.SunToolkit;
/**
* <code>InputMethodManager</code> is an abstract class that manages the input
* method environment of JVM. There is only one <code>InputMethodManager</code>
* instance in JVM that is executed under a separate daemon thread.
* <code>InputMethodManager</code> performs the following:
* <UL>
* <LI>
* Keeps track of the current input context.</LI>
*
* <LI>
* Provides a user interface to switch input methods and notifies the current
* input context about changes made from the user interface.</LI>
* </UL>
*
* The mechanism for supporting input method switch is as follows. (Note that
* this may change in future releases.)
*
* <UL>
* <LI>
* One way is to use platform-dependent window manager's menu (known as the <I>Window
* menu </I>in Motif and the <I>System menu</I> or <I>Control menu</I> in
* Win32) on each window which is popped up by clicking the left top box of
* a window (known as <I>Window menu button</I> in Motif and <I>System menu
* button</I> in Win32). This happens to be common in both Motif and Win32.</LI>
*
* <LI>
* When more than one input method descriptor can be found or the only input
* method descriptor found supports multiple locales, a menu item
* is added to the window (manager) menu. This item label is obtained invoking
* <code>getTriggerMenuString()</code>. If null is returned by this method, it
* means that there is only input method or none in the environment. Frame and Dialog
* invoke this method.</LI>
*
* <LI>
* This menu item means a trigger switch to the user to pop up a selection
* menu.</LI>
*
* <LI>
* When the menu item of the window (manager) menu has been selected by the
* user, Frame/Dialog invokes <code>notifyChangeRequest()</code> to notify
* <code>InputMethodManager</code> that the user wants to switch input methods.</LI>
*
* <LI>
* <code>InputMethodManager</code> displays a pop-up menu to choose an input method.</LI>
*
* <LI>
* <code>InputMethodManager</code> notifies the current <code>InputContext</code> of
* the selected <code>InputMethod</code>.</LI>
* </UL>
*
* <UL>
* <LI>
* The other way is to use user-defined hot key combination to show the pop-up menu to
* choose an input method. This is useful for the platforms which do not provide a
* way to add a menu item in the window (manager) menu.</LI>
*
* <LI>
* When the hot key combination is typed by the user, the component which has the input
* focus invokes <code>notifyChangeRequestByHotKey()</code> to notify
* <code>InputMethodManager</code> that the user wants to switch input methods.</LI>
*
* <LI>
* This results in a popup menu and notification to the current input context,
* as above.</LI>
* </UL>
*
* @see java.awt.im.spi.InputMethod
* @see sun.awt.im.InputContext
* @see sun.awt.im.InputMethodAdapter
* @author JavaSoft International
*/
public abstract class InputMethodManager {
/**
* InputMethodManager thread name
*/
private static final String threadName = "AWT-InputMethodManager";
/**
* Object for global locking
*/
private static final Object LOCK = new Object();
/**
* The InputMethodManager instance
*/
private static InputMethodManager inputMethodManager;
/**
* Returns the instance of InputMethodManager. This method creates
* the instance that is unique in the Java VM if it has not been
* created yet.
*
* @return the InputMethodManager instance
*/
public static final InputMethodManager getInstance() {
if (inputMethodManager != null) {
return inputMethodManager;
}
synchronized(LOCK) {
if (inputMethodManager == null) {
ExecutableInputMethodManager imm = new ExecutableInputMethodManager();
// Initialize the input method manager and start a
// daemon thread if the user has multiple input methods
// to choose from. Otherwise, just keep the instance.
if (imm.hasMultipleInputMethods()) {
imm.initialize();
Thread immThread = new Thread(imm, threadName);
immThread.setDaemon(true);
immThread.setPriority(Thread.NORM_PRIORITY + 1);
immThread.start();
}
inputMethodManager = imm;
}
}
return inputMethodManager;
}
/**
* Gets a string for the trigger menu item that should be added to
* the window manager menu. If no need to display the trigger menu
* item, null is returned.
*/
public abstract String getTriggerMenuString();
/**
* Notifies InputMethodManager that input method change has been
* requested by the user. This notification triggers a popup menu
* for user selection.
*
* @param comp Component that has accepted the change
* request. This component has to be a Frame or Dialog.
*/
public abstract void notifyChangeRequest(Component comp);
/**
* Notifies InputMethodManager that input method change has been
* requested by the user using the hot key combination. This
* notification triggers a popup menu for user selection.
*
* @param comp Component that has accepted the change
* request. This component has the input focus.
*/
public abstract void notifyChangeRequestByHotKey(Component comp);
/**
* Sets the current input context so that it will be notified
* of input method changes initiated from the user interface.
* Set to real input context when activating; to null when
* deactivating.
*/
abstract void setInputContext(InputContext inputContext);
/**
* Tries to find an input method locator for the given locale.
* Returns null if no available input method locator supports
* the locale.
*/
abstract InputMethodLocator findInputMethod(Locale forLocale);
/**
* Gets the default keyboard locale of the underlying operating system.
*/
abstract Locale getDefaultKeyboardLocale();
/**
* Returns whether multiple input methods are available or not
*/
abstract boolean hasMultipleInputMethods();
}

View File

@@ -0,0 +1,275 @@
/*
* Copyright (c) 2003, 2007, 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 sun.awt.im;
import java.awt.AWTException;
import java.awt.CheckboxMenuItem;
import java.awt.Component;
import java.awt.Container;
import java.awt.PopupMenu;
import java.awt.Menu;
import java.awt.MenuItem;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.im.spi.InputMethodDescriptor;
import java.util.Locale;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPopupMenu;
import javax.swing.JMenu;
import javax.swing.JMenuItem;
/**
* <code>InputMethodPopupMenu</code> provides the popup selection menu
*/
abstract class InputMethodPopupMenu implements ActionListener {
// Factory method to provide the menu, depending on the client, i.e.,
// provide Swing popup menu if client is a swing app, otherwise AWT popup
// is created.
static InputMethodPopupMenu getInstance(Component client, String title) {
if ((client instanceof JFrame) ||
(client instanceof JDialog)) {
return new JInputMethodPopupMenu(title);
} else {
return new AWTInputMethodPopupMenu(title);
}
}
abstract void show(Component c, int x, int y);
abstract void removeAll();
abstract void addSeparator();
abstract void addToComponent(Component c);
abstract Object createSubmenu(String label);
abstract void add(Object menuItem);
abstract void addMenuItem(String label, String command, String currentSelection);
abstract void addMenuItem(Object targetMenu, String label, String command,
String currentSelection);
void addOneInputMethodToMenu(InputMethodLocator locator, String currentSelection) {
InputMethodDescriptor descriptor = locator.getDescriptor();
String label = descriptor.getInputMethodDisplayName(null, Locale.getDefault());
String command = locator.getActionCommandString();
Locale[] locales = null;
int localeCount;
try {
locales = descriptor.getAvailableLocales();
localeCount = locales.length;
} catch (AWTException e) {
// ??? should have better error handling -
// tell user what happened, then remove this input method from the list.
// For the time being, just show it disabled.
localeCount = 0;
}
if (localeCount == 0) {
// could be IIIMP adapter which has lost its connection
addMenuItem(label, null, currentSelection);
} else if (localeCount == 1) {
if (descriptor.hasDynamicLocaleList()) {
// try to make sure that what the user sees and what
// we eventually select is consistent even if the locale
// list changes in the meantime
label = descriptor.getInputMethodDisplayName(locales[0], Locale.getDefault());
command = locator.deriveLocator(locales[0]).getActionCommandString();
}
addMenuItem(label, command, currentSelection);
} else {
Object submenu = createSubmenu(label);
add(submenu);
for (int j = 0; j < localeCount; j++) {
Locale locale = locales[j];
String subLabel = getLocaleName(locale);
String subCommand = locator.deriveLocator(locale).getActionCommandString();
addMenuItem(submenu, subLabel, subCommand, currentSelection);
}
}
}
/**
* Returns whether command indicates the same input method as currentSelection,
* taking into account that command may not specify a locale where currentSelection does.
*/
static boolean isSelected(String command, String currentSelection) {
if (command == null || currentSelection == null) {
return false;
}
if (command.equals(currentSelection)) {
return true;
}
// currentSelection may indicate a locale where command does not
int index = currentSelection.indexOf('\n');
if (index != -1 && currentSelection.substring(0, index).equals(command)) {
return true;
}
return false;
}
/**
* Returns a localized locale name for input methods with the
* given locale. It falls back to Locale.getDisplayName() and
* then to Locale.toString() if no localized locale name is found.
*
* @param locale Locale for which localized locale name is obtained
*/
String getLocaleName(Locale locale) {
String localeString = locale.toString();
String localeName = Toolkit.getProperty("AWT.InputMethodLanguage." + localeString, null);
if (localeName == null) {
localeName = locale.getDisplayName();
if (localeName == null || localeName.length() == 0)
localeName = localeString;
}
return localeName;
}
// ActionListener implementation
public void actionPerformed(ActionEvent event) {
String choice = event.getActionCommand();
((ExecutableInputMethodManager)InputMethodManager.getInstance()).changeInputMethod(choice);
}
}
class JInputMethodPopupMenu extends InputMethodPopupMenu {
static JPopupMenu delegate = null;
JInputMethodPopupMenu(String title) {
synchronized (this) {
if (delegate == null) {
delegate = new JPopupMenu(title);
}
}
}
void show(Component c, int x, int y) {
delegate.show(c, x, y);
}
void removeAll() {
delegate.removeAll();
}
void addSeparator() {
delegate.addSeparator();
}
void addToComponent(Component c) {
}
Object createSubmenu(String label) {
return new JMenu(label);
}
void add(Object menuItem) {
delegate.add((JMenuItem)menuItem);
}
void addMenuItem(String label, String command, String currentSelection) {
addMenuItem(delegate, label, command, currentSelection);
}
void addMenuItem(Object targetMenu, String label, String command, String currentSelection) {
JMenuItem menuItem;
if (isSelected(command, currentSelection)) {
menuItem = new JCheckBoxMenuItem(label, true);
} else {
menuItem = new JMenuItem(label);
}
menuItem.setActionCommand(command);
menuItem.addActionListener(this);
menuItem.setEnabled(command != null);
if (targetMenu instanceof JMenu) {
((JMenu)targetMenu).add(menuItem);
} else {
((JPopupMenu)targetMenu).add(menuItem);
}
}
}
class AWTInputMethodPopupMenu extends InputMethodPopupMenu {
static PopupMenu delegate = null;
AWTInputMethodPopupMenu(String title) {
synchronized (this) {
if (delegate == null) {
delegate = new PopupMenu(title);
}
}
}
void show(Component c, int x, int y) {
delegate.show(c, x, y);
}
void removeAll() {
delegate.removeAll();
}
void addSeparator() {
delegate.addSeparator();
}
void addToComponent(Component c) {
c.add(delegate);
}
Object createSubmenu(String label) {
return new Menu(label);
}
void add(Object menuItem) {
delegate.add((MenuItem)menuItem);
}
void addMenuItem(String label, String command, String currentSelection) {
addMenuItem(delegate, label, command, currentSelection);
}
void addMenuItem(Object targetMenu, String label, String command, String currentSelection) {
MenuItem menuItem;
if (isSelected(command, currentSelection)) {
menuItem = new CheckboxMenuItem(label, true);
} else {
menuItem = new MenuItem(label);
}
menuItem.setActionCommand(command);
menuItem.addActionListener(this);
menuItem.setEnabled(command != null);
((Menu)targetMenu).add(menuItem);
}
}

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 1999, 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 sun.awt.im;
/**
* Interface for input method windows that need special handling
* by input method window.
*
*/
public interface InputMethodWindow {
/**
* Sets the input context that this input method window is attached to,
* null to unattach the window.
* @see java.awt.im.spi.InputMethodContext#createInputMethodWindow
*/
public void setInputContext(InputContext inputContext);
}

View File

@@ -0,0 +1,67 @@
/*
* Copyright (c) 1999, 2011, 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 sun.awt.im;
import java.awt.Frame;
/**
* Implements a simple input method window that provides the minimal
* functionality as specified in
* {@link java.awt.im.spi.InputMethodContext#createInputMethodWindow}.
*
*/
public class SimpleInputMethodWindow
extends Frame
implements InputMethodWindow {
InputContext inputContext = null;
/**
* Constructs a simple input method window.
*/
public SimpleInputMethodWindow(String title, InputContext context) {
super(title);
if (context != null) {
this.inputContext = context;
}
setFocusableWindowState(false);
}
public void setInputContext(InputContext inputContext) {
this.inputContext = inputContext;
}
public java.awt.im.InputContext getInputContext() {
if (inputContext != null) {
return inputContext;
} else {
return super.getInputContext();
}
}
// Proclaim serial compatibility with 1.7.0
private static final long serialVersionUID = 5093376647036461555L;
}