Automatic toggling of character width by Windows 7 input methods in Java
Asked Answered
E

2

11

I have a couple of input methods for writing (Traditional Chinese) Taiwanese that come with the Windows 7. Also, all of the input methods have an option to switch the character width (single byte/double byte characters).

  • Chinese (Traditional) - New Quick
  • Chinese (Traditional) - ChangJie
  • Chinese (Traditional) - Quick
  • Chinese (Traditional) - Phonetic
  • Chinese (Traditional) - New Phonetic
  • Chinese (Traditional) - New ChangJie

If I select one of these input methods in Java application and set the character width to half-width(single byte character mode) i can successfully input text in JTextField. But, if the application displays some dialog box (e.g. JOptionPane) or pop up window, the input method character width will automatically change to full-width(double byte character mode). After that, the user must manually toggle to half-width characters.

I can programmatically switch on or off the input method using the Java class "InputContext", but i can't control if the input method is set to full-width/half-width (single/double byte) character mode.

I thought maybe it could be disabled from the Windows input method settings, but there was no option related to automatic switching of the character width.

The question is: Is there a way to handle (disable) this automatic toggling ?

Here is an example code to test this with the above input methods:

public class Example implements ActionListener {

    JFrame f = new JFrame("pasod");
    JTextField txt = new JTextField();
    Button btn = new Button("Locale");

    public Example() {

        JPanel panel = new JPanel();
        panel.setLayout(new GridLayout());
        btn.addActionListener(this);
        panel.add(btn);
        panel.add(txt);
        f.add(panel);
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.pack();
        f.setSize(800, 100);
        f.setVisible(true);
    }   

    public static void main(String[] args) {
        new Example();              
    }

    public void actionPerformed(ActionEvent arg0) {
        JOptionPane.showMessageDialog(btn, "Neso", "Neso",
                 JOptionPane.INFORMATION_MESSAGE);
    }
}

Thanks.

Estis answered 27/5, 2013 at 13:50 Comment(2)
Just a nitpick, but I don't think the full/half-width forms have anything to do with the number of bytes they consume in UTF-16. Not that this helps with the problem. +1Infinity
There are many things people find that the JOptionPane does wrong and the only simple solution is to make your own. i made my own JDialog class for Java and I have been using it ever since.Pearson
G
1

Ok I've had a trace through the Java source code looking for anything that stands out;

You call JOptionPane.showMessageDialog() this overloads to JOptionPane.showOptionDialog();

public static int showOptionDialog(Component parentComponent,
        Object message, String title, int optionType, int messageType,
        Icon icon, Object[] options, Object initialValue) 
        throws HeadlessException {
        JOptionPane             pane = new JOptionPane(message, messageType,
                                                       optionType, icon,
                                                       options, initialValue);

        pane.setInitialValue(initialValue);
        pane.setComponentOrientation(((parentComponent == null) ?
        getRootFrame() : parentComponent).getComponentOrientation());

        int style = styleFromMessageType(messageType);
        JDialog dialog = pane.createDialog(parentComponent, title, style);

        pane.selectInitialValue();
        dialog.show();    
        //..Result handling code
    }

So we look into createDialog();

public JDialog createDialog(String title) throws HeadlessException {
    int style = styleFromMessageType(getMessageType());
    JDialog dialog = new JDialog((Dialog) null, title, true);
    initDialog(dialog, style, null);
    return dialog;
}

So we check the constructor/s of JDialog these all call dialogInit();

protected void dialogInit() {
    enableEvents(AWTEvent.KEY_EVENT_MASK | AWTEvent.WINDOW_EVENT_MASK);
    setLocale( JComponent.getDefaultLocale() );
    setRootPane(createRootPane());
    setRootPaneCheckingEnabled(true);
    if (JDialog.isDefaultLookAndFeelDecorated()) {
        boolean supportsWindowDecorations = 
        UIManager.getLookAndFeel().getSupportsWindowDecorations();
        if (supportsWindowDecorations) {
            setUndecorated(true);
            getRootPane().setWindowDecorationStyle(JRootPane.PLAIN_DIALOG);
        }
    }
    sun.awt.SunToolkit.checkAndSetPolicy(this, true);
}

Here we've found setLocale( JComponent.getDefaultLocale() );;

So it appears whenever you create a JDialog, whether it be indirect or not the locale of your program is reset to default, I'm guessing this includes resetting your input settings.

There are a few ways you can set the default Locale (programatically, system properties or runtime args); Details found here

Hope that helps you

Gemagemara answered 4/8, 2013 at 22:23 Comment(0)
H
1

I did a simple test:

I opened IE, selected a tab, and at the address bar, set Chinese IME to be half width. Then click another tab, the IME change to full width automatically.

So I don't think it had anything to do with Java. It's a Windows behavior.

Hieratic answered 6/7, 2014 at 14:7 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.