TITLE:JTextPane、JLabelなどで複数行を表示

Posted by at 2006-06-12

JLabel、JTextAreaなどで複数行を表示

`JTextPaneJTextAreaJLabel`を使った複数行のラベルをテストします。

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

サンプルコード

private final JTextPane label1 = new JTextPane();
private final JTextArea label2 = new JTextArea();
private final JLabel    label3 = new JLabel();
public MainPanel() {
  super(new GridLayout(3,1));
  ImageIcon icon = new ImageIcon(getClass().getResource("wi0124-32.png"));

  SimpleAttributeSet attr = new SimpleAttributeSet();
  StyleConstants.setLineSpacing(attr, -0.2f);
  label1.setParagraphAttributes(attr, true);

  label1.setText("JTextPane\nasdfasdf");
  label2.setText("JTextArea\nasdfasdf");
  label3.setText("<html>JLabel+html<br>asdfasdf");
  label3.setIcon(icon);

  add(setLeftIcon(label1, icon));
  add(setLeftIcon(label2, icon));
  add(label3);

  setBorder(BorderFactory.createEmptyBorder(8,8,8,8));
  setPreferredSize(new Dimension(320, 160));
}
private static Box setLeftIcon(JTextComponent label, ImageIcon icon) {
  label.setForeground(UIManager.getColor("Label.foreground"));
  //label.setBackground(UIManager.getColor("Label.background"));
  label.setOpaque(false);
  label.setEditable(false);
  label.setFocusable(false);
  label.setMaximumSize(label.getPreferredSize());
  label.setMinimumSize(label.getPreferredSize());

  JLabel l = new JLabel(icon);
  l.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
  Box box = Box.createHorizontalBox();
  box.add(l);
  box.add(Box.createHorizontalStrut(2));
  box.add(label);
  box.add(Box.createHorizontalGlue());
  return box;
}
View in GitHub: Java, Kotlin

解説

  • 上:`JTextPane`
    • 文字色、背景色を変更し、編集不可、フォーカスの取得不可にした`JTextPane`を使用
    • `\n`を使って改行し複数行を表示
    • `SimpleAttributeSet`を使って、行間を詰めている
  • 中:`JTextArea`
    • 文字色、背景色を変更し、編集不可、フォーカスの取得不可にした`JTextArea`を使用
    • `\n`を使って改行し複数行を表示
  • 下:`JLabel+html`
    • `JLabelの文字列にhtml`タグを使用
    • `<br>`タグを使って改行し複数行を表示

参考リンク

コメント

  • `JDK 6で、htmlタグを使ったJLabelでの複数行表示がすこし変更(それとも自分の環境のフォントなどが変わっただけ?)されている?ようです(Windows環境)。行間が詰まって見易くなっているようで、わざわざJTextPane+SimpleAttributeSet`で行間を調節する必要もなさそうです。 -- aterai
  • `label.setBackground(UIManager.getColor("Label.background"));(いつの間にか白になっていた)をlabel.setOpaque(false);`に変更しました。 -- aterai
  • はじめまして。`Java初心者なのですが、JLabelで英字フォントを指定するとギザギザで表示されるのですが、ギザギザをなくすにはどうしたらよいでしょうか?ネットで探すとsetRenderingHintを使うとできると出てはくるのですが、JLabel`を使った場合の例が出てこなくて。。。ご教授よろしくお願いします。 -- ばしばし
    • こんばんは。「Java SE 6完全攻略」第17回 文字に対するアンチエイリアス:ITproにいろんな環境での方法がまとめられています。自宅の環境(`Windows XP + java1.6.0_03)では、以下のようにオプションを設定して起動するとアンチエイリアスが掛かるようです(XPの画面のプロパティ、デザイン、効果をClearType`に変更してもなぜかうまくいかない…)。 -- aterai
java -Dawt.useSystemAAFontSettings=on -cp ".\target\classes" example.MainPanel
  • ありがとうございます。なるほど、いろいろ書かれていますね!明日試してみます! -- ばしばし
  • こんにちは。当方の環境が`JDK1.5であったので、非標準の-Dswing.aatext=true`を設定するとアンチエイリアスがかかりました。けれども、標準ではどうするのかと言う疑問が。。。 -- ばしばし
    • ども。Sunに「`1.5にも標準のオプション用意して」とお願いする…のはひとまず置いといて…。Java Swing Hacks本では、テキストにアンチエイリアスを適用するためだけのLook & Feel(Wrap Look And Feel - L2FProd.com)を使用する方法が紹介(HACK#52)されています。これを使えば、-Dswing.aatext=true無しで、1.5`でもアンチエイリアスが掛かります。 -- aterai
    • もし、一部の`JLabelをアンチエイリアスするだけでいいのなら、以下のようにJLabel#paintComponent`メソッドをオーバーライドしてしまうのが手っ取り早いかもしれません。 -- aterai
JLabel label = new JLabel("asdfasdfasdf") {
  @Override protected void paintComponent(Graphics g) {
    Graphics2D g2d = (Graphics2D)g;
    g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
                         RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
    g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
                         RenderingHints.VALUE_RENDER_QUALITY);
    super.paintComponent(g2d);
  }
};
  • お返事遅くなりましたm(__)m。試してみます!ありがとうございます! -- ばしばし
  • `JLabelhtmlを使用するとsetEnabled(false)`でグレーアウトしてくれないです。どうしたものでしょう。 -- ApplePedlar
  • こんにちは。ココのおかげでとても助かっています。ところで、`1行の高さ(文字の高さを含めた高さ)を指定したい、というときには、setLineSpacingではダメってことですよね?「指定したい高さ-フォントの大きさ」をsetLineSpacingで指定してあげなきゃいけないんですよね?(文字サイズによって1`行の高さが揃わなくなるのはイヤで揃えたいなと思うのですが、フォントによってそれだと、そうすると、フォントの大きさを変えるたびに指定しなおさなきゃいけないってことですよね。面倒…) -- びびあず
    • こんにちは。どういたしまして。`LineSpacingはフォントサイズに依存するみたいですね。固定の間隔を指定するのなら、例えば以下のように、ParagraphView#getBottomInset`メソッドなどをオーバーライドするのが簡単かも。 -- aterai
    • ソースコードをJEditorPaneやJTextPaneに行間を設定するに移動しました。
  • (変な日本語を書いてましたね、失礼しました。) ところで…、さっそくご親切にソースまで書いて教えていただけて嬉しいです。ありがとうございました。これを参考にして、また勉強したいと思います。本当にありがとうございました。 -- びびあず
  • `Swing初心者です。JTextPaneでの複数行表示、大変参考になりました。複数行表示自体はおかげ様でうまくいったのですが、ボーダーが思い通りにならず困っています。TitledBorderを設定しているのですが、タイトルを囲む線の外側(コンポーネントの枠)がくぼんだ状態になってしまいます。外枠は表示させたくないのですが、どこかでOFF`できるのでしょうか。ご教授いただければ幸いです。 -- ka-ka
    • こんばんは。`TitledBorderの枠線を変更する場合は、label.setBorder(BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), "title"));のように、他のBorder(この場合、EmptyBorder`で非表示にしている)と組み合わせて使用します。TitledBorder (Java Platform SE 6) -- aterai
  • ありがとうございます。`NetBeansで開発しているのですが、あ~でもないこ~でもないとプロパティ画面をいじっていたら、JScrollPaneJTextPaneの組み合わせで思い描いたものはできました。SwingNetBeans`も初めてなので色々と思い通りにできずに四苦八苦しております。。。今後ともこちらのサイトで勉強させていただきます! -- ka-ka