【问题标题】:How to render a checkbox?如何渲染一个复选框?
【发布时间】:2011-04-20 09:37:11
【问题描述】:

我正在使用 Glazed 列表,在 jTable 中我有一个布尔列。 默认情况下,jTable 呈现一个复选框,其中列类型为Boolean.Class。 使用 Glazed 列表我无法获得所需的复选框。我渲染了扩展 DefaultTableCellRenderer 的复选框,但我对它不满意,因为复选框不是“可点击的”。

在 GL 常见问题解答 http://www.glazedlists.com/documentation/faq 我发现:

*问:如何指定我的布尔表格单元格使用复选框呈现? 出于某种原因,Glazed Lists 没有 getColumnClass() 方法。

A:如果需要指定列类,需要实现AdvancedTableFormat接口,而不是常规的TableFormat类。 如果您使用 GlazedLists.tableFormat() 工厂方法,则必须指定基对象的类才能正确实现 AdvancedTableFormat.getColumnClass() 方法。*

你们中的一些人有这方面的经验吗?我没有找到任何示例链接。常见问题解答中的基本链接已损坏。

我试过这个:

 public class CheckBoxTableModel implements  AdvancedTableFormat {

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

请帮忙!

编辑: 我试过了,带有jtable的表单不显示

   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.");
        }

    }

我用这个来称呼它:

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

【问题讨论】:

  • 应该可以,您确定 4 是布尔列的索引(索引从零开始,即第一个 == 0)?
  • 是的,我知道。 :( 只打印值 true/false 没有复选框:/
  • 不确定是否有帮助,但死链接应该指向here。
  • 只是为了仔细检查是否按预期调用了 advancedFormat:在 if 块中添加一个 println(column) (并使其成为一个块以确保您在其中)。
  • 当我添加EventTableModel(egList,objCheckBoxTableModel)时,jtable所在的表单不显示。

标签: java swing glazedlists


【解决方案1】:

这里的基本点是渲染表格单元格和编辑它们是两件不同的事情。对于表格单元格渲染,渲染器仅用作“标记”,即复选框初始化为应渲染的状态,然后表格仅拍摄渲染器的图片(通过调用其绘制方法)并放置 tat 图片在适当的单元格中 - 为了呈现所有单元格,相同的复选框实例被一遍又一遍地重新配置以表示相应的单元格值。您在代码中所做的是指定模型的数据类型风格,以便表格选择的默认表格单元格渲染器是复选框渲染器。

要使复选框可编辑,必须将单元格编辑器附加到表格单元格(例如,通过为特定列配置编辑器)。如果表格单元格接收到输入焦点,表格单元格编辑器组件将被初始化并放置在表格单元格内(即在渲染器之前绘制的图像上方)。此单元格编辑器组件(在您的情况下将是一个复选框)保留在那里(通过鼠标或键盘接受用户输入),直到用户导航离开该特定表调用。在编辑结束的那一刻,单元格编辑器被要求提供它从编辑过程中捕获的值,(即在编辑器上调用getCellEditorValue())并且表获取hte值并写回表模型那个细胞。

简而言之:渲染器只是在单元格上标记数据,即输出,需要一个编辑器组件来接收输入。

【讨论】:

    【解决方案2】:

    您是否在 AdvancedTableFormat 的实现中实现了 isEditable(...) 和 setColumnValue(...)?

    实现以下方法对我有用。

    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)
    

    编辑:一个例子(又快又脏)

    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);
            }
        });
    
    }
    }
    

    【讨论】:

    • 我尝试了我在问题中作为编辑发布的示例。没有显示 jtable 所在的表单。
    • 我终于解决了这个问题。凯非常感谢您的时间和精力。 :)
    猜你喜欢
    • 1970-01-01
    • 2019-04-12
    • 1970-01-01
    • 2017-08-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-09-05
    相关资源
    最近更新 更多