JTable/セルに複数行の文字列を表示する

JTableの各セルに複数行の文字列を表示する方法です。

Java Web Start(要JRE5.0以上)

どうやってやる

JTableのセルのデフォルトレンダラであるDefaultTableCellRendererは,JLabelのサブクラスであるため,複数行の文字列を表示できません(改行できません)。

複数行の文字列を表示したい場合,改行できるJTextAreaのサブクラスとしてカスタムのTableCellRendererを作ります。

この場合,一からレンダラを作ることになるのですが,DefaultTableCellRendererのソースを参考にして(必要機能に絞って)作ると,簡単です。

ソースコード

 class MultiLineCellRenderer extends JTextArea implements TableCellRenderer {
     // フォーカスを持っていない場合のボーダーはDefaultTableCellRendererで
     // 定義しているので,ここでも同様にします。
     protected static Border noFocusBorder = new EmptyBorder(1, 1, 1, 1);
 
     public MultiLineCellRenderer() {
         setLineWrap(true);
         setWrapStyleWord(true);
         setOpaque(true);
     }
 
     // ここも基本的にDefaultTableCellRendererのパ○リです。
     public Component getTableCellRendererComponent(JTable table, Object value,
             boolean isSelected, boolean hasFocus, int row, int column) {
         if (isSelected) {
             super.setForeground(table.getSelectionForeground());
             super.setBackground(table.getSelectionBackground());
         } else {
             super.setForeground(table.getForeground());
             super.setBackground(table.getBackground());
         }
 
         setFont(table.getFont());
 
         if (hasFocus) {
             setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
         } else {
             setBorder(noFocusBorder);
         }
 
         setText((value == null) ? "" : value.toString());
 
         return this;
     }
 }
 
 public class MultiLineCellRendererTest extends JFrame {
 
     private JComponent createComponent() {
         JTable tb = new JTable(
                 new Object[][] { { 
                     "MultiLine\nTableCellRenderer",    "複数行の\nレンダラです。", "", "", "", "" },
                     { "", "", "ぐいJava\nWorks", "", "", "" } },
                 new Object[] { "A", "B", "C", "D", "E", "F" }) {
         };
         tb.setDefaultRenderer(Object.class, new MultiLineCellRenderer());
         tb.setRowSelectionAllowed(false);
         tb.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
 
         // とりあえず固定で高さを設定する。
         tb.setRowHeight(35);
         // JTableのセルを変種不可にする場合は,DefaultEditorにnullを設定する。
         tb.setDefaultEditor(Object.class, null);
         return new JScrollPane(tb);
 
     }
 
     private MultiLineCellRendererTest() {
         super("MultiLineCellRendererTest");
         setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
 
         add(createComponent());
         setSize(300, 150);
         setVisible(true);
     }
 
     public static void main(String[] args) {
         new MultiLineCellRendererTest();
     }
 }
 

まとめ

カスタムレンダラを作成する場合は,適当なJTextComponentやJComponentを継承して,DefaultTableCellRendererのソースを参考に実装するパターンが使えます。

ただ,本格的に汎用的に作ろうと,もっといろいろ考える必要があります。(必ずしも汎用的である必要はないですが。)

上の例ではセルの高さの指定をアプリ側でやっていますが,実アプリでは,セルの内容から必要な高さを,行毎に算出するようにする必要があると思います。

また,編集機能も場合によっては必要でしょうが,これはこれでいろいろ必要そうです。


last update:2007-02-01 08:53:27

新規 編集 検索 一覧 ヘルプ