2014-11-01

複数行の文字列表示と StyledText

SWT の Text を、複数行にわたる文字列を表示するだけの用途に使おうとして、サンプルを作って確認をしました。以下のように Text の編集機能を無効にすればなんとかなると簡単に考えていたのすが…、ひとつ問題がありました。

List: SWTAppText.java
package text;

import org.eclipse.swt.SWT;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;

public class SWTAppText {
    Shell shell;

    public SWTAppText(Display display) {
        shell = new Shell(display);
        shell.setText("メッセージ");

        initUI();

        shell.setSize(200, 100);
        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }

    }

    public void initUI() {
        shell.setLayout(new GridLayout(1, true));

        Text text = new Text(shell, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY);
        text.setText("複数行の文字列を Text に表示するためだけのサンプルです。");
        text.setEditable(false); // READ_ONLY だけで十分かもしれないが、念の為
        
        GridData gd = new GridData();
        gd.horizontalAlignment = GridData.FILL;
        gd.verticalAlignment = GridData.FILL;
        gd.grabExcessHorizontalSpace = true;
        gd.grabExcessVerticalSpace = true;
        text.setLayoutData(gd);

    }

    public static void main(String[] args) {
        Display display = new Display();
        new SWTAppText(display);
        display.dispose();
    }
}

実行例

上の実行例のように、複数行にわたる文字列を表示する用途には使えるのですが、文字列の先頭に必ず「入力カーソル (Input Cursor)」が表示されていて、これを消すことができません。解決方法をインターネットで探しているうちに気が付きました。そもそも、文字れの先頭に表示されている入力用のカーソルを「入力カーソル (Input Cursor)」であると信じ込んでいたことが、解決に時間がかかってしまったことをです。「キャレット (Caret)」をキーワードにして探せば簡単に StyledText を使えば良いことに気付いたことでしょう。

「入力カーソル (Input Cursor)」は Tcl/Tk で使われている用語です(例えば [2])。昔、Tcl/Tk を IME などの日本語入力へ対応させることに取り組んでいて、Caret = 「漢字キーなどを押して(Caret の位置に)かな変換用ウィンドウを出すこと」にイメージが固まってしまっていて Caret というキーワードが出てきませんでした。

Text の代わりに StyledText を利用して Caret を非表示にしたサンプルを示します。

List: SWTAppStyledText.java
package styledtext;

import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.StyledText;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell;

public class SWTAppStyledText {
    Shell shell;

    public SWTAppStyledText(Display display) {
        shell = new Shell(display);
        shell.setText("メッセージ");

        initUI();

        shell.setSize(200, 100);
        shell.open();

        while (!shell.isDisposed()) {
            if (!display.readAndDispatch()) {
                display.sleep();
            }
        }

    }

    public void initUI() {
        shell.setLayout(new GridLayout(1, true));

        StyledText text = new StyledText(shell, SWT.MULTI | SWT.WRAP | SWT.READ_ONLY);
        text.setText("複数行の文字列を StyledText に表示するためだけのサンプルです。");
        text.setEditable(false);
        text.setCaret(null); 
        
        GridData gd = new GridData();
        gd.horizontalAlignment = GridData.FILL;
        gd.verticalAlignment = GridData.FILL;
        gd.grabExcessHorizontalSpace = true;
        gd.grabExcessVerticalSpace = true;
        text.setLayoutData(gd);

    }

    public static void main(String[] args) {
        Display display = new Display();
        new SWTAppStyledText(display);
        display.dispose();
    }
}

実行例

複数行にわたる文字列を表示するだけのことですが、Caret というキーワードを使わなかったために意外に解決に手こずってしまったので、自戒を込めて備忘録的に書留ました。

参考サイト

  1. Eclipse Community Forums: Standard Widget Toolkit (SWT) » how to remove blinking cursor in StyledText widget
  2. The Tk Text Widget | Linux Journal

0 件のコメント: