Custom Table using AbstractTableModel
hello all, i am trying to create a Custom swing table extending AbstractTableModel, the problem is no Data is shown, here is what i am trying to do, any help wud be appreciated. Thanx in advance.
The class that is called to create a table
Code :
class Inbox implements TableModelListener{
public JTable table = null ;
JFrame win = null ;
int Height, Width, X, Y ;
public Inbox(JFrame win, int X, int Y, int Height, int Width, InboxTable dataStruc){
this.win = win ;
this.X = X ; this.Y = Y ; this.Height = Height ; this.Width = Width ;
table = new JTable(dataStruc) ;
table.getModel().addTableModelListener(this) ;
}
public void tableDraw(){
table.getTableHeader().setBounds(X, Y, Width, 25) ;
table.setBounds(X, Y + 25, Width, Height) ;
table.setDefaultRenderer(Object.class, new UnreadBold()) ;
win.add(table.getTableHeader()) ;
win.add(table) ;
}
public void tableChanged(TableModelEvent e){
int row = e.getFirstRow() ;
int col = e.getColumn() ;
Object model = e.getSource() ;
System.out.println(model) ;
}
}
The actual table class :
Code :
class InboxTable extends AbstractTableModel{
public String [] columnNames = {" ", "From", "Subject", "Date/Time" } ;
public Object [][] data = {{"", "", "", ""}} ;
public int [] mailID ;
public String [] mailDate ;
public String [] mailTime ;
public String [] mailFrom ;
public String [] mailMsg ;
public int [] mailAttCnt ;
public String [] mailSub ;
public String [] mailLabel ;
public int getColumnCount(){
return columnNames.length ;
}
public int getRowCount(){
return data.length ;
}
public String getColumnName(int col){
return (String)columnNames[col] ;
}
public Object getValueAt(int row, int col){
return data[row][col] ;
}
public Class getColumnClass(int c){
return getValueAt(0, c).getClass() ;
}
public boolean isCellEditable(int row, int col) {
if (col == 0) {
return true;
} else {
return false;
}
}
public void setValueAt(Object value, int row, int col) {
data[row][col] = value;
fireTableCellUpdated(row, col);
}
public InboxTable(){
}
}
And this is how i call the draw routine:
Code :
// Swallow a big gulp of data from a database and store it on an Array List then call populate table
void populateTable(){
InboxTable dataStruc = new InboxTable() ;
MailDescriptor [] mArray = new MailDescriptor[mailList.size()] ;
mArray = mailList.toArray(mArray) ;
dataStruc.data = new Object [mArray.length][4] ;
for (int i = 0 ; i < mArray.length ; i++){
dataStruc.data[i][0] = new Boolean(false) ;
dataStruc.data[i][1] = mArray[i].mailFrom ;
dataStruc.data[i][2] = mArray[i].mailSub ;
dataStruc.data[i][3] = mArray[i].mailDate ;
/*
dataStruc.setValueAt(new Boolean(false), i, 0) ;
dataStruc.setValueAt(mArray[i].mailFrom, i, 1) ;
dataStruc.setValueAt(mArray[i].mailSub, i, 2) ;
dataStruc.setValueAt(mArray[i].mailDate, i, 3) ;
*/
}
System.out.println(dataStruc.data.length) ;
}
void drawInbox(){
inbox = new Inbox( wClient, 200, 100, 500, 500, dataStruc) ;
inbox.tableDraw() ;
}
the thing is passing an old instance of AbstractTableModel should work or not ??
Re: Custom Table using AbstractTableModel
You made this more complicated than necessary. Regardless, where do you call the drawInbox() method that creates the JTable?
I am sort of confused about how your code actually works and why you did it this way.
Re: Custom Table using AbstractTableModel
Found something.
Look at this code:
Code java:
void populateTable(){
InboxTable dataStruc = new InboxTable() ;
MailDescriptor [] mArray = new MailDescriptor[mailList.size()] ;
mArray = mailList.toArray(mArray) ;
dataStruc.data = new Object [mArray.length][4] ;
for (int i = 0 ; i < mArray.length ; i++){
dataStruc.data[i][0] = new Boolean(false) ;
dataStruc.data[i][1] = mArray[i].mailFrom ;
dataStruc.data[i][2] = mArray[i].mailSub ;
dataStruc.data[i][3] = mArray[i].mailDate ;
/*
dataStruc.setValueAt(new Boolean(false), i, 0) ;
dataStruc.setValueAt(mArray[i].mailFrom, i, 1) ;
dataStruc.setValueAt(mArray[i].mailSub, i, 2) ;
dataStruc.setValueAt(mArray[i].mailDate, i, 3) ;
*/
}
System.out.println(dataStruc.data.length) ;
}
void drawInbox(){
inbox = new Inbox( wClient, 200, 100, 500, 500, dataStruc) ;
inbox.tableDraw() ;
}
In your drawInbox() method, you send dataStruc. In your populateTable() method, you have this: InboxTable dataStruc = new InboxTable() ;. Based on the code, I can only assume the dataStruc variable being used in your drawInbox() method is global. When you make changes to the dataStruc variable in your populateTable() method, you create a new Object named dataStruc but you do not alter the dataStruc variable that your drawInbox() method will use.
Sort of confusing. Does that make sense?
Re: Custom Table using AbstractTableModel
Sorry for late reply, had a long sleep. @aussiemcgr : obeservation of a veteran. I think i am learning and implementing in a wrong way. Could u help regarding implementation of a custom table which will be populated by large data ?? Fixed this now getting an Exception like this:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException and painting later only when taken mouse over.
at InboxTable.getColumnClass(Inbox.java:35)
at javax.swing.JTable.getColumnClass(Unknown Source)
at javax.swing.JTable.getCellRenderer(Unknown Source)
at javax.swing.plaf.basic.BasicTableUI.paintCell(Unkn own Source)
at javax.swing.plaf.basic.BasicTableUI.paintCells(Unk nown Source)
at javax.swing.plaf.basic.BasicTableUI.paint(Unknown Source)
at javax.swing.plaf.ComponentUI.update(Unknown Source)
at javax.swing.JComponent.paintComponent(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at javax.swing.JLayeredPane.paint(Unknown Source)
at javax.swing.JComponent.paintChildren(Unknown Source)
at javax.swing.JComponent.paintToOffscreen(Unknown Source)
at javax.swing.BufferStrategyPaintManager.paint(Unkno wn Source)
at javax.swing.RepaintManager.paint(Unknown Source)
at javax.swing.JComponent.paint(Unknown Source)
at java.awt.GraphicsCallback$PaintCallback.run(Unknow n Source)
at sun.awt.SunGraphicsCallback.runOneComponent(Unknow n Source)
at sun.awt.SunGraphicsCallback.runComponents(Unknown Source)
at java.awt.Container.paint(Unknown Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unkno wn Source)
at javax.swing.RepaintManager.paintDirtyRegions(Unkno wn Source)
at javax.swing.RepaintManager.seqPaintDirtyRegions(Un known Source)
at javax.swing.SystemEventQueueUtilities$ComponentWor kRequest.run(Unknow
n Source)
at java.awt.event.InvocationEvent.dispatch(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForFilter s(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForFilter(U nknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarch y(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
Re: Custom Table using AbstractTableModel
just a suggestion, instead AbstractTableModel why dont you extend DefaultTableModel instead? and just add the fields you needed? it will save you a lot of line of codes.
Re: Custom Table using AbstractTableModel
Quote:
Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException and painting later only when taken mouse over.
Huh? Where exactly did you copy that from?
db
Re: Custom Table using AbstractTableModel
Quote:
Originally Posted by
Darryl.Burke
Huh? Where exactly did you copy that from?
db
java2s. really weak in GUI programming, later i seriously debugged and found out that i was calling the drawing routine at a wrong time, and also after fixing that getting the same result, then found out this public Class getColumnClass(int c){
return getValueAt(0, c).getClass() ;
}
was returning null. Then changed it to data[0][c].getClass() ; that solved the problem. Well thanx to every body who tried to help. and
@relixus
Quote:
just a suggestion, instead AbstractTableModel why dont you extend DefaultTableModel instead? and just add the fields you needed? it will save you a lot of line of codes.
sure to check it out man thanx :D
Re: Custom Table using AbstractTableModel
You copied the exception stack trace line I quoted from java2s?
db
Re: Custom Table using AbstractTableModel
Quote:
Originally Posted by
Darryl.Burke
You copied the exception stack trace line I quoted from java2s?
db
Oh sorry, i misunderstood u, sorry for my bad english, actually i was in a hurry, so didn't recheck. instead puting the fact that the the painting occured only when mouse was over at last mangled it inside.. i guess it wud be a slight touch at the touchpad of my laptop that did this ( caused a mouse click event :D). But i must tell u now, i think u got a nice sense of humour.
Re: Custom Table using AbstractTableModel
I wasn't trying to be funny.
db
Re: Custom Table using AbstractTableModel
I threw this together as a simple example of how to create a JTable the easiest way I have found.
Main:
Code java:
import javax.swing.JFrame;
public class Table
{
public static void main(String[] args)
{
JFrame mainFrame = new JFrame("JTable Test");
mainFrame.setContentPane(new TableJAVA());
mainFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainFrame.setSize(500,400);
mainFrame.setVisible(true);
}
}
TableJAVA (extends JPanel and contains JTable code):
Code java:
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import java.util.Vector;
import java.awt.Dimension;
public class TableJAVA extends JPanel
{
//Create Table Elements
/* There are a few important things when creating a JTable.
* 1) The Data Array. This is a 2D array that holds the row
* and column data.
* 2) The Column Names Array. This is a 1D array that holds
* the column names.
* 3) The JTable Object itself.
* 4) A Table Model, in this case a DefaultTableModel.
* 5) A JScrollPane to allow the table to be viewable
* completely.
*/
Object[][] data;
String[] columnNames;
JTable table;
DefaultTableModel model;
JScrollPane tableScroller;
/* To create a table of dynamic size, we need a dynamic data
* structure to hold a list of Object that will be represented
* in the table. For this example, it is Person Objects.
*/
Vector<Person> personList;
public TableJAVA()
{
super();
//Initialize Person List
personList = new Vector<Person>();
personList.add(new Person("First1", "Last1", 23, "Male"));
personList.add(new Person("First2", "Last2", 58, "Female"));
personList.add(new Person("First3", "Last3", 94, "Male"));
personList.add(new Person("First4", "Last4", 34, "Female"));
personList.add(new Person("First5", "Last5", 20, "Male"));
personList.add(new Person("First6", "Last6", 71, "Female"));
personList.add(new Person("First7", "Last7", 13, "Male"));
personList.add(new Person("First8", "Last8", 43, "Female"));
//Initialize Column Names Array
columnNames = new String[]{"First Name","Last Name","Age","Gender" };
//Initialize Data Array
data = new Object[personList.size()][columnNames.length];
//Fill Data Array
for(int i=0;i<personList.size();i++)
{
data[i][0] = personList.get(i).firstName;
data[i][1] = personList.get(i).lastName;
data[i][2] = personList.get(i).age;
data[i][3] = personList.get(i).gender;
}
//Initialize DefaultTableModel
model = new DefaultTableModel(data,columnNames);
//Initialize JTable
table = new JTable(model);
//Initialize Table Scroll Pane and set size
tableScroller = new JScrollPane(table);
tableScroller.setPreferredSize(new Dimension(450, 250));
//Remember to add the Table Scroller, not the JTable to the container
super.add(tableScroller);
// ----- Now let's add a new person -----
Person newPerson = new Person("First9", "Last9", 18, "Female");
//Remember to add to Person List for consistency
personList.add(newPerson);
//Now we add to the JTable
model.addRow(new Object[]{newPerson.firstName,newPerson.lastName,newPerson.age,newPerson.gender});
}
}
Person Class:
Code java:
public class Person
{
String firstName;
String lastName;
int age;
String gender;
public Person(String fn, String ln, int a, String gen)
{
firstName = fn;
lastName = ln;
age = a;
gender = gen;
}
}
Tell me if anything is confusing. JTables can be hard to learn how to properly use.
Re: Custom Table using AbstractTableModel
Thank u very much for ur awsome hard work, really grateful. This one is sure to help, the way it is structured.