TITLE:JTextPaneを一行に制限してスタイル可能なJTextFieldとして使用する

Posted by at 2013-05-06

JTextPaneを一行に制限してスタイル可能なJTextFieldとして使用する

`JTextPaneの行数を一行のみに制限して、文字色などのスタイル付けが可能なJTextField`として使用します。

  • &jnlp;
  • &jar;
  • &zip;
OneLineTextPane.png

サンプルコード

JTextPane textPane = new JTextPane() {
  @Override public void scrollRectToVisible(Rectangle rect) {
    int r = getBorder().getBorderInsets(this).right;
    rect.grow(r, 0);
    super.scrollRectToVisible(rect);
  }
};
textPane.setEditorKit(new NoWrapEditorKit());
AbstractDocument doc = new SimpleSyntaxDocument();
textPane.setDocument(doc);
try {
  doc.insertString(0, text, null);
} catch(Exception ex) {
  ex.printStackTrace();
}
InputMap im = textPane.getInputMap(JComponent.WHEN_FOCUSED);
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0), new AbstractAction() {
  @Override public void actionPerformed(ActionEvent e) {
    // Do nothing
  }
});
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0), new AbstractAction() {
  @Override public void actionPerformed(ActionEvent e) {
    // Do nothing
  }
});

// @see http://terai.xrea.jp/Swing/FocusTraversalKeys.html
Set<AWTKeyStroke> forwardKeys = new HashSet<AWTKeyStroke>(
    textPane.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS));
forwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
forwardKeys.add(KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.SHIFT_MASK));
textPane.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, forwardKeys);

JScrollPane scrollPane = new JScrollPane(
    textPane, ScrollPaneConstants.VERTICAL_SCROLLBAR_NEVER,
              ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER) {
  @Override public Dimension getMinimumSize() {
    return super.getPreferredSize();
  }
};
View in GitHub: Java, Kotlin

解説

  • `JScrollPane`に追加
    • `JScrollBarを常に非表示にした、JScrollPaneJTextPane`を追加
  • JTextPaneの折り返しを無効化
  • 文字列の最後にある`Caret`が表示されないのを修正
    • `JTextPane#scrollRectToVisible(Rectangle)`をオーバーライドして、余白までスクロールするように設定
    • メモ: No Wrap Text Pane ≪ Java Tips Weblogのように、`CaretListener`を使用する方法もある
  • 改行キーの無効化
    • `JTextPaneからInputMapを取得して、KeyEvent.VK_ENTERをなにもしないAction`で置き換える
    • `Document#insertString(...)`をオーバーライドして、コピー・ペーストなどで張り込まれた文字列から、改行を空白に置換
  • タブキーでフォーカス移動
  • 文字スタイルの変更

参考リンク

コメント

  • `JTextFieldでは、aaaaa|bbbbbでカーソル|の位置に文字を追加していくと領域外にカーソルが移動した時点でbbbbbが表示されるようにスクロールするが、ここのOneLineTextPane`では未対応。 -- aterai