Editors和Render的基本理解和基本使用

一. 基本理解

  1. render即在界面展示的时候所调用的类,用来绘制图形

官方文档:The Renderer used to draw the data cells of the column using the specific compenent such as the JLabel, JCheckbox, and so on.

  1. Editor即在用户点击单元格是调用的类, 用来处理点击编辑等事件

官方文档The Editor used to take over the cell, controlling the cell’s editing behavior

  1. 一般来说两者是一致的,但也存在使用不同组件对象的情况

官方文档: BTW, the same cell, the Render and Editor could use the different compenet to react the behavior.
综上,可以直白地理解为:
* TableCellRenderer就是用来绘制展示当前cell单元数值内容的,
* 你可以用文字、数值或者图片来表示内容,
* 当然最强大展示方式的就是通过自定义自己的renderer组件,
* 通过Java2D来绘制各种天花乱坠的效果。
* TableCellEditor主要是用来当用户点击在具体cell时进行编辑的组件,
* 所以TableCellEditor除了具有TableCellRenderer一样的绘制功能外还可以进行交互动作,
* 例如在cell上出现下拉框、勾选框甚至通过按钮弹出更复杂的对话框让用户进行输入编辑。

二. 如何使用

1. 如何使用Renders:

1.1. 首先,先知道如何用已经写好了的Renders
调用JTable中的方法setDefaultRender, 具体到某一列可以:

//getColumn获取column这一列
//setCellRender设置这一列表格的Render
jTable.getColumn("Button").setCellRenderer(new ButtonRenderer());

参考文档:You can set a type-specific cell renderer using the JTable method
setDefaultRenderer. To specify that cells in a particular column
should use a renderer, you use the TableColumn method setCellRenderer.
You can even specify a cell-specific renderer by creating a JTable
subclass.

2.2. 如何写自己的Render类
可以直接继承类DefaultTableCellRenderer,也可以通过实现接口TableCellRender来写自己的Render类.
2.2.1 直接继承类DefaultTableCellRender比较简单方便,通过重写方法setValue实现setText或者setIcon,比如下面是类Date的Render类:

static class DateRenderer extends DefaultTableCellRenderer {
    DateFormat formatter;
    public DateRenderer() { super(); }

    public void setValue(Object value) {
        if (formatter==null) {
            formatter = DateFormat.getDateInstance();
        }
        setText((value == null) ? "" : formatter.format(value));
    }
}

参考文献:It is easy to customize the text or image rendered by the default
renderer, DefaultTableCellRenderer. You just create a subclass and
implement the setValue method so that it invokes setText or setIcon
with the appropriate string or image.

2.2.2 如果继承类DefaTableCellRender不能充分体现出自己的特色,就可以使用另外一种方法: 就是实现TableCellRenderer接口,而这个接口只需要实现一个方法:getTableCellRenderer, 该方法的实现要反映出组件的状态,最后返回该组件,
举一个栗子就容易明白了,比如要有如下的效果:在这里插入图片描述
这个里面使用的是ColorRender, 下面是源码如何实现的:

public class ColorRenderer extends JLabel
                           implements TableCellRenderer {
    ...
    public ColorRenderer(boolean isBordered) {
        this.isBordered = isBordered;
        setOpaque(true); //MUST do this for background to show up.
    }

    public Component getTableCellRendererComponent(
                            JTable table, Object color,
                            boolean isSelected, boolean hasFocus,
                            int row, int column) {
        Color newColor = (Color)color;
        setBackground(newColor);
        if (isBordered) {
            if (isSelected) {
                ...
                //selectedBorder is a solid border in the color
                //table.getSelectionBackground().
                setBorder(selectedBorder);
            } else {
                ...
                //unselectedBorder is a solid border in the color
                //table.getBackground().
                setBorder(unselectedBorder);
            }
        }
        
        setToolTipText(...); //Discussed in the following section
        return this;
    }
}

通过查找官方文档, 我们来看一下getTableCellRenderComponent的参数:

/**
     * table - the JTable that is asking the renderer to draw; can be null
     * value - the value of the cell to be rendered.
     *      It is up to the specific renderer to interpret and draw the value.
     *      For example, if value is the string "true",
     *      it could be rendered as a string or it could be rendered as a check box that is checked.
     *      null is a valid value
     * isSelected - true if the cell is to be rendered with the selection highlighted; otherwise false
     * hasFocus - if true, render cell appropriately.
     *      For example, put a special border on the cell,
     *      if the cell can be edited, render in the color used to indicate editing
     * row - the row index of the cell being drawn.
     *      When drawing the header, the value of row is -1
     * column - the column index of the cell being drawn
     *
     */

