Question

I want to dispose the text inserted into a JTable cell in a particular way. Infact now if I write into a cell, the text will be all on the same line, while I would like to see it in two lines.

Maybe I would be clearer with a graphic description. See, I would like the second one:

enter image description here

My Table code here:

public class TablePanel extends JPanel
{
private JTable table;
public Tabella()
{
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); 
table = new JTable(new MyTableModel());
table.setFillsViewportHeight(true);     
table.setPreferredScrollableViewportSize(new Dimension(500, 100));
JScrollPane jps = new JScrollPane(table);
add(jps);
add(new JScrollPane(table));
table.setCellSelectionEnabled(true);
table.setRowHeight(30);
TableColumn tcol;
    for (int i=0; i<table.getColumnCount(); i++)
    {
        tcol = table.getColumnModel().getColumn(i);
        tcol.setCellRenderer(new CustomTableCellRenderer());
    }

table.addMouseListener(
    new MouseAdapter(){
    public void mouseClicked(MouseEvent e) {
        int row = table.rowAtPoint(new Point(e.getX(), e.getY()));
        int col = table.columnAtPoint(new Point(e.getX(), e.getY()));

        if (col>0) {
        if (e.getClickCount() > 1) {
        if (row == 5 | row == 6) 
            {
                JOptionPane.showMessageDialog(null, "Impossible to set lesson.");

                return;
            }
        else {
            table.getColumnName(col);
            String day = table.getColumnName(col);
            String hour = (String) table.getValueAt(row, 0);
            InsertLesson cell = new InsertLesson(day, hour);
            cel.setVisible(true);

             }
            }
          }
        }
}
);
}
private class MyTableModel extends AbstractTableModel {
private String[] columns = {"","Monday","Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
private String[][] data = {{"8:30 - 9:30","","","","","",""},
    {"9:30 - 10:30","","","","","",""},
    {"10:30 - 11:30","","","","","",""},
    {"11:30 - 12:30","","","","","",""},
    {"12:30 - 13:30","","","","","",""},
    {"13:30 - 14:30","","","","","",""},
    {"14:30 - 15:30","","","","","",""},
    {"15:30 - 16:30","","","","","",""},
    {"16:30 - 17:30","","","","","",""}};

public int getColumnCount() {
    return columns.length;
}

public int getRowCount() {
    return data.length;
}

public String getColumnName(int col) {
    return columns[col];
}

public Object getValueAt(int row, int col) {
    return data[row][col];
}
}
public class CustomTableCellRenderer extends DefaultTableCellRenderer{
  public Component getTableCellRendererComponent (JTable table, 
Object obj, boolean isSelected, boolean hasFocus, int row, int column) {
  Component cell = super.getTableCellRendererComponent(
   table, obj, isSelected, hasFocus, row, column);
  if (isSelected) {
  cell.setBackground(Color.lightGray);
  } 
  else {
  if (row % 2 == 0) {
  cell.setBackground(new Color (245,245,250));
  }
  else {
  cell.setBackground(new Color(250,250,240));
  }
  }

  return cell;
  }
  }
}   

Thanks to the user Kiheru, a solution has been found: we have to:

1) centre the format of the string that will be inserted into the cell;

2) centre the "space" of the cell itself;

We can do these action by:

1) insert html centring text code in the string that has to be inserted into the cell (html code is automatically recognized);

2) centre the cell itself with the command setHorizontalAlignment(JLabel.CENTER);.

This question might be useful for everyone has this problem.

Was it helpful?

Solution

It's possible to have multiline labels (DefaultTableCellRenderer extends JLabel) using html as the label text:

"<html>Math,<br>Class1</html>"

Note that you may need to adjust the row heights as described here.

Update: Centering the label text was wanted as well, in addition to the line breaking.

That needs a setHorizontalAlignment(JLabel.CENTER) call on the cell renderer to center the text block. Also, the text lines were wanted centered relative to each other, so the html code ended up to like (actual code has more formatting):

<html><div style="text-align:center">Math,<br>Class1</div></html>

OTHER TIPS

I'm not sure where I got this from, but I accomplished this with a TextAreaRenderer

public class TextAreaRenderer extends JTextArea implements TableCellRenderer {

    private final DefaultTableCellRenderer adaptee = new DefaultTableCellRenderer();
    /** map from table to map of rows to map of column heights */
    private final Map cellSizes = new HashMap();


    public TextAreaRenderer() {
        setLineWrap(true);
        setWrapStyleWord(true);
    }

    public Component getTableCellRendererComponent(
            JTable table, Object obj, boolean isSelected,
            boolean hasFocus, int row, int column) {

        // set the colours, etc. using the standard for that platform
        adaptee.getTableCellRendererComponent(table, obj,
                isSelected, hasFocus, row, column);
        setForeground(adaptee.getForeground());
        setBackground(adaptee.getBackground());
        setBorder(adaptee.getBorder());
        setFont(adaptee.getFont());
        setText(adaptee.getText());


        // This line was very important to get it working with JDK1.4
        TableColumnModel columnModel = table.getColumnModel();
        setSize(columnModel.getColumn(column).getWidth(), 100000);
        int height_wanted = (int) getPreferredSize().getHeight();
        addSize(table, row, column, height_wanted);
        height_wanted = findTotalMaximumRowSize(table, row);
        if (height_wanted != table.getRowHeight(row)) {
            table.setRowHeight(row, height_wanted);
        }
        return this;
    }

    @SuppressWarnings("unchecked")
    private void addSize(JTable table, int row, int column, int height) {
        Map rows = (Map) cellSizes.get(table);
        if (rows == null) {
            cellSizes.put(table, rows = new HashMap());
        }
        Map rowheights = (Map) rows.get(new Integer(row));
        if (rowheights == null) {
            rows.put(new Integer(row), rowheights = new HashMap());
        }
        rowheights.put(new Integer(column), new Integer(height));
    }

    /**
     * Look through all columns and get the renderer.  If it is
     * also a TextAreaRenderer, we look at the maximum height in
     * its hash table for this row.
     */
    private int findTotalMaximumRowSize(JTable table, int row) {
        int maximum_height = 0;
        Enumeration columns = table.getColumnModel().getColumns();
        while (columns.hasMoreElements()) {
            TableColumn tc = (TableColumn) columns.nextElement();
            TableCellRenderer cellRenderer = tc.getCellRenderer();
            if (cellRenderer instanceof TextAreaRenderer) {
                TextAreaRenderer tar = (TextAreaRenderer) cellRenderer;
                maximum_height = Math.max(maximum_height,
                        tar.findMaximumRowSize(table, row));
            }
        }
        return maximum_height;
    }

    private int findMaximumRowSize(JTable table, int row) {
        Map rows = (Map) cellSizes.get(table);
        if (rows == null) {
            return 0;
        }
        Map rowheights = (Map) rows.get(new Integer(row));
        if (rowheights == null) {
            return 0;
        }
        int maximum_height = 0;
        for (Iterator it = rowheights.entrySet().iterator();
                it.hasNext();) {
            Map.Entry entry = (Map.Entry) it.next();
            int cellHeight = ((Integer) entry.getValue()).intValue();
            maximum_height = Math.max(maximum_height, cellHeight);
        }
        return maximum_height;
    }
}

Then you just use it like this (mine was for a "Notes" column):

table.getColumn("Notes").setCellRenderer(new TextAreaRenderer());

Whenever a \n appears, it will wrap the text. I also used this to accomplish the need for "merged cells" (you just have to be methodical about how you wrap the newlines). It's not perfect for the merged cells requirement, but it gets the job done.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top