tbboyett
asked on
Sortable table paint problem arrayout of bounds
I have a Sortable jtable. The first time that data is added to it, it loads up just fine. I have an update button (basically, the user select certain criteria and the data is displayed in the jtable when they click update). This works fine. When i click the headers the jtable's data is displaying fine and sorting properly. The problem is after sorting the jtable several times and then clicking update it throws the following error (seems to throw it for every row being added) and leaving the row blank, then after all rows have been added, all the data is displayed properly in the jtable (or it appears to be correct)
If it helps i am using the jtable example, but have altered the executing code slightly so that I can add data anytime instead of just once when the dialog is displayed:
http://www.objects.com.au/java/examples/swing/SortableTable.do
Error:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfB oundsExcep tion: 40 >= 40
at java.util.Vector.elementAt (Vector.ja va:432)
at javax.swing.table.DefaultT ableModel. getValueAt (DefaultTa bleModel.j ava:621)
at table.SortableTableModel.g etValueAt( SortableTa bleModel.j ava:17)
at javax.swing.JTable.getValu eAt(JTable .java:1852 )
at javax.swing.JTable.prepare Renderer(J Table.java :3907)
at javax.swing.plaf.basic.Bas icTableUI. paintCell( BasicTable UI.java:19 85)
at javax.swing.plaf.basic.Bas icTableUI. paintCells (BasicTabl eUI.java:1 887)
at javax.swing.plaf.basic.Bas icTableUI. paint(Basi cTableUI.j ava:1810)
at javax.swing.plaf.Component UI.update( ComponentU I.java:154 )
at javax.swing.JComponent.pai ntComponen t(JCompone nt.java:74 2)
at javax.swing.JComponent.pai nt(JCompon ent.java:1 005)
at javax.swing.JComponent.pai ntChildren (JComponen t.java:842 )
at javax.swing.JComponent.pai nt(JCompon ent.java:1 014)
at javax.swing.JViewport.pain t(JViewpor t.java:726 )
at javax.swing.JComponent.pai ntChildren (JComponen t.java:842 )
at javax.swing.JComponent.pai nt(JCompon ent.java:1 014)
at javax.swing.JComponent._pa intImmedia tely(JComp onent.java :4881)
at javax.swing.JComponent.pai ntImmediat ely(JCompo nent.java: 4667)
at javax.swing.RepaintManager .paintDirt yRegions(R epaintMana ger.java:4 77)
at javax.swing.SystemEventQue ueUtilitie s$Componen tWorkReque st.run(Sys temEventQu eueUtiliti es.java:11 4)
at java.awt.event.InvocationE vent.dispa tch(Invoca tionEvent. java:209)
at java.awt.EventQueue.dispat chEvent(Ev entQueue.j ava:461)
at java.awt.EventDispatchThre ad.pumpOne EventForHi erarchy(Ev entDispatc hThread.ja va:275)
at java.awt.EventDispatchThre ad.pumpEve ntsForHier archy(Even tDispatchT hread.java :196)
at java.awt.EventDispatchThre ad.pumpEve nts(EventD ispatchThr ead.java:1 90)
at java.awt.EventDispatchThre ad.pumpEve nts(EventD ispatchThr ead.java:1 82)
at java.awt.EventDispatchThre ad.run(Eve ntDispatch Thread.jav a:110)
Has anyone ran into this issue before?
If it helps i am using the jtable example, but have altered the executing code slightly so that I can add data anytime instead of just once when the dialog is displayed:
http://www.objects.com.au/java/examples/swing/SortableTable.do
Error:
Exception in thread "AWT-EventQueue-0" java.lang.ArrayIndexOutOfB
at java.util.Vector.elementAt
at javax.swing.table.DefaultT
at table.SortableTableModel.g
at javax.swing.JTable.getValu
at javax.swing.JTable.prepare
at javax.swing.plaf.basic.Bas
at javax.swing.plaf.basic.Bas
at javax.swing.plaf.basic.Bas
at javax.swing.plaf.Component
at javax.swing.JComponent.pai
at javax.swing.JComponent.pai
at javax.swing.JComponent.pai
at javax.swing.JComponent.pai
at javax.swing.JViewport.pain
at javax.swing.JComponent.pai
at javax.swing.JComponent.pai
at javax.swing.JComponent._pa
at javax.swing.JComponent.pai
at javax.swing.RepaintManager
at javax.swing.SystemEventQue
at java.awt.event.InvocationE
at java.awt.EventQueue.dispat
at java.awt.EventDispatchThre
at java.awt.EventDispatchThre
at java.awt.EventDispatchThre
at java.awt.EventDispatchThre
at java.awt.EventDispatchThre
Has anyone ran into this issue before?
ASKER
my appologies, i meant the code that sets up the jtable headers and adds data, renderers and so forth.
I'll post the way that i'm doing this in just a sec so that you can compare
I'll post the way that i'm doing this in just a sec so that you can compare
ASKER
// My way
SortableTableModel zipsTM = new SortableTableModel() {
public Class getColumnClass(int col) {
switch (col) {
case 0:
return Double.class;
case 1:
return String.class;
case 2:
return String.class;
case 3:
return Integer.class;
case 4:
return Integer.class;
default:
return Object.class;
}
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 1:
return false;
default:
return true;
}
}
public void setValueAt(Object obj, int row, int col) {
switch (col) {
case 2:
super.setValueAt(new Integer(obj.toString()), row, col);
return;
default:
super.setValueAt(obj, row, col);
return;
}
}
};
JTable zipsJT = new JTable(zipsTM);
Vector zipsheaders = new Vector();
zipsheaders.addElement("Di stance");
zipsheaders.addElement("Di rection");
zipsheaders.addElement("Ci ty");
zipsheaders.addElement("Zi p");
zipsheaders.addElement("Co unt");
SortButtonRenderer renderer = new SortButtonRenderer();
TableColumnModel model = zipsJT.getColumnModel();
JTableHeader header = zipsJT.getTableHeader();
header.addMouseListener(ne w HeaderListener(header, renderer));
((SortableTableModel) zipsJT.getModel()).setColu mnIdentifi ers(zipshe aders);
SortableTableModel t = (SortableTableModel) zipsJT.getModel();
t.setRowCount(0);
int []zipwidths = {80, 80, 150, 50, 70};
int n = zipsheaders.size();
for (int i = 0; i < n; i++) {
model.getColumn(i).setHead erRenderer (renderer) ;
model.getColumn(i).setPref erredWidth (zipwidths [i]);
}
// The examples way
String[] headerStr = {"Name","Date","Size","Dir "};
int[] columnWidth = {100,150,100,50};
SortableTableModel dm = new SortableTableModel() {
public Class getColumnClass(int col) {
switch (col) {
case 0: return String.class;
case 1: return Date.class;
case 2: return Integer.class;
case 3: return Boolean.class;
default: return Object.class;
}
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 1: return false;
default: return true;
}
}
public void setValueAt(Object obj, int row, int col) {
switch (col) {
case 2: super.setValueAt(new Integer(obj.toString()), row, col); return;
default: super.setValueAt(obj, row, col); return;
}
}
};
dm.setDataVector(new Object[][]{
{"b" ,getDate("98/12/02"),new Integer(14),new Boolean(false)},
{"a" ,getDate("99/01/01"),new Integer(67),new Boolean(false)},
{"d" ,getDate("99/02/11"),new Integer(2) ,new Boolean(false)},
{"c" ,getDate("99/02/27"),new Integer(7) ,new Boolean(false)},
{"foo" ,new Date() ,new Integer(5) ,new Boolean(true)},
{"bar" ,new Date() ,new Integer(10),new Boolean(true)}},
headerStr);
JTable table = new JTable(dm);
//table.setShowGrid(false) ;
table.setShowVerticalLines (true);
table.setShowHorizontalLin es(false);
SortButtonRenderer renderer = new SortButtonRenderer();
TableColumnModel model = table.getColumnModel();
int n = headerStr.length;
for (int i=0;i<n;i++) {
model.getColumn(i).setHead erRenderer (renderer) ;
model.getColumn(i).setPref erredWidth (columnWid th[i]);
}
JTableHeader header = table.getTableHeader();
header.addMouseListener(ne w HeaderListener(header,rend erer));
If you notice in the examples code, you have to add the data to the model then create the jtable.
I needed to be able to add data later and change it when needed.
When I add data, this is how i do it:
SortableTableModel z = (SortableTableModel) zipsJT.getModel();
z.setNumRows(0);
Vector ziprow = new Vector();
ziprow.addElement(new Double(format.format(czc.d istance))) ;
ziprow.addElement(czc.dire ction);
ziprow.addElement(czc.city );
ziprow.addElement(new Integer(czc.zip));
ziprow.addElement(new Integer(czc.count));
z.addRow(ziprow);
Like i say it works perfect the first time, the problem just happens if i sort the table and then readd data
I hope this helps
SortableTableModel zipsTM = new SortableTableModel() {
public Class getColumnClass(int col) {
switch (col) {
case 0:
return Double.class;
case 1:
return String.class;
case 2:
return String.class;
case 3:
return Integer.class;
case 4:
return Integer.class;
default:
return Object.class;
}
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 1:
return false;
default:
return true;
}
}
public void setValueAt(Object obj, int row, int col) {
switch (col) {
case 2:
super.setValueAt(new Integer(obj.toString()), row, col);
return;
default:
super.setValueAt(obj, row, col);
return;
}
}
};
JTable zipsJT = new JTable(zipsTM);
Vector zipsheaders = new Vector();
zipsheaders.addElement("Di
zipsheaders.addElement("Di
zipsheaders.addElement("Ci
zipsheaders.addElement("Zi
zipsheaders.addElement("Co
SortButtonRenderer renderer = new SortButtonRenderer();
TableColumnModel model = zipsJT.getColumnModel();
JTableHeader header = zipsJT.getTableHeader();
header.addMouseListener(ne
((SortableTableModel) zipsJT.getModel()).setColu
SortableTableModel t = (SortableTableModel) zipsJT.getModel();
t.setRowCount(0);
int []zipwidths = {80, 80, 150, 50, 70};
int n = zipsheaders.size();
for (int i = 0; i < n; i++) {
model.getColumn(i).setHead
model.getColumn(i).setPref
}
// The examples way
String[] headerStr = {"Name","Date","Size","Dir
int[] columnWidth = {100,150,100,50};
SortableTableModel dm = new SortableTableModel() {
public Class getColumnClass(int col) {
switch (col) {
case 0: return String.class;
case 1: return Date.class;
case 2: return Integer.class;
case 3: return Boolean.class;
default: return Object.class;
}
}
public boolean isCellEditable(int row, int col) {
switch (col) {
case 1: return false;
default: return true;
}
}
public void setValueAt(Object obj, int row, int col) {
switch (col) {
case 2: super.setValueAt(new Integer(obj.toString()), row, col); return;
default: super.setValueAt(obj, row, col); return;
}
}
};
dm.setDataVector(new Object[][]{
{"b" ,getDate("98/12/02"),new Integer(14),new Boolean(false)},
{"a" ,getDate("99/01/01"),new Integer(67),new Boolean(false)},
{"d" ,getDate("99/02/11"),new Integer(2) ,new Boolean(false)},
{"c" ,getDate("99/02/27"),new Integer(7) ,new Boolean(false)},
{"foo" ,new Date() ,new Integer(5) ,new Boolean(true)},
{"bar" ,new Date() ,new Integer(10),new Boolean(true)}},
headerStr);
JTable table = new JTable(dm);
//table.setShowGrid(false)
table.setShowVerticalLines
table.setShowHorizontalLin
SortButtonRenderer renderer = new SortButtonRenderer();
TableColumnModel model = table.getColumnModel();
int n = headerStr.length;
for (int i=0;i<n;i++) {
model.getColumn(i).setHead
model.getColumn(i).setPref
}
JTableHeader header = table.getTableHeader();
header.addMouseListener(ne
If you notice in the examples code, you have to add the data to the model then create the jtable.
I needed to be able to add data later and change it when needed.
When I add data, this is how i do it:
SortableTableModel z = (SortableTableModel) zipsJT.getModel();
z.setNumRows(0);
Vector ziprow = new Vector();
ziprow.addElement(new Double(format.format(czc.d
ziprow.addElement(czc.dire
ziprow.addElement(czc.city
ziprow.addElement(new Integer(czc.zip));
ziprow.addElement(new Integer(czc.count));
z.addRow(ziprow);
Like i say it works perfect the first time, the problem just happens if i sort the table and then readd data
I hope this helps
ASKER
if i use this code to to call the method it works fine except it doesn't update the progressbar and labels as it normally would:
Runnable runnable = new Runnable() {
public void run() {
loadzipsTable();
}
};
EventQueue.invokeLater(run nable);
I tried:
try {
EventQueue.invokeLater(new ProgressUpdater(line, numlines));
} catch (Exception e) {
e.printStackTrace();
}
to update the progressbar but it throws:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call invokeAndWait from the event dispatcher thread
can someone explain the reason why?
Runnable runnable = new Runnable() {
public void run() {
loadzipsTable();
}
};
EventQueue.invokeLater(run
I tried:
try {
EventQueue.invokeLater(new
} catch (Exception e) {
e.printStackTrace();
}
to update the progressbar but it throws:
Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call invokeAndWait from the event dispatcher thread
can someone explain the reason why?
Reason for your original problem is that you were updating your table from a different thread, Swing is single threaded so all calls need to be made from event dispatch thread.
> it doesn't update the progressbar and labels as it normally would:
can u post the code that updates the progress and labels
> Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call invokeAndWait from the event dispatcher thread
you can only use invokeLater() from the edt.
> it doesn't update the progressbar and labels as it normally would:
can u post the code that updates the progress and labels
> Exception in thread "AWT-EventQueue-0" java.lang.Error: Cannot call invokeAndWait from the event dispatcher thread
you can only use invokeLater() from the edt.
ASKER
Here is how i update the labels
try {
EventQueue.invokeAndWait(n ew ProgressLblUpdater("Doing some long process"));
} catch (Exception e) {
e.printStackTrace();
}
private class ProgressLblUpdater implements Runnable {
private String text;
public ProgressLblUpdater(String text) {
this.text = text;
}
public void run() {
actionLbl.setText(text);
}
}
Here is how i update the progressbar
try {
EventQueue.invokeAndWait(n ew ProgressUpdater(line, numlines));
} catch (Exception e) {
e.printStackTrace();
}
private class ProgressUpdater implements Runnable {
private int line, numlines;
public ProgressUpdater(int line, int numlines) {
this.line = line;
this.numlines = numlines;
}
public ProgressUpdater(int line, int numlines) {
this.line = line;
this.numlines = numlines;
}
public void run() {
pbar.setMaximum((numlines) );
pbar.setValue(line);
}
}
try {
EventQueue.invokeAndWait(n
} catch (Exception e) {
e.printStackTrace();
}
private class ProgressLblUpdater implements Runnable {
private String text;
public ProgressLblUpdater(String text) {
this.text = text;
}
public void run() {
actionLbl.setText(text);
}
}
Here is how i update the progressbar
try {
EventQueue.invokeAndWait(n
} catch (Exception e) {
e.printStackTrace();
}
private class ProgressUpdater implements Runnable {
private int line, numlines;
public ProgressUpdater(int line, int numlines) {
this.line = line;
this.numlines = numlines;
}
public ProgressUpdater(int line, int numlines) {
this.line = line;
this.numlines = numlines;
}
public void run() {
pbar.setMaximum((numlines)
pbar.setValue(line);
}
}
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
What is that?