Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8264728

When use chinese IME, the candidate box isn't moved with caret of JTextArea

XMLWordPrintable

      ADDITIONAL SYSTEM INFORMATION :
      LINUX

      A DESCRIPTION OF THE PROBLEM :
      When I use chinese IME, the candidate box isn't moved with caret of JTextArea. It always under the window.

      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      1, Run the example code for test case.
      2, Open chinese IME to input a chinese char.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      We hope the candidate box is moved with caret of JTextArea.
      ACTUAL -
      The candidate box is always under the window.

      ---------- BEGIN SOURCE ----------
      public class TestManager
      {
          private static void testTextArea()
          {
              JFrame frame = new JFrame();
              frame.setSize(1000, 600);
              
              JTextArea ta = new JTextArea();
              ta.setText("OFFICE");
              ta.setBounds(100, 100, 300, 300);
             
              frame.getContentPane().setLayout(null);
              frame.getContentPane().add(ta);
              
              frame.setVisible(true);
          }

          
          public static void main(String[] args)
          {
           testTextArea();
          }
      }
      ---------- END SOURCE ----------

      CUSTOMER SUBMITTED WORKAROUND :
      1, add code to XInputMethod
      public class XInputMethod extends X11InputMethod {

          @Override
          public void setInputMethodContext(InputMethodContext context) {
              this.inputContext = context; // add this.
              context.enableClientWindowNotification(this, true);
          }
          public void dispatchEvent(AWTEvent e) {
              switch (e.getID())
              {
                  case KeyEvent.KEY_PRESSED:
                  case KeyEvent.KEY_RELEASED:
                  case MouseEvent.MOUSE_CLICKED:
                      positionCandidateWindow();
                      break;

                  default:
                      break;
              }
          }


          private void positionCandidateWindow()
          {
              if (this.inputContext == null)
              {
                  return;
              }

              Component client = getClientComponent();

              if (client == null || !client.isShowing())
              {
                  return;
              }

              int x = 0;
              int y = 0;

              // Get this textcomponent coordinate from root window.
              Component temp = client;
              while (temp != null)
              {
                   Component parent = temp.getParent();
                   if (parent == null
                      || temp instanceof javax.swing.JFrame
                      || temp instanceof javax.swing.JDialog)
                   {
                       break;
                   }

                   x += temp.getX();
                   y += temp.getY();
                   temp = parent;
              }

              if (haveActiveClient())
              {
                  Rectangle rc = inputContext.getTextLocation(TextHitInfo.leading(0));
                  x += rc.x;
                  y += rc.y + rc.height;
                  //we don't need this location
                  Point p = client.getLocationOnScreen();
                  x -= p.x;
                  y -= p.y;
              }
              else
              {
                  Dimension size = client.getSize();
                  y += size.height;
              }

              moveCandidateWindow(x, y);
          }
      private native void moveCandidateWindow(int x, int y);

      2. add code to awt_InputMethod.c
      JNIEXPORT void JNICALL Java_sun_awt_X11_XInputMethod_moveCandidateWindow
       (JNIEnv *env, jobject this, jint x, jint y)
      {
          X11InputMethodData *pX11IMData;
          XVaNestedList preedit_attr;
          XPoint nspot;
          nspot.x = x;
          nspot.y = y;

          AWT_LOCK();
          pX11IMData = getX11InputMethodData(env, this);

          if ((pX11IMData == NULL) || (pX11IMData->current_ic == NULL)) {
              AWT_UNLOCK();
              return;
          }

          preedit_attr = XVaCreateNestedList(0, XNSpotLocation, &nspot, NULL);
          XSetICValues(pX11IMData->current_ic, XNPreeditAttributes, preedit_attr, NULL);

          XFree(preedit_attr);

          AWT_UNLOCK();
      }

      3. add code to mapfile-vers
      Java_sun_awt_X11_XInputMethod_moveCandidateWindow;

      FREQUENCY : always


            Unassigned Unassigned
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            7 Start watching this issue

              Created:
              Updated: