tags:

views:

26

answers:

1

Hello,

I have a JTable instance, containing a number of rows. The columns in this table are JLabel instances containing an HTML-formatted string.

One of my requirements is that all the data in these columns should be displayed. If the column width (for whatever reason) is not wide enough to display all the data, the text should wrap onto the next line. Currently the text is just cut off.

This piece of code illustrates the problem:

import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class TableTest {

 public static void main(final String[] args) {

  final JTable jTable = new JTable();

  jTable.setModel(new DefaultTableModel() {
   private static final long serialVersionUID = 1L;
   @Override
   public Object getValueAt(final int row, final int column) {
    final StringBuffer sb = new StringBuffer();
    sb.append("<html>");
    sb.append("<font color=\"red\">this text is red</font> ");
    sb.append("<font color=\"green\">this text is green!</font>");
    sb.append("</html>");
    return sb.toString();
   }
   @Override
   public int getColumnCount() {
    return 2;
   }
   @Override
   public int getRowCount() {
    return 2;
   }
  });

  final JFrame jFrame = new JFrame();
  jFrame.getContentPane().add(jTable);
  jFrame.setSize(120, 80);
  jFrame.pack();
  jFrame.setTitle("Table test");
  jFrame.setLocationRelativeTo(null);
  jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
  jFrame.setVisible(true);

 }

}

My problem might become more clear when running the SSCCE above. If the JFrame is resized, I want the row height to automatically be modified to allow the entire contents of the JPanel to be displayed.

Due to the requirement of HTML, I am not able to use a JTextArea.

Thanks,

Ben

+1  A: 

This was a good challenge for a Friday morning.

The answer is to use a custom TableCellRenderer which update the table height on the fly:

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import java.awt.*;

public class ScratchSpace {


    public static void main(final String[] args) {

        final JTable jTable = new JTable();

        jTable.setModel(new DefaultTableModel() {
            private static final long serialVersionUID = 1L;

            @Override
            public Object getValueAt(final int row, final int column) {
                final StringBuffer sb = new StringBuffer();
                sb.append("<html>");
                sb.append("<font color=\"red\">this text is red</font> ");
                sb.append("<font color=\"green\">this text is green!</font>");
                sb.append("</html>");
                return sb.toString();
            }

            @Override
            public int getColumnCount() {
                return 2;
            }

            @Override
            public int getRowCount() {
                return 2;
            }
        });


        jTable.getColumnModel().getColumn(0).setCellRenderer(new MyTableCellRenderer());
        jTable.getColumnModel().getColumn(1).setCellRenderer(new MyTableCellRenderer());
        final JFrame jFrame = new JFrame();
        jFrame.getContentPane().add(jTable);
        jFrame.setSize(120, 80);
        jFrame.pack();
        jFrame.setTitle("Table test");
        jFrame.setLocationRelativeTo(null);
        jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        jFrame.setVisible(true);

    }

    private static class MyTableCellRenderer extends JLabel implements TableCellRenderer {

        public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
            setText(String.valueOf(value));
            table.setRowHeight(row, getPreferredSize().height);
            return this;
        }
    }
}

I think there is a problem with my solution though - the last column to be updated in each row will ultimately be the only one that gets a say in the row height. I leave solving that issue as an exercise for the reader. :-)

Steve McLeod
Thanks for the quick response - worked like a charm.
Ben Turner