JTextPaneは、
複数行のテキスト(文字列)の編集を行うコンポーネント。
単なるテキストの編集を行うならJTextArea(一行ならJTextField)
を使えばよいが、文字毎に属性を変える(色を変えたりしたい)場合はJTextPaneを使う。
(JTextPaneは「Pane」という名前だが、ペイン(パネル・JPanel)というよりは、コンポーネントの方に近い感じがする)
|
|
import javax.swing.JTextPane; import javax.swing.text.BadLocationException; import javax.swing.text.Document; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants;
private JTextPane text = new JTextPane();
/** * JTextPaneに色付き文字列を追加する。 * * @param str 追加する文字列 * @param fg 文字列の色 */ public void append(String str, Color fg) { SimpleAttributeSet attr = new SimpleAttributeSet(); // attr.addAttribute(StyleConstants.Foreground, fg); StyleConstants.setForeground(attr, fg); Document doc = text.getDocument(); if (doc != null) { try { doc.insertString(doc.getLength(), str, attr); } catch (BadLocationException e) { } } }
テキストが増えた際にスクロールさせたい場合は、JScrollPaneと組み合わせる。
ただし、横スクロールは行われない。横幅より長い文字列は、右端で折り返される。
(JTextAreaはデフォルトで折り返しを行わない。setLineWrap()によって折り返すかどうか設定できるが、JTextPaneにはそういったメソッドは無い)
折り返しを行うかどうか判定するメソッドがあるので、それをオーバーライドしてやる。
(このメソッドはJEditorPaneのものなので、JEditorPaneでも同じだろうなのだろう)
private JTextPane text = new JTextPane() { @Override public boolean getScrollableTracksViewportWidth() { return false; // 折り返しを行わない } }; private JScrollPane scroll = new JScrollPane(text);
ただしこれだと、初期状態が変なことになる。
文字列が全く無い時や短い(右端に届いていない)時に、文字列がある位置までしか背景が白くならない(残りは灰色(スクロールエリアの背景色?))。
そこで、実際に表示したい範囲(テキスト)が右端に届いていない場合だけtrueを返してやるようにする。
(折り返し地点まで達していないのに「折り返し(true)」を返すのって、なんか変だけど…)
@Override public boolean getScrollableTracksViewportWidth() { Object parent = getParent(); if (parent instanceof JViewport) { JViewport port = (JViewport) parent; int w = port.getWidth(); // 表示できる範囲(上限) TextUI ui = getUI(); Dimension sz = ui.getPreferredSize(this); // 実際の文字列サイズ if (sz.width < w) { return true; } } return false; }