emergente - manejo de ventanas en java
¿Por qué la configuración de JDialog o JFrame setVisible(true) cambia la configuración de mi IME? (4)
Creo que puede estar relacionado con el hecho de que Windows 7 recuerda el teclado / idioma establecido para cada aplicación en ejecución:
- Abro mi navegador (en este caso Chrome). Puedo ver en mi barra de tareas mi teclado es ES (español).
- Entonces abro cualquier otra aplicación. Nada cambia.
- Puse el foco de nuevo en el navegador.
- Presiono Alt + Shift, que es un atajo para cambiar el conjunto de teclado. Ahora lo que puedo ver es EN (Inglés)
- Hago clic en la ventana de la otra aplicación (o uso Alt + TAB). Mi conjunto de teclado cambia a ES
- Cada vez que vuelvo al navegador, el conjunto de teclado cambia a EN, manteniendo el ES para el resto de aplicaciones.
Esto funciona también para aplicaciones JVM, por ejemplo Eclipse, así que creo que no es un problema de configuración regional de JVM.
Descubrí que cuando muestro un JDialog
o un nuevo JFrame
en mi aplicación Java swing, cambiaré mi Método de Entrada Chino del modo de medio byte al modo de byte completo en Windows 7.
¿Por qué llamar al diálogo o al método setVisible(true)
para cambiar mi configuración de IME?
¿Alguien sabe qué está mal con el código, o es un error de Java?
Procedimiento para reproducir el problema:
- Ejecutar la aplicación.
- cambie su idioma a uno de los métodos de entrada chinos, por ejemplo. Chino (tradicional) - Rápido
- haga clic en el botón en el programa
Mi configuración de idioma
He encontrado una pregunta similar Alternar automáticamente el ancho de caracteres por los métodos de entrada de Windows 7 en Java
y después de agregar la configuración regional predeterminada, todavía no funciona
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();
}
}
});
}
}
De acuerdo con la documentación de Oracle , parece que esto se está comportando como lo esperaría, de cómo entendí la pregunta:
La configuración regional predeterminada de su aplicación se determina de tres maneras. Primero, a menos que haya cambiado explícitamente el valor predeterminado, el método Locale.getDefault () devuelve la configuración regional que inicialmente fue determinada por la Máquina Virtual de Java (JVM) cuando se cargó por primera vez. Es decir, la JVM determina la configuración regional predeterminada del entorno de host. La configuración regional del entorno del host está determinada por el sistema operativo del host y las preferencias del usuario establecidas en ese sistema.
En su pregunta, el valor predeterminado se cambió en Windows después de que se inició la aplicación, lo que significa que la configuración regional de JVM ya estaba establecida. Se estableció la configuración regional para un marco específico, pero la creación de un nuevo marco establece la configuración regional en función de la configuración regional predeterminada (que ocurre tanto para JDialog como para 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);
}
Dado que está configurando la configuración regional predeterminada en Windows, se podría pensar que JComponent.getDefaultLocale () devolverá la configuración regional de Windows. getDefaultLocale () devuelve la configuración regional del contexto de la aplicación actual (la configuración regional de VM). Al llamar al siguiente método se establecerá la configuración regional para el contexto actual:
javax.swing.JComponent.setDefaultLocale(locale);
Eso establece la configuración regional predeterminada para la máquina virtual (en realidad llama a través de
SwingUtilities.appContextPut(defaultLocale, l);
lo que hace que sea un poco más evidente lo que está sucediendo).
Si la configuración de DefaultLocale soluciona el problema, me imagino que en otro lugar de la cadena de llamadas se llama a defaultLocale de una manera que hace que Windows cambie la configuración.
Si eso no le proporciona la funcionalidad esperada, la única otra propiedad que puedo sugerirle es la clase InputContext :
Proporciona métodos para controlar las instalaciones de entrada de texto, como los métodos de entrada y las distribuciones de teclado. Dos métodos manejan tanto los métodos de entrada como los diseños de teclado: selectInputMethod permite que un componente del cliente seleccione un método de entrada o diseño de teclado por configuración regional, getLocale permite que un componente del cliente obtenga la configuración regional del método de entrada actual o el diseño del teclado.
Hice una prueba simple:
Abrí IE, seleccioné una pestaña y, en la barra de direcciones, configuré IME chino en la mitad del ancho. Luego haga clic en otra pestaña, el IME cambiará a ancho completo automáticamente.
Así que no creo que tenga nada que ver con Java. Es un comportamiento de Windows / IME.
Primero, hay un error en el código del OP. Déjame escribir lo que es correcto:
l = new Locale("zh", "TW");
Y lo que quiere decir OP es medio ancho / ancho completo (no medio byte / completo byte). En un modo de ancho completo, una letra en inglés usará más de un byte, como A en lugar de A. Esto se puede cambiar usando Shift-Space.
Introducción a IME
En Región e Idioma, puede seleccionar un idioma, además de muchos teclados. El lenguaje chino simplificado, por ejemplo, tiene al menos tres teclados de uso común:
El teclado de EE. UU. Permite al usuario escribir en inglés, no hay forma de escribir en chino
El teclado Microsoft Pinyin permite a un usuario escribir la ortografía y elegir el carácter correcto
ShuangPin permite al usuario escribir la ortografía con menos pulsaciones de teclas
Hay más teclados en Windows 7 que se agregarán solo para chino simplificado.
¿Es eso lo suficientemente complicado? Tengo más que decirle: bajo uno de los teclados, como Microsoft Pinyin, hay modos, que le permiten seleccionar un símbolo Unicode o un símbolo ASCII para comas, puntos y otras puntuaciones, mientras escribe chino. Sí, primero puedo escribir palabras chinas con。 ,、 por un tiempo, luego puedo cambiar el modo y desde entonces puedo escribir chino con., /
¿Qué? Estoy escribiendo inglés en chino IME? Sí, además del teclado estadounidense en chino IME, el teclado Microsoft Pinyin también tiene el modo de escribir solo en inglés. Así que si quiero escribir en inglés, puedo usar el inglés de EE. UU.
, o idioma chino teclado de Estados Unidos
, o idioma chino Microsoft Pinyin Keyboard con modo inglés
.
Mi respuesta
Lo que OP quiere explícitamente es cambiar el teclado, o incluso el modo bajo un teclado, en lugar de cambiar el idioma. La configuración regional se puede configurar de muchas maneras en Java para cambiar el idioma, pero no el teclado, ni los modos. ¿Qué sucede si deseo que mi aplicación Java Swing cambie al modo con el teclado chino ShuangPin, para la entrada de chino pero con puntuación en inglés?
Corríjame si me equivoco, pero NO hay forma de que Java seleccione un teclado nativo para un IME determinado o un modo. Aquí hay un artículo sobre el desarrollo de IME en Windows e incluso Mac. Espero que eso pueda explicar mucho.
http://blog.gatunka.com/2009/09/20/ime-basics-for-developers/
Pero si el OP solo quiere que el usuario escriba inglés para un campo de contraseña, entonces tiene muchas soluciones. Pero esto no es lo que dijo.