Hi Christian Kaulhold,
I have resolved the trouble, but now I have other.
My trouble now is that when I select a cell with Integer, String,...
data, all is right. A nice rectangle is painting around cell (one
pixel of width). But when I select a cell with Boolean data, this
rectangle do not appear.
What's the trouble?
Do you know is good idea two use only one class to renderer all kind
of types in cells?
My code is:
public class MyTable extends JPanel
{
private JTable myTable = new JTable();
// Sorting helper class
SortedTableHelper helper = new SortedTableHelper(myTable);
private JScrollPane jScrollPane1 = new JScrollPane();
private BorderLayout borderLayout1 = new BorderLayout();
public MyTable() {
this.setLayout(borderLayout1);
setVerticalInterspaceCell(3);
myTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
setupHeaderRenderer();
setupCellRenderers();
// Disable automatic sorting initially
helper.getSortedTableModel().setAlwaysSort(false);
helper.prepareTable();
updateColumnWidth();
jScrollPane1.getViewport().add(myTable, null);
this.add(jScrollPane1, BorderLayout.CENTER);
}
public void setVerticalInterspaceCell(int especio) {
myTable.setRowHeight(myTable.getRowHeight() + 2 * especio);
}
private void setupHeaderRenderer()
{
setHeaderHorizontalAlignment(SwingConstants.CENTER);
setHeaderHorizontalTextPosition(SwingConstants.LEFT);
setHeaderFontColor(new Color(158, 11, 14));
}
private void setupCellRenderers()
{
MyCellRenderer numberRenderer = new MyCellRenderer();
numberRenderer.setHorizontalAlignment(SwingConstants.RIGHT);
myTable.setDefaultRenderer(Number.class, numberRenderer);
myTable.setDefaultRenderer(Float.class, numberRenderer);
myTable.setDefaultRenderer(Double.class, numberRenderer);
myTable.setDefaultRenderer(Boolean.class, new
MyCellRenderer());
myTable.setDefaultRenderer(Date.class, new MyCellRenderer());
myTable.setDefaultRenderer(String.class, new
MyCellRenderer());
}
// This is Christian Kaulhold code, but it only examines 25 first
rows.
private void updateColumnWidth()
{
int numberRowExamined = 25;
JTableHeader header = myTable.getTableHeader();
TableCellRenderer defaultHeaderRenderer = null;
if (header != null) {
defaultHeaderRenderer = header.getDefaultRenderer();
}
TableColumnModel columns = myTable.getColumnModel();
TableModel data = myTable.getModel();
int margin = columns.getColumnMargin();
int totalWidth = 0;
for (int i = columns.getColumnCount() - 1; i >= 0; --i)
{
TableColumn column = columns.getColumn(i);
int columnIndex = column.getModelIndex();
int width = -1;
TableCellRenderer h = column.getHeaderRenderer();
if (h == null) {
h = defaultHeaderRenderer;
}
if (h != null) { // Not explicitly impossible
Component c = h.getTableCellRendererComponent(myTable,
column.getHeaderValue(), false, false, -1, i);
width = c.getPreferredSize().width;
}
if (myTable.getRowCount() < 25) {
numberRowExamined = myTable.getRowCount();
}
for (int row = numberRowExamined - 1; row >= 0; --row)
{
TableCellRenderer r = myTable.getCellRenderer(row, i);
Component c = r.getTableCellRendererComponent(myTable,
data.getValueAt(row, columnIndex), false,
false, row, i);
width = Math.max(width, c.getPreferredSize().width);
}
if (width >= 0) {
column.setPreferredWidth(width + margin); // <1.3:
without margin
} else {
; // ???
}
totalWidth += column.getPreferredWidth();
}
/* If you like; This does not make sense for two many columns!
Dimension size = table.getPreferredScrollableViewportSize();
size.width = totalWidth;
table.setPreferredScrollableViewportSize(size);
*/
}
public JTable getTabla() {
return myTable;
}
public void setModel(TableModel model) {
TableModel oldModel = myTable.getModel();
if (model != null) {
helper.setTableModel(model);
setupHeaderRenderer();
setupCellRenderers();
updateColumnWidth();
}
}
public void setHeaderHorizontalAlignment(int alignment) {
SortedTableHeaderCellRenderer renderer =
getSortedTableHeaderCellRenderer();
if (renderer == null) {
return;
} else {
renderer.setHeaderHorizontalAlignment(alignment);
}
}
public void setHeaderHorizontalTextPosition(int alignment) {
SortedTableHeaderCellRenderer renderer =
getSortedTableHeaderCellRenderer();
if (renderer == null) {
return;
} else {
renderer.setHeaderHorizontalTextPosition(alignment);
}
}
public void setHeaderFontColor(Color color) {
SortedTableHeaderCellRenderer renderer =
getSortedTableHeaderCellRenderer();
if (renderer == null) {
return;
} else {
renderer.setHeaderFontColor(color);
}
}
public void setHeaderFontStyle(int style) {
SortedTableHeaderCellRenderer renderer =
getSortedTableHeaderCellRenderer();
if (renderer == null) {
return;
} else {
renderer.setHeaderFontStyle(style);
}
}
public void setHeaderFontSize(int size) {
SortedTableHeaderCellRenderer renderer =
getSortedTableHeaderCellRenderer();
if (renderer == null) {
return;
} else {
renderer.setHeaderFontSize(size);
}
}
// This method is used to get HeaderRenderer when table is sorted.
private SortedTableHeaderCellRenderer
getSortedTableHeaderCellRenderer() {
TableCellRenderer renderer = helper.getHeaderCellRenderer();
if (renderer instanceof SortedTableHeaderCellRenderer) {
return (SortedTableHeaderCellRenderer) renderer;
} else {
return null;
}
}
// Customize cell renderer
class MyCellRenderer extends DefaultTableCellRenderer
{
int rowsPerGroup = 1;
// Two groups of rows. Group One with one background color and
// Group Two with other background color
Color backgroundGroupOne = SystemColor.white;
Color backgroundGroupTwo = SystemColor.controlHighlight;
Color foregroundGroupOne = myTable.getForeground();
Color foregroundGroupTwo = SystemColor.blue;
private int horizontalAlignment = SwingConstants.CENTER;
int fontStyle = Font.PLAIN;
int fontSize;
DateFormat dateFormatter = new SimpleDateFormat("dd/MM/yyyy");
public MyCellRenderer() {
fontSize = this.getFont().getSize();
}
public void setHorizontalAlignment(int horizontalAlignment) {
this.horizontalAlignment = horizontalAlignment;
}
// ... More set...(...) methods
public Component getTableCellRendererComponent(JTable table,
Object value, boolean isSelected, boolean hasFocus,
int row,
int column) {
setEnabled(table == null || table.isEnabled());
if (value instanceof Boolean) {
JCheckBox checkBox = new JCheckBox();
checkBox.setSelected(((Boolean)value).booleanValue());
checkBox.setHorizontalAlignment(horizontalAlignment);
if (isSelected) {
checkBox.setForeground(myTable.getSelectionForeground());
checkBox.setBackground(myTable.getSelectionBackground());
} else {
if (isRowGroupOne(row, myTable.getRowCount())) {
checkBox.setForeground(foregroundGroupOne);
checkBox.setBackground(backgroundGroupOne);
} else {
checkBox.setForeground(foregroundGroupTwo);
checkBox.setBackground(backgroundGroupTwo);
}
}
return checkBox;
}
Component comp =
super.getTableCellRendererComponent(table, value,
isSelected, hasFocus, row, column);
JLabel label = (JLabel) comp;
label.setHorizontalAlignment(horizontalAlignment);
label.setFont(new Font(label.getFont().getName(),
fontStyle,
fontSize));
if (isSelected) {
label.setForeground(myTable.getSelectionForeground());
label.setBackground(myTable.getSelectionBackground());
} else {
if (isRowGroupOne(row, myTable.getRowCount())) {
label.setForeground(foregroundGroupOne);
label.setBackground(backgroundGroupOne);
} else {
label.setForeground(foregroundGroupTwo);
label.setBackground(backgroundGroupTwo);
}
}
if (value instanceof Double) {
label.setText(formatNumber((Double) value, 3));
}
if (value instanceof Float) {
label.setText(formatNumber((Float) value, 3));
}
if (value instanceof Date) {
label.setText(dateFormatter.format((Date) value));
}
// super.getTableCellRendererComponent(table, value,
isSelected,
// hasFocus, row,
column);
return label;
}
private boolean isRowGroupOne(int rowIndex, int rows)
{
boolean groupOne = true;
for (int i = rowsPerGroup; i < rows; i += rowsPerGroup) {
if (rowIndex < i) {
return groupOne;
} else {
groupOne = !groupOne;
}
}
return groupOne;
}
public void validate() {}
public void revalidate() {}
protected void firePropertyChange(String propertyName, Object
oldValue,
Object newValue) {}
public void firePropertyChange(String propertyName, boolean
oldValue,
boolean newValue) {}
private String formatNumber(Float number, int nDecimal) {
NumberFormat formatter =
NumberFormat.getNumberInstance();
formatter.setMaximumFractionDigits(nDecimal);
formatter.setMinimumFractionDigits(nDecimal);
return formatter.format(number);
}
private String formatNumber(Double number, int nDecimal) {
NumberFormat formatter =
NumberFormat.getNumberInstance();
formatter.setMaximumFractionDigits(nDecimal);
formatter.setMinimumFractionDigits(nDecimal);
return formatter.format(number);
}
}
}
> > Is it possible to have customized renderer only for one cell or a
> > specify row? How can I do this?
>
> Delegation.
I do not know what is Delegation. Could you explain me, please?
Sincerely,
Alvaro