6

I'm working on a Java application for people learning German, and I have run into a problem with the special characters of this language. I want to make a subclass of JTextField that will interpret ALT + a as ä, ALT + o as ö and so on, while behaving as usual for all ASCII characters.

My attempts so far:

public class GermanTextField extends JTextField implements KeyListener{
  public GermanTextField() {
    init();
  }
   
  // other constructors ...
  
  private void init() {
    addKeyListener(this);
  }

  
  
  public void keyPressed(KeyEvent arg0) {}


  public void keyReleased(KeyEvent arg0) {}


  public void keyTyped(KeyEvent evt) {
    if(evt.getKeyChar() == 'o' && evt.isAltGraphDown()){
      setText(getText() + "ö");
      evt.consume();
    }
  }


}

Code above does not work (GermanTextField behaves like standard JTextField), and when I print evt.getKeyChar() to console this is what I get:

?
?
?
?

This may be due to my own language, because ALT + o produces ó on my system. Of course I could have done it like that:

  public void keyTyped(KeyEvent evt) {
    if(evt.getKeyChar() == 'ó'){
      setText(getText() + "ö");
      evt.consume();
    }
  }

But it probably won't work on any systems other than Polish.

My question is: is there any solution to this problem that will behave as expected on systems with different language settings?


Full solution to this problem, based on MvGs answer:

package daswort.gui;

import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.HashMap;
import java.util.Map;

import javax.swing.JTextField;

public class GermanTextField extends JTextField implements KeyListener{
  
  private Map<Integer, String> transform = 
      new HashMap<Integer, String>();
  
  public GermanTextField() {
    init();
  }


  public GermanTextField(int columns) {
    super(columns);
    init();
  }


  public GermanTextField(String text, int columns) {
    super(text, columns);
    init();
  }


  public GermanTextField(String text) {
    super(text);
    init();
  }

  
  private void init() {
    transform.put(KeyEvent.VK_A, "äÄ");
    transform.put(KeyEvent.VK_U, "üÜ");
    transform.put(KeyEvent.VK_O, "öÖ");
    
    addKeyListener(this);
  }

  
  
  public void keyPressed(KeyEvent evt) {
    if(evt.isAltGraphDown()){
      String umlaut = transform.get(evt.getKeyCode());
      if(umlaut != null){
        int idx = evt.isShiftDown() ? 1 : 0;
        setText(getText() + umlaut.charAt(idx));
      }
    }
  }

  public void keyReleased(KeyEvent arg0) {}


  public void keyTyped(KeyEvent evt) {
    if(evt.isAltGraphDown()){
      evt.consume();
    }
  }


}
4

3 回答 3

6

要识别独立于当前语言环境的关键事件,请不要使用getKeyChar. 相反,用于isKeyCode()标识独立于与其关联的字符的键。像这样:

if (evt.getKeyCode() == KeyEvent.VK_O && evt.isAltGraphDown())

这应该与任何键盘布局上的Alt Gr+匹配。O

于 2012-09-13T23:55:51.580 回答
1

这可能是由于我自己的语言,因为 ALT + o 在我的系统上产生ó。当然我可以这样做:

JTextComponents使用DocumentFilter

但它可能不适用于除波兰语之外的任何系统。

我的问题是:这个问题是否有任何解决方案可以在具有不同语言设置的系统上按预期运行?

  • 不,没有,

  • 希望所有 PC 都为Localein Native OS(错误的决定)估算了正确的值

  • 您可以Unicode Chars使用ALT和编写任何内容numbers

  • 最安全的只是用户操作关于 的设置Locale,然后您可以为具体Locale(自己的Encode Page)创建一个字符数组

于 2012-09-14T00:17:08.693 回答
0

问题是 JTextField 使用与 JTextArea 不同的默认字体。在我编写的必须支持多语言的应用程序中,我遇到了同样的问题。

出现问题的原因是 JTextField 通常用于显示等宽字体,例如 Courier New。通常,Java 不包含用于显示 Kanji 的等宽图形字体的额外映射。

您的修复工作有效,因为没有名为“123”的字体,因此采用默认值(对话框)。“对话框”字体在内部映射到您平台的 font.properties 文件中的字体系列。这将与 JTextField 使用的字体相同。

我有以下修复,以确保在所有图形组件中使用相同的字体定义。您还可以找到 JTextField 的特定键并进行更改。这样您就不必担心任何组件的字体,它们将通过对话框进行初始化。请在包含 JTextField 的类中输入以下代码。

Object fontDefinition = new UIDefaults.ProxyLazyValue("javax.swing.plaf.FontUIResource", null, new Obje

java.util.Enumeration keys = UIManager.getDefaults().keys();
while (keys.hasMoreElements()) {
    Object key = keys.nextElement();
    Object value = UIManager.get(key);
    if (value instanceof javax.swing.plaf.FontUIResource) {
        UIManager.put(key, fontDefinition);
    }
}

希望这可以帮助。

于 2012-09-13T23:13:16.283 回答