Still problems with JTable
I still can't get a JTable working.
This is third time that I try to write from scratch.
I just want to use JTable for displaying information.
Meaning not editable not resizable etceteras.
Also I want to determine from all cells how they look.
Including Headers.
Meaning borders, colors and fonts.
For that I created an Object CellContent.
It contains all information on the look and the value.
I subclassed JTable.
And added a default Renderer for CellContent.
(At the constructor of MyJTable)
this.setDefaultRenderer(CellContent.class, new MyRenderer());
What happens that MyRenderer isn't called.
MyJTable displays CellContent.toString().
I also noticed that tableChanged(TableModelEvent e) is called at
JTable.
Even I not added any listeners.
If I override this methode in MyJTable then
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
in that methode generate ArrayIndexOutOfBoundExeptions -1.
Think that means it is called before MyJTable is created.
Why it is called before MyJTable is created?
I think this is a bug.
So I changed it to super.tableChanged(e); return;
In my previous example I also got ArrayIndexOutOfBoundException from
inside the Java source.
I added
protected TableModel createDefaultDataModel()
{
return new MyTableModel();
}
But that didn't change anything.
My simple question is why is MyRenderer not called when I set it with
this.setDefaultRenderer(CellContent.class, new MyRenderer());
at the constructor of MyJTable ?
Here is my source code:
===============================
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class MyJTable extends JTable //implements TableModelListener
{
public MyJTable()
{
super();
// Note in Suns example SimpleTableDemo.java they extend JPanel
not JTable
// it contains a variable table which is a default JTable
// also they made this table final.
// In convention a final variable should be written in capital
letters.
//
// Where table is used I will use the keyword this.
// need to tell to use a default MyRenderer for CellContent
this.setDefaultRenderer(CellContent.class, new MyRenderer
());
}
public MyJTable(Object[][] rowData, Object[] columnNames)
{
super(rowData,columnNames);
this.setDefaultRenderer(CellContent.class, new MyRenderer());
System.out.println("MyRender is set.");
}
protected TableModel createDefaultDataModel()
{
return new MyTableModel();
}
public void tableChanged(TableModelEvent e)
{
System.out.println("tableChanged called");
super.tableChanged(e);
return;
}
===================================
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class MyTableModel extends AbstractTableModel
{
public String[] columnNames=new String[0];
public Object[][] rowData=new Object[0][0];
public String getColumnName(int col)
{
return columnNames[col].toString();
}
public int getRowCount()
{
return rowData.length;
}
public int getColumnCount()
{
return columnNames.length;
}
public Object getValueAt(int row, int col)
{
return rowData[row][col];
}
public boolean isCellEditable(int row, int col)
{
// return true;
return false; // non of the my cells are editable, we only
display data.
}
public void setValueAt(Object value, int row, int col)
{
rowData[row][col] = value;
fireTableCellUpdated(row, col);
}
/*
From SUN example
Remember that if you let a table create its own model,
it uses Object as the type of every column.
To specify more precise column types, the table model
must define the getColumnClass method appropriately, as
demonstrated by
*/
public Class getColumnClass(int c)
{
return getValueAt(0, c).getClass();
}
}
=======================
// This renderer uses an Object named CellContent
// CellContent contains all information on how to show the content
// CellContent also contains the value to display.
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class MyRenderer extends JLabel implements TableCellRenderer
{
public MyRenderer()
{
super();
setOpaque(true); // background must show
}
public Component getTableCellRendererComponent( JTable table,
Object cellContent,
boolean isSelected,
boolean hasFocus,
int row,
int
column)
{
System.out.println("Renderer Called."); // NEVER CALLED
if (cellContent==null) return this;
CellContent content=(CellContent)cellContent; // We only cast one
time to speed up.
this.setBackground(content.getBackground());
this.setForeground(content.getForeground());
this.setFont(content.getFont());
this.setHorizontalAlignment(content.getHorizontalAlignment());
if (content.getLineBorder()!=null) { this.setBorder
(content.getLineBorder()); }
this.setText(content.getValue());
return this;
}
}
========================
public class CellContent
{
private Color bgcolor=Color.WHITE; // background color
private Color color =Color.BLACK; // foreground color
private Font font =new Font(Font.MONOSPACED,Font.PLAIN,12);
private int alignment=JLabel.LEFT; // default alignment is left
private LineBorder lineBorder=null;
private String value ="";
public CellContent() {}
public CellContent(String value)
{
this(null,null,null,JLabel.LEFT,null,value);
}
public CellContent(Color bgcolor,Color color,Font font,int
alignment,LineBorder lineBorder,String value )
{
if (bgcolor!=null) { this.bgcolor=bgcolor; }
if (color!=null) { this.color=color; }
if (font!=null) { this.font=font;}
this.alignment=alignment;
if (lineBorder!=null) {this.lineBorder=lineBorder;}
if (value!=null) { this.value=value;}
}
public Color getBackground() { return bgcolor; }
public Color getForeground() { return color; }
public Font getFont() { return font; }
public int getHorizontalAlignment() { return alignment; }
public LineBorder getLineBorder() { return lineBorder; }
public String getValue() { return value; }
public void setBackground(Color bgcolor) { this.bgcolor=bgcolor; }
public void setForeground(Color color) { this.color=color; }
public void setFont(Font font) { this.font=font; }
public void setHorizontalAlignment(int alignment)
{ this.alignment=alignment; }
public void setLineBorder(LineBorder lineBorder)
{ this.lineBorder=lineBorder;}
public void setValue(String value) { this.value=value; }
}
===================
import java.awt.*;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.*;
public class MyJTableDemo
{
public static void main(String[] args)
{
Object[] columnNames =
{"AccountNumber","AccountName","DebetValue","CreditValue"};
Object[][] data =
{
{new CellContent("010.00")
,new CellContent("Eigen Vermogen")
,new CellContent("")
,new CellContent("10000")
},
{"010.00","Eigen Vermogen","",10000}
};
// create a frame for displaying
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
MyJTable myJTable = new MyJTable(data,columnNames);
// JTable myJTable = new JTable(data,columnNames);
JScrollPane jscrollPane=new JScrollPane(myJTable);
frame.getContentPane().add(jscrollPane,BorderLayout.CENTER);
frame.pack();
frame.setExtendedState(frame.getExtendedState()|
JFrame.MAXIMIZED_BOTH);
frame.setVisible(true);
// TODO, add your application code
System.out.println("Hello World!");
}
}