英语要好好学鸭~~~~
我们主要看几个关键参数, value也就是你一开始是传给table的Object数组在这个cell的Object值, isSelected就是所在行是否被选中, row是cell所在行, column是cell所在列。在运行是这个函数会在选中,光标悬停,状态改变等情况下被调用~~
如果要针对某一个cell使用某个Render, 那么就要写一个JTables的子类重写getCellRender()方法,下面是如何针对第【0, 0】个Cell使用WeirdRender(),而其他cell还是用原来Render方法 的代码实现:

TableCellRenderer weirdRenderer = new WeirdRenderer();
table = new JTable(...) {
    public TableCellRenderer getCellRenderer(int row, int column) {
        if ((row == 0) && (column == 0)) {
            return weirdRenderer;
        }
        // else...
        return super.getCellRenderer(row, column);
    }
};

2. 如何使用Editors

放个文档链接:Interface TableCellEditor

默认实现类 :

editors都是实现了一个叫做TableCellEditor的接口,而类DefaultCellEditor实现了这个接口并且已经为JTextField, JCheckBox, or JComboBox类提供了构造器。一般我们不需要为复选框去构造editor,因为table已经为boolean自动提供了复选框的render和editor。

构造特有类:

但是除了上面所提到的类 JTextField, JCheckBox, or JComboBox不需要自己手动构造editors外,对于其他的类,我们需要去做一些工作。

如何构造定制化的editors:
可以用来继承的类:

AbstractCellEditor 和 DefaultTableCellEditor
DefaultTableCellEditor: 提供了一些可以直接使用的默认类
AbstractCellEditor: 为您省去了实现单元格编辑器所需的事件触发代码的麻烦。

参考文档: What if you want to specify an editor other than a text field, check box, or combo box? As DefaultCellEditor does not support other types of components, you must do a little more work. You need to create a class that implements the TableCellEditor interface. The AbstractCellEditor class is a good superclass to use. It implements TableCellEditor’s superinterface, CellEditor, saving you the trouble of implementing the event firing code necessary for cell editors.

需要去实现的方法:

至少需要实现两个方法,getCellEditorValue and getTableCellEditorComponent

getCellEditorValue :被CellEditor所需要,返回单元格的当前值
getTableCellEditorComponent: 被TableCellEditor所需要,应该配置相关属性并返回要作用于编辑器的组件,在被点击的时候会被调用,这个时候可以获得table和被点击的行和列,可以用来做点击事件处理

下面是从ColorEditor.java的源码:

public class ColorEditor extends AbstractCellEditor
                         implements TableCellEditor,
                                    ActionListener {
    Color currentColor;
    JButton button;
    JColorChooser colorChooser;
    JDialog dialog;
    protected static final String EDIT = "edit";

    public ColorEditor() {
        button = new JButton();
        button.setActionCommand(EDIT);
        button.addActionListener(this);
        button.setBorderPainted(false);

        //Set up the dialog that the button brings up.
        colorChooser = new JColorChooser();
        dialog = JColorChooser.createDialog(button,
                                        "Pick a Color",
                                        true,  //modal
                                        colorChooser,
                                        this,  //OK button handler
                                        null); //no CANCEL button handler
    }

    public void actionPerformed(ActionEvent e) {
        if (EDIT.equals(e.getActionCommand())) {
            //The user has clicked the cell, so
            //bring up the dialog.
            button.setBackground(currentColor);
            colorChooser.setColor(currentColor);
            dialog.setVisible(true);

            fireEditingStopped(); //Make the renderer reappear.

        } else { //User pressed dialog's "OK" button.
            currentColor = colorChooser.getColor();
        }
    }

    //Implement the one CellEditor method that AbstractCellEditor doesn't.
    public Object getCellEditorValue() {
        return currentColor;
    }

    //Implement the one method defined by TableCellEditor.
    public Component getTableCellEditorComponent(JTable table,
                                                 Object value,
                                                 boolean isSelected,
                                                 int row,
                                                 int column) {
        currentColor = (Color)value;
        return button;
    }
}

最令人困惑的可能要属fireEditingStopped, 这个方法可以让编辑器不会保持活跃, 在没有察觉到编辑时使用render进行渲染处理。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值