开发者

How to render a checkbox?

I'm using Glazed lists, in a jTable where I have a column which is boolean. By default the jTable renders a checkbox where the column is type Boolean.Class. Using Glazed lists i cannot get the checkbox which is needed. I rendered checkboxs extending the DefaultTableCellRenderer but i'm not satisfied with it because the checkboxs are not "clickable".

In the GL faq http://www.glazedlists.com/documentation/faq i found:

*Q: How do I specify that my boolean table cells be rendered with a checkbox? For some reason, Glazed Lists has no getColumnClass() method.

A: If you need to specify the column class, you need to implement the AdvancedTableFormat interface instead of the regular TableFormat class. If you are using the GlazedLists.tableFormat() factory method, you must specify the base Object's class for a proper implementation of the AdvancedTableFormat.getColumnClass() method.*

Does some of you have experience with this I did not find any links with an example. The essential link in the faq is broken.

I tried with this:

 public class CheckBoxTableModel implements  AdvancedTableFormat {

     public Class getColumnClass(int column) {
         if(column==4)
        return Boolean.class;
         else
             return Object.class;
    }
}

Please help!

EDIT: I tried with this, the form 开发者_Go百科with the jtable does not show

   private class TicketTableFormat implements AdvancedTableFormat<Ticket>  {

        private final String[] cols = new String[]{"Id", "From", "Subject", "Date", "Incomplete"};

        public int getColumnCount() {
            return cols.length;
        }

        public String getColumnName(int colId) {
            return cols[colId];
        }

        public Class getColumnClass(int col) {
            if (col == 4) {
                return Boolean.class;
            } else {
                return Object.class;
            }
        }


        public Object getColumnValue(Ticket ticket, int colId) {

            switch (colId) {
                case 0:
                    return ticket.getId();
                case 1:
                    return ticket.getFrom();
                case 2:
                    return ticket.getSubject();
                case 3:
                    return ticket.getDate();
                case 4:
                    return ticket.getIncomplete();
            }
            return null;
        }

        public boolean isEditable(Ticket e, int col) {
            if (col < 4) {
                return false;
            } else {
                return true;
            }
        }

        public Ticket setColumnValue(Ticket e, Object o, int i) {
            e.setB((Boolean) editedValue);
            return e;           
           }

        public Comparator getColumnComparator(int i) {
            throw new UnsupportedOperationException("Not supported yet.");
        }

    }

i call it with this:

 TicketTableFormat tbFormat = new TicketTableFormat();
 TicketsModel = new EventTableModel(textFilteredTickets, tbFormat);
 ticketTable.setModel(TicketsModel);


The basic point here is that rendering table cells and eiting them are two different things. For table cell rendering, the renderer only serves as a 'stamp', i.e. the check box is initialized to the state that should be rendered and aterwards the Table only takes apicture of the renderer (by invoking its paint method) and places the tat picture in the appropriate cell - for rendering all the cells, the same instance of checkbox is re-configured over and over again to represent the according cell value. What you did in your code, is specifying the data type flavor of the model, so that the default table cell renderer chosen by the table is a checkbox renderer.

For the checkbox to be editable, a cell editor must be attached to the table cell (e.g. by configuring an editor for the particular column). In case a table cell receives input focus, the table cell editor component is initialized and placed inside the table cell (i.e. above the image that was painted by the renderer before). This cell editor component (would be a checkbox in your case) is remainig there (accepting user input via mouse or keyboard) until the user navigates away from that particzular table call. In the moment when editing ends, the cell editor is asked for the vale it has captured from the editing process, (i.e. getCellEditorValue() is called on the editor) and hte value is taken by the table and written back to the table model for that cell.

So in short: The renderer is only stamping data on the cell, i.e. outputting, an editor component is necessary to receive input.

  • Example code for custom table cell editor

  • Java tuorial explaining the thing in detail and having also checkbox examples and code


Did you implement isEditable(...) & setColumnValue(...) in your implementation of AdvancedTableFormat?

Implementing the following methods works for me.

public int getColumnCount()
public String getColumnName(int column)
public Object getColumnValue(E model, int column)
public boolean isEditable(E model, int column) // For making the checkbox editable
public IFdsModel setColumnValue(E model, Object value, int column)
public Class getColumnClass(int column) // For making it a Checkbox
public Comparator<E> getColumnComparator(int arg0) // for sorting (if you have a SortedList)

Edit: an example (quick and dirty)

import java.util.Comparator;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;

import ca.odell.glazedlists.BasicEventList;
import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.gui.AdvancedTableFormat;
import ca.odell.glazedlists.gui.WritableTableFormat;
import ca.odell.glazedlists.swing.EventTableModel;

public class Tester {

private static class MyBoolean {
    private Boolean b = Boolean.FALSE;

    public Boolean getB() {
        return b;
    }

    public void setB(Boolean b) {
        this.b = b;
    }

}

private static class BooleanTableFormat implements AdvancedTableFormat<MyBoolean>, WritableTableFormat<MyBoolean> {

    @Override
    public int getColumnCount() {
        return 1;
    }

    @Override
    public String getColumnName(int column) {
        return "Bool";
    }

    @Override
    public Object getColumnValue(MyBoolean baseObject, int column) {
        return baseObject.getB();
    }

    @Override
    public Class getColumnClass(int column) {
        return Boolean.class;
    }

    @Override
    public Comparator getColumnComparator(int column) {
        throw new IllegalStateException("Not yet implemented.");
    }

    @Override
    public boolean isEditable(MyBoolean baseObject, int column) {
        return true;
    }

    @Override
    public MyBoolean setColumnValue(MyBoolean baseObject, Object editedValue, int column) {
        baseObject.setB((Boolean) editedValue);
        return baseObject;
    }
}

public static void main(String[] args) {

    SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
            EventList<MyBoolean> list = new BasicEventList<MyBoolean>();
            list.add(new MyBoolean());
            list.add(new MyBoolean());
            EventTableModel<MyBoolean> etm = new EventTableModel<MyBoolean>(list, new BooleanTableFormat());
            JTable table = new JTable(etm);
            JFrame f = new JFrame("Tester");
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setSize(300, 200);
            f.getContentPane().add(new JScrollPane(table));
            f.setVisible(true);
        }
    });

}
}
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