- - PR -
VISTAでsetCharacterSubsetsメソッドによるIMEモード変更が行われません
1
投稿者 | 投稿内容 |
---|---|
|
投稿日時: 2008-03-19 11:41
いつもお世話様になっております。
質問させていただきたく思います。 setCharacterSubsets(・・・)を使用し あるテキストフィールドにはひらがな入力、 あるテキストフィールドには半角カタカナ入力という入力制御を 行いたいと思っています。 しかし、あるフレームから新しいダイアログを表示したとき、 そのダイアログのテキストフィールドの入力制御が行われません。 なぜか、もとのフレームにおけるIMEの状態が ダイアログでも保持されていて(?) 行っているはずの入力制御がきいていません。 この問題は、 XP(jre1.4.1_05-b01)だと発生せず、 VISTA(jre1.6.0_03-b05)だと発生します。 この問題について何かご存知の方がいらっしゃいましたら、 教えていただけますでしょうか。 よろしくお願い致します。 また、以下が現象を確認できるソースコードになります。 TestTextFieldというJTextFieldを継承したコンポーネントを使用し、 その使用元でTestTextFieldインスタンスにsetImeMode(入力モード)をすることで IMEの制御を行っています。 問題が再現するテキストフィールドは、 testDialogクラスで使用されている「tfFalfLatinDigit」です。 IMEがONの状態でtestDialogを表示すると、 「tfFalfLatinDigit」はフォーカスが当たった際に直接入力モードになるはずが ひらがな入力モードのままとなってしまいます。 ===テストアプリケーションクラス============================================= package testime; import java.awt.Toolkit; import javax.swing.SwingUtilities; import javax.swing.UIManager; import java.awt.Dimension; public class TestApplication { boolean packFrame = false; /** * アプリケーションの構築と表示。 */ public TestApplication() { testFrame frame = new testFrame(); // validate() はサイズを調整する // pack() は有効なサイズ情報をレイアウトなどから取得する if (packFrame) { frame.pack(); } else { frame.validate(); } // ウィンドウを中央に配置 Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); Dimension frameSize = frame.getSize(); if (frameSize.height > screenSize.height) { frameSize.height = screenSize.height; } if (frameSize.width > screenSize.width) { frameSize.width = screenSize.width; } frame.setLocation((screenSize.width - frameSize.width) / 2, (screenSize.height - frameSize.height) / 2); frame.setVisible(true); } /** * アプリケーションエントリポイント。 * * @param args String[] */ public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { try { UIManager.setLookAndFeel(UIManager. getSystemLookAndFeelClassName()); } catch (Exception exception) { exception.printStackTrace(); } new TestApplication(); } }); } } ===始めに表示するフレーム=================================================== package testime; import java.awt.Dimension; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.*; import testime.component.TestTextField; public class testFrame extends JFrame { JPanel contentPane; JButton jButton1 = new JButton(); TestTextField jTextField = new TestTextField(); JLabel jLabel1 = new JLabel(); public testFrame() { try { setDefaultCloseOperation(EXIT_ON_CLOSE); jbInit(); } catch (Exception exception) { exception.printStackTrace(); } } /** * コンポーネントの初期化。 * @throws java.lang.Exception */ private void jbInit() throws Exception { contentPane = (JPanel) getContentPane(); contentPane.setLayout(null); setSize(new Dimension(400, 300)); setTitle("テストフレーム"); jButton1.setBounds(new Rectangle(106, 184, 193, 48)); jButton1.setText("ダイアログを表示"); jButton1.addActionListener(new testFrame_jButton1_actionAdapter(this)); jTextField.setBounds(new Rectangle(107, 119, 195, 37)); jTextField.setImeMode(TestTextField.MODE_WIDE_HIRAGANA); jLabel1.setText("↓ここでひらがな入力モードに変更する"); jLabel1.setBounds(new Rectangle(110, 84, 198, 27)); contentPane.add(jButton1); contentPane.add(jTextField); contentPane.add(jLabel1); } public void jButton1_actionPerformed(ActionEvent e) { testDialog testDialog = new testDialog(); testDialog.setSize(400,300); testDialog.show(); } } class testFrame_jButton1_actionAdapter implements ActionListener { private testFrame adaptee; testFrame_jButton1_actionAdapter(testFrame adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.jButton1_actionPerformed(e); } } ===問題が発生するダイアログ============================================= package testime; import java.awt.*; import java.awt.event.*; import javax.swing.*; import testime.component.*; public class testDialog extends JDialog { JPanel panel1 = new JPanel(); //半角英数用テキストフィールド TestTextField tfFalfLatinDigit = new TestTextField(); //IMEオフ(直接入力固定)用テキストフィールド TestTextField tfWideHiragana = new TestTextField(); //戻るボタン JButton btnHide = new JButton(); JLabel jLabel1 = new JLabel(); JLabel jLabel2 = new JLabel(); public testDialog(Frame owner, String title, boolean modal) { super(owner, title, modal); try { setDefaultCloseOperation(DISPOSE_ON_CLOSE); jbInit(); pack(); } catch (Exception exception) { exception.printStackTrace(); } } public testDialog() { this(new Frame(), "testDialog", false); } private void jbInit() throws Exception { panel1.setLayout(null); tfFalfLatinDigit.setBounds(new Rectangle(19, 39, 182, 32)); //半角英数入力を指定 tfFalfLatinDigit.setImeMode(TestTextField.MODE_HALF_LATIN_DIGIT); tfWideHiragana.setBounds(new Rectangle(19, 124, 183, 33)); //ひらがな入力モードを指定 tfWideHiragana.setImeMode(TestTextField.MODE_WIDE_HIRAGANA); btnHide.setBounds(new Rectangle(257, 119, 108, 38)); btnHide.setText("戻る"); btnHide.addActionListener(new testDialog_btnHide_actionAdapter(this)); jLabel1.setText("半角英数(ひらがな入力モードへの切り替え可)"); jLabel1.setBounds(new Rectangle(20, 11, 173, 23)); jLabel2.setText("ひらがな"); jLabel2.setBounds(new Rectangle(24, 92, 174, 28)); panel1.add(tfFalfLatinDigit); panel1.add(tfWideHiragana); panel1.add(btnHide); panel1.add(jLabel1); panel1.add(jLabel2); getContentPane().add(panel1); } public void btnHide_actionPerformed(ActionEvent e) { this.hide(); } } class testDialog_btnHide_actionAdapter implements ActionListener { private testDialog adaptee; testDialog_btnHide_actionAdapter(testDialog adaptee) { this.adaptee = adaptee; } public void actionPerformed(ActionEvent e) { adaptee.btnHide_actionPerformed(e); } } ===IME制御を内部的に行うテキストフィールド========================================= package testime.component; import java.awt.TextField; import java.awt.event.FocusEvent; import java.awt.event.FocusListener; import java.awt.im.InputContext; import java.awt.im.InputSubset; public class TestTextField extends TextField { public static final int MODE_HALF_LATIN_DIGIT = 1; //半角英数モード public static final int MODE_WIDE_HIRAGANA = 2;//ひらがなモード public int imeMode = -1; public TestTextField() { super(); super.addFocusListener(new TextFieldListener(this)); } public void setImeMode(int imeMode) { switch (imeMode) { case MODE_HALF_LATIN_DIGIT: //半角英数 enableInputMethods(true); break; case MODE_WIDE_HIRAGANA: //ひらがな enableInputMethods(true); break; default: System.out.println("不正なパラメータです"); } int oldImeMode = this.imeMode; this.imeMode = imeMode; firePropertyChange("imeMode", oldImeMode, imeMode); } public final class TextFieldListener implements FocusListener { /** キーボードフォーカスイベントを受け取るテキストフィールド */ private TestTextField textField; public TextFieldListener(TestTextField txtFld) { textField = txtFld; } public void focusGained(FocusEvent fEvent) { switch (textField.imeMode) { case MODE_HALF_LATIN_DIGIT: //半角英数 textField.setCharacterSubsets(new Character. Subset[] {InputSubset.LATIN_DIGITS}); break; case MODE_WIDE_HIRAGANA: //ひらがな textField.setCharacterSubsets(new Character. Subset[] {InputSubset.KANJI}); break; default: break; } } public void focusLost(FocusEvent fEvent) { } } public void setCharacterSubsets(Character.Subset[] subsets) { InputContext input = this.getInputContext(); if (input != null) { input.setCharacterSubsets(subsets); } } } 以上がソースになります。 長文になってしまい申し訳ありませんが よろしくお願い致します。 |
1