JDK-7026055 : Regression : Cannot use IME on JComboBox Japanese
  • Type: Bug
  • Component: client-libs
  • Sub-Component: java.awt
  • Affected Version: 7
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: windows
  • CPU: x86
  • Submitted: 2011-03-09
  • Updated: 2015-04-06
  • Resolved: 2011-07-07
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b142Fixed
Related Reports
Relates :  
Relates :  
Relates :  
Relates :  
Relates :  
Description
SYNOPSIS
--------
Cannot use IME on JComboBox

OPERATING SYSTEMS
-----------------
Windows XP SP3 x86 (Japanese)
Windows Server 2008 R2 Enterprise SP1 (Japanese)
Not Reproducible using JDK 7 b130 on Linux
Not Reproducible using 1.6.0_24-b07 on Windows


FULL JDK VERSION
----------------
java version "1.7.0-ea"
Java(TM) SE Runtime Environment (build 1.7.0-ea-b130)
Java HotSpot(TM) Client VM (build 21.0-b02, mixed mode)

DESCRIPTION
-----------
On Windows platform, we cannot use IME on JComboBox after opening drop-down list. I applied KeyListener against JComboBox, it should work.  Works fine with JDK 7 b130 on Linux, and 1.6.0_24-b07 on Windows

REPRODUCTION INSTRUCTIONS
-------------------------
This testing requires Japanese Windows

1. Compile and run JComboBoxTest2.java from Command Prompt
   > javac JComboBoxTest2.java
   > java JComboBoxTest2
2. Turn on IME, type "ma", Japanese "MA" is displayed on preedit area
3. Press Return key to commit
4. Japanese "MAMIMUMEMO" is displayed on JComboBox
5. Open drop-down list on JComboBox
6. Check IME status. If IME is turned off, please turn it on
   (If it's turned off, it may not be turned on)
7. If IME is on, type "wa", Japanese "WA" should be displayed on preedit
   area, but "wa" is displayed in Command Prompt

TESTCASE SOURCE
---------------
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

class JComboBoxTest2 extends JFrame implements ActionListener {
    MyComboBox cb = null;
    JButton btn = null;
    static String[] data = new String[] {
        "\u3042\u3044\u3046\u3048\u304a", "\u304b\u304d\u304f\u3051\u3053",
        "\u3055\u3057\u3059\u305b\u305d", "\u305f\u3061\u3064\u3066\u3068",
        "\u306a\u306b\u306c\u306d\u306e", "\u306f\u3072\u3075\u3078\u307b",
        "\u307e\u307f\u3080\u3081\u3082", "\u3084\u3086\u3088",
        "\u3089\u308a\u308b\u308c\u308d", "\u308f\u3092\u3093",
    };

    JComboBoxTest2 () {
        setTitle("JComboBoxTest2");
        Container c = getContentPane();
        c.setLayout(new GridLayout(0,1));
        cb = new MyComboBox(data);
        c.add(cb);
        btn = new JButton("Print");
        btn.addActionListener(this);
        c.add(btn);
        pack();
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);
        setVisible(true);
    }
    public void actionPerformed(ActionEvent ae) {
        System.out.println(cb.getSelectedItem().toString());
        cb.requestFocus();
    }
    public static void main(String[] args) {
        new JComboBoxTest2();
    }

    class MyComboBox extends JComboBox implements KeyListener, JComboBox.KeySelectionManager {
        private long accessTime;
        private StringBuffer sb = new StringBuffer();
        MyComboBox(String[] s){
            super(s);
            setKeySelectionManager(this);
            addKeyListener(this);
        }
        public int selectionForKey(char aKey, ComboBoxModel aModel) { return -1; }
        public void keyPressed(KeyEvent event) { }
        public void keyTyped(KeyEvent event) {
            char c = event.getKeyChar();
            if ((accessTime + 800) < System.currentTimeMillis()) {
                sb = new StringBuffer();
            }
            sb.append(c);
            accessTime = System.currentTimeMillis();
            String lower = sb.toString().toLowerCase();
            System.out.println("Search String: " + lower);
            for(int i=0; i<getItemCount(); i++) {
                if(((String)getItemAt(i)).toLowerCase().startsWith(lower)) {
                    setSelectedIndex(i);
                    break;
                }
            }
        }
        public void keyReleased(KeyEvent event) { }
    }
}

Comments
SUGGESTED FIX The latest version of the fix eliminates both calls: http://sa.sfbay.sun.com/projects/awt_data/7/7026055/
29-04-2011

EVALUATION The proposed fix eliminates both calls to ImmAssociateContext in the AwtComponent class. These calls really look redundant and wrong in case of the synthetic focus model. Likely, both removed calls are workarounds introduced long time ago to resolve some old focus issue (my guess the problem was that focus events doesn't come for some reason and the input context isn't associated with the focus owner properly and additional "set context" calls were introduced). It's likely that the focus issues are already fixed in jdk7 and the focus change should set the proxy window handle to the input context.
29-04-2011

EVALUATION It's a regression of the changes for 6806217 implement synthetic focus model for MS Windows After 6806217, it nullifies the input context associated to the proxy upon the creation/showing/hiding the supplementary window.
20-04-2011

SUGGESTED FIX $ hg diff src/windows/native/sun/windows/awt_Component.cpp diff -r b5e609488bc8 src/windows/native/sun/windows/awt_Component.cpp --- a/src/windows/native/sun/windows/awt_Component.cpp Tue Mar 01 15:24:46 2011 +0300 +++ b/src/windows/native/sun/windows/awt_Component.cpp Wed Apr 20 18:50:25 2011 +0400 @@ -549,7 +549,7 @@ AwtComponent::CreateHWnd(JNIEnv *env, LP m_hwnd = hwnd; - ImmAssociateContext(NULL); + ::ImmAssociateContext(GetHWnd(), NULL); SetDrawState((jint)JAWT_LOCK_SURFACE_CHANGED | (jint)JAWT_LOCK_BOUNDS_CHANGED | @@ -2036,7 +2036,7 @@ MsgRouting AwtComponent::WmShowWindow(BO } if (ImmGetContext() != 0 && ImmGetContext() != context) { - ImmAssociateContext(context); + ::ImmAssociateContext(GetHWnd(), context); } return mrDoDefault;
20-04-2011

EVALUATION according to the comments it looks like an AWT problem, reassigned
05-04-2011