0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

swingにおける日本語入力時にUIが崩れる不具合と解決方法

Last updated at Posted at 2020-09-21

はじめに

ここ最近、swing関連のバグ?に悩まされていました。

1.png

例えば、このようにJTextFieldやJTextAreaなどのJTextComponent系コンポーネントを用意したとします。
半角英数字を入力する分には特に変わりはないのですが、日本語入力をした途端に、

2.png
$\Huge{な~ん~な~ん~す~か~こ~れ}$

バグにも程があります。

ググってみるとInputMethodListenerを用いてウィンドウのrepaint()を叩き続ければ良いという解決法を見つけたので、フレームを最小化していない間はコンポーネントへの全角文字入力以降にwhileでフレームのrepaint()を叩き続けるためのバグ修正用クラスを用意。

バグ修正用クラス
final class SwingPaintBugFix extends Thread {
    private Window w;
    private boolean running = true;

    private static SwingPaintBugFix bugfix = new SwingPaintBugFix();

    private SwingPaintBugFix() {}

    private SwingPaintBugFix(Window w) {
        this.w = w;
    }

    public static void of(JTextComponent txtComp, Window w) {
        w.addWindowListener(new WindowAdapter() {
            @Override public void windowIconified(WindowEvent e) {
                bugfix.stopRunning();
            }
            @Override public void windowDeiconified(WindowEvent e) {
                bugfix = new SwingPaintBugFix(w);
                bugfix.start();
            }
        });
        txtComp.addInputMethodListener(new InputMethodListener() {
            @Override public void inputMethodTextChanged(InputMethodEvent e) {
                // 全角文字を受け取る
                bugfix.stopRunning();
                bugfix = new SwingPaintBugFix(w);
                bugfix.start();
            }
            @Override public void caretPositionChanged(InputMethodEvent e) {}
        });
        txtComp.addKeyListener(new KeyAdapter() {
            // 半角文字を受け取る
            @Override public void keyTyped(KeyEvent e) {}
        });
    }

    @Override public void start() {
        new Thread(this).start();
    }

    @Override public void run() {
        while (running) {
            ((Component) w).repaint();
        }
    }

    private void stopRunning() {
        running = false;
    }
}

しかしながら、常にwhileで処理を実行し続けるという行為に抵抗感が否めず、すべてのJTextComponent系コンポーネントにバグ修正用クラスを適用するのも手間がかかるため、抜本的な解決策を探ることとしました。

原因究明

とりあえず数回再起動しても治らず。

Windows Updateで不具合がでないかどうか確認しながら最新版に更新しても駄目。

「あーめんど」と思いながらも、仕方がないのでセーフモードに。セーフモードでは先程のバグが発生しないことを確認したので、「バッググラウンドプロセス」と「サービス」を控えて通常起動に戻す。

「これでもない、これでもない・・・」と、タスクマネージャーからセーフモード以外のタスクを一つづつ終了させ、ついに原因を特定!

3.png

「Nahimic Service」というサウンドユーティリティが犯人だったようです。こいつを試しに停止させてみたら見事にバグが直りました。ググってみると、こいつはUI関連以外にもいろいろと競合を起こしているようです。

・・・これならバグ修正クラスなんて作る意味なかったじゃんか。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?