为什么设置JDialog或JFramesetVisible(True)切换我的IME设置?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (4)
  • 关注 (0)
  • 查看 (167)

我发现当我在Java中显示一个JDialog或一个新的JFrame应用程序时,会在Windows 7中将我的中文输入法从半字节模式切换到全字节模式。

为什么调用对话框或框架setVisible(true)方法切换我的IME设置?

有谁知道代码有什么问题,或者是Java的错误?

重现问题的过程:

  1. 运行应用程序。
  2. 将您的语言改为中文输入法之一。中文(繁体) - 快速
  3. 点击程序中的按钮

我的语言设置

添加默认区域设置后,它仍然无法工作

import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JButton;
import javax.swing.JLabel;
import java.awt.BorderLayout;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import java.util.Locale;

public class MainWindow {

private JFrame frame;
private Locale l;

/**
 * Create the application.
 */
public MainWindow() {
    initialize();
}

/**
 * Initialize the contents of the frame.
 */
private void initialize() {

    l = new Locale("zh", "zh_TW");

    frame = new JFrame();
    frame.setLocale(l);
    frame.setBounds(100, 100, 450, 300);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JButton btnNewButton = new JButton("New button");
    btnNewButton.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent arg0) {

            JDialog d = new JDialog(frame, "Run", true);
            d.getContentPane().add(new JLabel("dsad"));
            d.setMinimumSize(new Dimension(150, 100));
            d.setLocationRelativeTo(null);
            d.setLocale(l);
            d.setVisible(true);

        }
    });
    frame.getContentPane().add(btnNewButton, BorderLayout.CENTER);
}

/**
 * Launch the application.
 */
public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
        public void run() {
            try {
                MainWindow window = new MainWindow();
                window.frame.setVisible(true);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    });
}


}
提问于
用户回答回答于

我做了一个简单的测试:

我打开IE浏览器,选中一个选项卡,在地址栏中设置中文IME为半宽。然后单击另一个选项卡,IME自动更改为全宽。

所以我不认为这与Java有什么关系。这是一个Windows / IME行为。

用户回答回答于

OP明确要求的是切换键盘,甚至是一个键盘下的模式,而不是切换语言。在Java语言环境可以设置很多方式来改变语言,但不是键盘,没有模式。如果我想让我的Java Swing应用程序切换到使用中文双拼键盘的模式,但对于中文输入却带有英文标点符号呢?

纠正我,如果我错了,但没有办法让Java为特定的IME或模式选择本机键盘。这里是一篇关于Windows甚至Mac的IME开发的文章。我希望能够解释很多

http://blog.gatunka.com/2009/09/20/ime-basics-for-developers/

但是如果OP只是想让用户输入密码字段的英文,那么他有很多解决方案。但这不是他所说的。

用户回答回答于

我认为这可能与Windows 7记得为每个正在运行的应用程序设置的键盘/语言有关:

  1. 我打开我的浏览器。我可以在我的任务栏中看到我的键盘是ES。
  2. 然后我打开任何其他应用程序。没有什么变化。
  3. 我再次在浏览器中设置焦点。
  4. 我按Alt + Shift,这是一个快捷键来改变键盘设置。现在我可以看到的是EN(英文)
  5. 我点击另一个应用程序的窗口(或者我使用Alt + Tab)。我的键盘设置更改为ES
  6. 每次我回到浏览器时,键盘设置都会变为EN,并保留其余的应用程序。

这也适用于JVM应用程序,例如Eclipse,所以我认为这不是JVM语言环境问题。

用户回答回答于

根据Oracle的文档

你的应用程序的默认语言环境有三种确定方式。首先,除非明确更改默认值,否则Locale.getDefault()方法将返回Java虚拟机(JVM)首次加载时最初确定的区域设置。也就是说,JVM从主机环境中确定默认的语言环境。主机环境的语言环境由主机操作系统和在该系统上建立的用户首选项决定。

在我的问题中,在应用程序启动之后,Windows中的默认值已经被更改,这意味着JVM语言环境已经设置好了。设置了特定框架的语言环境,但是创建新框架会根据默认语言环境(对于JDialog和JFrame)来设置语言环境:

 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);
 }

由于在Windows中设置了默认语言环境,因此可以认为JComponent.getDefaultLocale()将返回Windows语言环境。getDefaultLocale()本身返回当前应用程序上下文的语言环境(VM语言环境)。调用下面的方法将设置当前上下文的语言环境:

javax.swing.JComponent.setDefaultLocale(locale);

这为虚拟机设置了默认的语言环境

SwingUtilities.appContextPut(defaultLocale, l);

扫码关注云+社区

领取腾讯云代金券