Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

checkbox in JTable

7 views
Skip to first unread message

Sandra Setz

unread,
Mar 4, 2001, 10:44:16 AM3/4/01
to
Hi,

I am trying to get a checkbox in a JTable. If I am correct, I do not need to
make a new Renderer, since the default renderer for a Boolean is already a
checkbox. Right?

I have been looking through a lot of of examples and I think my code should
be correct this way. But for some reason I cannot get this to work right.
When showing the frame that contains the table, the following exception
occurs:


Does anyone have an idea what it is that I am doing wrong? When I leave out
the getColumnClass procedure in the model, everything works fine, but I then
get "true" and "false" instead of a checkbox.

Below I have added the code for creating the table and the model I am using.
I have also added a trace of the exception that occurs.

I hope someone can help me.

Thanks in advance,
Sandra Setz


===================================
Code for creating the table:

public JScrollPane createTable() {

tableView = new JTable(AddressBook.getTitleModel());
AddressBook.getTitleModel().addTableModelListener(tableView);

tableView.setRowHeight(AddressBook.INITIAL_ROWHEIGHT);

AddressBook.getTitleModel().clear();
if (addressToEdit != null) {
Title title;
Iterator elements = addressToEdit.getTitleList().iterator();
while (elements.hasNext()) {
title = (Title)elements.next();
AddressBook.getTitleModel().updateTitle(title);
}

}
tableView.setDefaultRenderer()
TableColumn column = null;
for (int i = 0; i < 6; i++) {
column = tableView.getColumnModel().getColumn(i);
if (i > 0) {
column.setPreferredWidth(1);

// column.setCellEditor(new DefaultCellEditor(new JCheckBox()));
}
}

return new JScrollPane(tableView);

}


===================================
Code of the model:


import javax.swing.table.*;
import java.util.*;
import java.util.Vector;
import java.io.*;

public class TitleModel extends AbstractTableModel {
protected static int NUM_COLUMNS = 6;
protected static int START_NUM_ROWS = 0;
protected int nextEmptyRow = 0;
protected int numRows = 0;

protected Vector data = null;


public TitleModel() {
data = new Vector();
}

public String getColumnName(int column) {
switch (column) {
case 0:
return AddressBook.RS_TITLE;
case 1:
return AddressBook.RS_PRINT_ON_BIRTHDAY;
case 2:
return AddressBook.RS_PRINT_ON_CHRISTMAS;
case 3:
return AddressBook.RS_PRINT_ON_MARRIAGE;
case 4:
return AddressBook.RS_PRINT_ON_HOLIDAY;
case 5:
return AddressBook.RS_PRINT_ON_AGENDA;
}
return "";
}

public synchronized int getColumnCount() {
return NUM_COLUMNS;
}

public synchronized int getRowCount() {
if (numRows < START_NUM_ROWS) {
return START_NUM_ROWS;
} else {
return numRows + 1;
}
}

public synchronized Object getValueAt(int row, int column) {
if (row < nextEmptyRow) {
try {
Title t = (Title)data.elementAt(row);
switch (column) {
case 0:
return t.getTitle();
case 1:
return new Boolean(t.getPrintOnBirthday());
case 2:
return new Boolean(t.getPrintOnChristmas());
case 3:
return new Boolean(t.getPrintOnMarriage());
case 4:
return new Boolean(t.getPrintOnHoliday());
case 5:
return new Boolean(t.getPrintOnAgenda());
}
}
catch (Exception e) {
e.printStackTrace();
}
}
return "";
}

public void setValueAt(Object aValue, int row, int column) {
boolean newTitle = false;
Title title;
if (row < nextEmptyRow) {
title = (Title)data.elementAt(row);
}
else {
title = new Title("", false,false,false, false, false);
newTitle=true;

}

switch (column) {
case 0:
title.setTitle((String)aValue);
break;
case 1:
title.setPrintOnBirthday(((Boolean)aValue).booleanValue());
break;
case 2:
title.setPrintOnChristmas(((Boolean)aValue).booleanValue());
break;
case 3:
title.setPrintOnMarriage(((Boolean)aValue).booleanValue());
break;
case 4:
title.setPrintOnHoliday(((Boolean)aValue).booleanValue());
break;
case 5:
title.setPrintOnAgenda(((Boolean)aValue).booleanValue());
break;
}

if (newTitle) {
data.addElement(title);
numRows++;
nextEmptyRow++;
}
else {
data.setElementAt(title, row);
}
}

public Title getTitleAt(int row) {
Title a = null;
if (row < nextEmptyRow) {
try {
a = (Title)data.elementAt(row);
}
catch (Exception e) {
}
}
return a;
}


public synchronized void deleteTitle(Title title) {

int id = title.getId();

Title t = null;
int index = -1;
boolean found = false;
boolean addedRow = false;

int i = 0;
while (!found && (i < nextEmptyRow)) {
t = (Title)data.elementAt(i);
if (t.getId() == id) {
found = true;
index = i;
} else {
i++;
}
}

if (found) { //delete title
data.removeElementAt(index);
numRows--;
nextEmptyRow--;
fireTableRowsUpdated(index, data.size());
Collections.sort(data);
}
index = nextEmptyRow;

}


public synchronized void updateTitle(Title title) {

Title t = null;
int index = -1;
boolean found = false;
boolean addedRow = false;

int id = title.getId();

if (id == 0) {
title.setId(data.size() + 1);
}
else {
int i = 0;
while (!found && (i < nextEmptyRow)) {
t = (Title)data.elementAt(i);
if (t.getId() == id) {
found = true;
index = i;
}
else {
i++;
}
}
}


if (found) {
data.setElementAt(title, index);
}
else {
if (numRows <= nextEmptyRow) {
numRows++;
addedRow = true;
}
}
index = nextEmptyRow;
if (!found) {
data.addElement(title);
nextEmptyRow++;
}

if (addedRow) {
fireTableRowsInserted(index, index);
} else {
fireTableRowsUpdated(index, index);
}
Collections.sort(data);
}

public synchronized boolean isCellEditable(int row, int col) {
return true;
}

public synchronized void clear() {
int oldNumRows = numRows;

numRows = START_NUM_ROWS;
data.removeAllElements();
nextEmptyRow = 0;

if (oldNumRows > START_NUM_ROWS) {
fireTableRowsDeleted(START_NUM_ROWS, oldNumRows - 1);
}
fireTableRowsUpdated(0, START_NUM_ROWS - 1);
}


public void addTitlesToList(Address address) {

Title title;
int i = 0;
while (i < nextEmptyRow) {
title = (Title)data.elementAt(i);
address.addTitle(title);
i++;
}
}


public Class getColumnClass(int c) {
if (c > 0) {
return Boolean.class;
}
else {
return String.class;
}
}
}

