• 追加された行はこの色です。
  • 削除された行はこの色です。
TITLE:JTextPane、JLabelなどで複数行を表示
#navi(../)
*JLabel、JTextAreaなどで複数行を表示 [#k03fb08c]
Posted by [[terai]] at 2006-06-10

#contents

**概要 [#e9b92ec1]
JTextPane、JTextArea、JLabelを使った複数行のラベルをテストします。

-&jnlp;
-&jar;
-&zip;

#screenshot

**サンプルコード [#j2554de9]
#code{{
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);
  setPreferredSize(new Dimension(200, 200));
}
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;
}
}}

**解説 [#m912719c]
- 上:JTextPane
-- 文字色、背景色を変更し、編集不可、フォーカスの取得不可にしたJTextPaneを使用
-- \nを使って改行し複数行を表示
-- SimpleAttributeSetを使って、行間を詰めている

- 中:JTextArea
-- 文字色、背景色を変更し、編集不可、フォーカスの取得不可にしたJTextAreaを使用
-- \nを使って改行し複数行を表示

- 下:JLabel+html
-- JLabelの文字列にhtmlタグを使用
-- <br>タグを使って改行し複数行を表示

**参考リンク [#bcf44b9c]
-[[XP Style Icons - Windows Application Icon, Software XP Icons>http://www.icongalore.com/]]
--アイコンを利用しています。

**コメント [#h1e6b5a0]
- JDK 6 で、htmlタグを使ったJLabelでの複数行表示がすこし変更されているみたいです(Windows環境)。行間が詰まって見易くなっているようで、わざわざJTextPane+SimpleAttributeSetで行間を調節する必要もなさそうです。 -- [[terai]] &new{2007-01-10 (水) 12:44:53};
- label.setBackground(UIManager.getColor("Label.background"));((いつの間にか白になっていた))をlabel.setOpaque(false);に変更しました。 -- [[terai]] &new{2007-10-01 (月) 12:12:55};
- はじめまして。Java初心者なのですが、JLabelで英字フォントを指定するとギザギザで表示されるのですが、ギザギザをなくすにはどうしたらよいでしょうか?ネットで探すと「setRenderingHint」を使うとできると出てはくるのですが、JLabelを使った場合の例が出てこなくて。。。ご教授よろしくお願いします。 -- [[ばしばし]] &new{2007-10-17 (水) 20:16:10};
-- こんばんは。[[「Java SE 6完全攻略」第17回 文字に対するアンチエイリアス:ITpro>http://itpro.nikkeibp.co.jp/article/COLUMN/20070205/260649/]]にいろんな環境での方法がまとめられています。自宅の環境(Windows XP + java1.6.0_03)では、以下のようにオプションを設定して起動するとアンチエイリアスが掛かるようです(XPの画面のプロパティ、デザイン、効果をClearTypeに変更してもなぜかうまくいかない…)。 -- [[terai]] &new{2007-10-17 (水) 21:54:38};
 java -Dawt.useSystemAAFontSettings=on -cp ".\target\classes" example.MainPanel
- ありがとうございます。なるほど、いろいろ書かれていますね!明日試してみます! -- [[ばしばし]] &new{2007-10-17 (水) 23:59:34};
- こんにちは。当方の環境がJDK1.5であったので、非標準の「-Dswing.aatext=true」を設定するとアンチエイリアスがかかりました。けれども、標準ではどうするのかと言う疑問が。。。 -- [[ばしばし]] &new{2007-10-18 (木) 09:37:28};
-- ども。Sunに「1.5にも標準のオプション用意して」とお願いする…のはひとまず置いといて…。「Java Swing Hacks」本では、テキストにアンチエイリアスを適用するためだけのLook & Feel([[Wrap Look And Feel - L2FProd.com>http://wraplf.l2fprod.com/]])を使用する方法が紹介(HACK#52)されています。これを使えば、「-Dswing.aatext=true」無しで、1.5でもアンチエイリアスが掛かります。 -- [[terai]] &new{2007-10-18 (木) 14:42:33};
-- もし、一部のJLabelをアンチエイリアスするだけでいいのなら、以下のようにJLabel#paintComponentメソッドをオーバーライドしてしまうのが手っ取り早いかもしれません。 -- [[terai]] &new{2007-10-18 (木) 15:16:04};
#code{{
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。試してみます!ありがとうございます! -- [[ばしばし]] &new{2007-10-22 (月) 09:57:29};
- JLabelでhtmlを使用するとsetEnabled(false)でグレーアウトしてくれないです。どうしたものでしょう。 -- [[ApplePedlar]] &new{2007-12-11 (火) 17:34:00};
-- [[Bug ID: 4740519 HTML JLabel not greyed out on setEnabled(false)>http://bugs.sun.com/view_bug.do?bug_id=4740519]]ですね。今のところ、[[Swing - JLabel with html tag can not be disabled or setForegroud?!>http://forums.sun.com/thread.jspa?threadID=735190]]みたいに%%逃げるしかない?みたいです。%% する方法があります。 -- [[terai]] &new{2007-12-11 (火) 18:27:05};
-- コードが長くなってしまったので、別ページを作成しました。JEditorPaneを使用する方法も追加しています。[[Htmlを使ったJLabelとJEditorPaneの無効化>Swing/DisabledHtmlLabel]] -- [[terai]] &new{2007-12-24 (月) 23:24:50};
- こんにちは。ココのおかげでとても助かっています。ところで、1行の高さ(文字の高さを含めた高さ)を指定したい、というときには、setLineSpacingではダメってことですよね?「指定したい高さ-フォントの大きさ」をsetLineSpacingで指定してあげなきゃいけないんですよね?(文字サイズによって1行の高さが揃わなくなるのはイヤで揃えたいなと思うのですが、フォントによってそれだと、そうすると、フォントの大きさを変えるたびに指定しなおさなきゃいけないってことですよね。面倒…) -- [[びびあず]] &new{2008-10-31 (金) 10:42:47};
-- こんにちは。どういたしまして。LineSpacingはフォントサイズに依存するみたいですね。固定の間隔を指定するのなら、例えば以下のように、ParagraphView#getBottomInsetメソッドなどをオーバーライドするのが簡単かも。 -- [[terai]] &new{2008-10-31 (金) 14:36:51};
#code{{
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.text.*;
public class MainPanel extends JPanel{
  private final JTextPane editor = new JTextPane();
  public MainPanel() {
    super(new BorderLayout());
    editor.setEditorKit(new MyEditorKit());
//     SimpleAttributeSet a = new SimpleAttributeSet(); 
//     StyleConstants.setLineSpacing(a, 1.0f);
//     editor.setParagraphAttributes(a, true);
    editor.setText("12341234\nasdf_fASdfasf_fasdf_affffFSDdfasdf\nasdfasFasdf");
    SimpleAttributeSet attr = new SimpleAttributeSet();
    StyleConstants.setFontSize(attr, 32);
    try{
      Document doc = editor.getDocument();
      doc.insertString(doc.getLength(), "12341234\nasdfasdf", attr);
      editor.setCaretPosition(doc.getLength());
    }catch(BadLocationException e) {}
    add(new JScrollPane(editor));
    setPreferredSize(new Dimension(320, 240));
  }
  public static void main(String[] args) {
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        createAndShowGUI();
      }
    });
  }
  public static void createAndShowGUI() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    frame.getContentPane().add(new MainPanel());
    frame.pack();
    frame.setLocationRelativeTo(null);
    frame.setVisible(true);
  }
}
class MyEditorKit extends StyledEditorKit {
  @Override public ViewFactory getViewFactory() {
    return new MyViewFactory();
  }
}
class MyViewFactory implements ViewFactory {
  @Override public View create(Element elem) {
    String kind = elem.getName();
    if(kind!=null) {
      if(kind.equals(AbstractDocument.ContentElementName)) {
        return new LabelView(elem);
      }else if(kind.equals(AbstractDocument.ParagraphElementName)) {
        return new ParagraphView(elem) {
          @Override protected short getBottomInset() {
            return 5;
          }
        };
      }else if(kind.equals(AbstractDocument.SectionElementName)) {
        return new BoxView(elem, View.Y_AXIS);
      }else if(kind.equals(StyleConstants.ComponentElementName)) {
        return new ComponentView(elem);
      }else if(kind.equals(StyleConstants.IconElementName)) {
        return new IconView(elem);
      }
    }
    return new LabelView(elem);
  }
}
}}
- (変な日本語を書いてましたね、失礼しました。) ところで…、さっそくご親切にソースまで書いて教えていただけて嬉しいです。ありがとうございました。これを参考にして、また勉強したいと思います。本当にありがとうございました。 -- [[びびあず]] &new{2008-11-07 (金) 14:22:27};
- Swing初心者です。JTextPaneでの複数行表示、大変参考になりました。複数行表示自体はおかげ様でうまくいったのですが、ボーダーが思い通りにならず困っています。TitledBorderを設定しているのですが、タイトルを囲む線の外側(コンポーネントの枠)がくぼんだ状態になってしまいます。外枠は表示させたくないのですが、どこかでOFFできるのでしょうか。ご教授いただければ幸いです。 -- [[ka-ka]] &new{2008-12-25 (木) 00:03:08};

#comment