Java: Swing: JTable and TableModel: Row headers: JList
Call list.setFixedCellHeight(table.getHeight()); Add listeners to dynamically synchronize if you expect changes to the table's height. It is not necessary to call setFixedCellWidth(), as the default value will be sensible (or will it?)
Do not call list.setFixedCellHeight().
Subclass JTable and fire a bogus contentsChanged event from the adapter model to force recalculation of the cell height when it is changed.
Set the new height as preferred height on the renderer. This can be done as follows in a renderer similar to the one above:
class ...
{
private JTable table;
// Constructor omitted
public Component getListCellRendererComponent(JList list, Object value,
int index, boolean selected, boolean focused, int row)
{
// ...
Dimension size = getPreferredSize();
size.height = table.getRowHeight(index);
setPreferredSize(size);
return this;
}
}Again, I think the solution with a JTable is cleaner here.
Example: RowHeaderList.java
Either use a ListModel that listens to the TableModel and adjusts itself properly, or use a ListModel from TableModel bridge and have the row column in the TableModel as well. This is more complicated and probably less generic. It may be a reason to use a JTable instead of a JList for the header.
Set an special (simple) ListSelectionModel that never has any selection and lead/anchor indices equal to -1 on the header.
Use for example a JLabel, configured like the header renderer:
import javax.swing.JLabel;
import javax.swing.UIManager;
import javax.swing.LookAndFeel;
import javax.swing.border.Border;
import javax.swing.plaf.UIResource;
import javax.swing.plaf.BorderUIResource;
public class CornerHeader
extends JLabel
{
public CornerHeader()
{
}
public CornerHeader(String text)
{
super(text);
}
public void updateUI()
{
super.updateUI();
setOpaque(true);
LookAndFeel.installColors(this, "TableHeader.background", "TableHeader.foreground");
Border headerBorder = UIManager.getBorder("TableHeader.border");
if (headerBorder != null)
{
Border old = getBorder();
if (old == null || old instanceof UIResource)
setBorder(new BorderUIResource.CompoundBorderUIResource
(headerBorder, UIManager.getBorder("TableHeader.cellBorder")));
}
else
LookAndFeel.installBorder(this, "TableHeader.cellBorder");
}
}
Note: border changing doesn't work with MetalLookAndFeel because it uses a non-UIResource border for the TableHeader cells (a bug (#4422795), despite the evaluation).
How the content is dynamically updated depends on your model structure.
JList by default returns the same preferred, minimum and maximum width, so resizing isn't possible (if you honour these values) unless you set these properties explicitly (to what values?)
(C) 2001-2009 Christian Kaufhold (swing@chka.de)