============================================
Exception trace:

Exception occurred during event dispatching: java.lang.ClassCastException:
java.lang.String at
javax.swing.JTable$BooleanRenderer.getTableCellRendererComponent(JTable.java
:3249) at javax.swing.JTable.prepareRenderer(JTable.java:3537) at
javax.swing.plaf.basic.BasicTableUI.paintCell(BasicTableUI.java:995) at
javax.swing.plaf.basic.BasicTableUI.paintCells(BasicTableUI.java:917) at
javax.swing.plaf.basic.BasicTableUI.paint(BasicTableUI.java:858) at
javax.swing.plaf.ComponentUI.update(ComponentUI.java:39) at
javax.swing.JComponent.paintComponent(JComponent.java:398) at
javax.swing.JComponent.paint(JComponent.java:739) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JViewport.paint(JViewport.java:668) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JLayeredPane.paint(JLayeredPane.java:546) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JComponent.paintChildren(JComponent.java:523) at
javax.swing.JComponent.paint(JComponent.java:748) at
javax.swing.JLayeredPane.paint(JLayeredPane.java:546) at
javax.swing.JComponent.paintWithBuffer(JComponent.java:4393) at
javax.swing.JComponent._paintImmediately(JComponent.java:4336) at
javax.swing.JComponent.paintImmediately(JComponent.java:4187) at
javax.swing.RepaintManager.paintDirtyRegions(RepaintManager.java:370) at
javax.swing.SystemEventQueueUtilities$ComponentWorkRequest.run(SystemEventQu
eueUtilities.java:205) at
java.awt.event.InvocationEvent.dispatch(InvocationEvent.java:154) at
java.awt.EventQueue.dispatchEvent(EventQueue.java:317) at
java.awt.EventDispatchThread.pumpOneEvent(EventDispatchThread.java:103) at
java.awt.EventDispatchThread.pumpEvents(EventDispatchThread.java:93) at
java.awt.EventDispatchThread.run(EventDispatchThread.java:84)

Christian Kaufhold

unread,
Mar 5, 2001, 9:56:18 AM3/5/01
to
Sandra Setz <ss...@wxs.nl> wrote:

> I am trying to get a checkbox in a JTable. If I am correct, I do not need to
> make a new Renderer, since the default renderer for a Boolean is already a
> checkbox. Right?

Yes, as long as you don't want to have any (even trivial) modifications of
the renderer.

[but there is a ClassCastException]
See at the end for the reason.


> tableView = new JTable(AddressBook.getTitleModel());
> AddressBook.getTitleModel().addTableModelListener(tableView);

Why? JTable already does that on its own, and will become confused if
it receives the TableModelEvents twice.


> for (int i = 0; i < 6; i++) {
> column = tableView.getColumnModel().getColumn(i);
> if (i > 0) {
> column.setPreferredWidth(1);

That doesn't do what you think it does, it sets the preferred width to
15 (because that is the current minimum size).


>
> // column.setCellEditor(new DefaultCellEditor(new JCheckBox()));

You can also that (and setCellRenderer() with a custom renderer) and don't
need to care about getColumnClass() or default renderers at all.

[...]


>
> public String getColumnName(int column) {
> switch (column) {

[...]
> }
> return "";

Please throw an Exception. Don't (explicitly) accept any invalid values
passed in.



> public synchronized Object getValueAt(int row, int column) {

I wonder about all these "synchronized". They don't give you anything,
since the JTable/TableUI code will do multiple calls without locking.


> if (row < nextEmptyRow) {
> try {
> Title t = (Title)data.elementAt(row);
> switch (column) {
> case 0:
> return t.getTitle();
> case 1:
> return new Boolean(t.getPrintOnBirthday());

To avoid much work for the garbage collector, use the constants in
Boolean: return t.getPrintOnBirthday() ? Boolean.TRUE : Boolean.FALSE;


> case 2:
> return new Boolean(t.getPrintOnChristmas());
> case 3:
> return new Boolean(t.getPrintOnMarriage());
> case 4:
> return new Boolean(t.getPrintOnHoliday());
> case 5:
> return new Boolean(t.getPrintOnAgenda());
> }
> }
> catch (Exception e) {
> e.printStackTrace();
> }
> }
> return "";

And here you return a String for a column that is guaranteed to only to
contains Booleans -> the renderer expects a Boolean and gets a String
-> Exception.


Christian
--
Yes, my guards stood hard when abstract threats / Too noble to neglect
Deceived me into thinking / I had something to protect
Good and bad, I define these terms / Quite clear, no doubt, somehow
Bob Dylan, My Back Pages

0 new messages