JTable 为单元格添加按钮效果和事件效果

来源:互联网 发布:zeppelin源码下载 编辑:程序博客网 时间:2024/05/16 11:11

一、添加按钮显示效果

在JTable中,单元格的数据默认是Label的效果,也没有事件。

如果要为单元格添加一个按钮显示效果的话,那么就需要使用到一个swing的接口:javax.swing.table.TableCellRenderer,来改变单元桥格的默认默认渲染方法(DefaultTableCellRenderer),

实现的自定义的渲染器如下:

 
package org.sky.table.render;

import java.awt.Component;

import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.table.TableCellRenderer;

public class MyButtonRender implements TableCellRenderer
{
    private JPanel panel;

    private JButton button;

    public MyButtonRender()
    {
        this.initButton();

        this.initPanel();

        // 添加按钮。
        this.panel.add(this.button);
    }

    private void initButton()
    {
        this.button = new JButton();

        // 设置按钮的大小及位置。
        this.button.setBounds(0, 0, 50, 15);

        // 在渲染器里边添加按钮的事件是不会触发的
        // this.button.addActionListener(new ActionListener()
        // {
        //
        // public void actionPerformed(ActionEvent e)
        // {
        // // TODO Auto-generated method stub
        // }
        // });

    }

    private void initPanel()
    {
        this.panel = new JPanel();

        // panel使用绝对定位,这样button就不会充满整个单元格。
        this.panel.setLayout(null);
    }

    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row,
            int column)
    {
        // 只为按钮赋值即可。也可以作其它操作,如绘背景等。
        this.button.setText(value == null ? "" : String.valueOf(value));

        return this.panel;
    }

}

 

修改表格的渲染器:this.table.getColumnModel().getColumn(2).setCellRenderer(new MyButtonRender());//只有获取到表格的列后才能添加渲染器。

 

二、添加事件

通过第一部已经为表格添加了默认的渲染器,但是还无法触发事件,触发事件是没有反应的,因为在点击表格时,会触发表格的编辑事件,而要想触发渲染的按钮的事件,还需要通过修改表格的默认编辑器来实现:

package org.sky.table.editor; 
import java.awt.Component; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
 
import javax.swing.DefaultCellEditor; 
import javax.swing.JButton; 
import javax.swing.JPanel; 
import javax.swing.JTable; 
import javax.swing.JTextField; 
 
/**
 * 自定义一个往列里边添加按钮的单元格编辑器。最好继承DefaultCellEditor,不然要实现的方法就太多了。
 * 
 */ 
public class MyButtonEditor extends DefaultCellEditor 

 
    /**
     * serialVersionUID
     */ 
    private static final long serialVersionUID = -6546334664166791132L; 
 
    private JPanel panel; 
 
    private JButton button; 
 
    public MyButtonEditor() 
    { 
        // DefautlCellEditor有此构造器,需要传入一个,但这个不会使用到,直接new一个即可。  
        super(new JTextField()); 
 
        // 设置点击几次激活编辑。  
        this.setClickCountToStart(1); 
 
        this.initButton(); 
 
        this.initPanel(); 
 
        // 添加按钮。  
        this.panel.add(this.button); 
    } 
 
    private void initButton() 
    { 
        this.button = new JButton(); 
 
        // 设置按钮的大小及位置。  
        this.button.setBounds(0, 0, 50, 15); 
 
        // 为按钮添加事件。这里只能添加ActionListner事件,Mouse事件无效。  
        this.button.addActionListener(new ActionListener() 
        { 
            public void actionPerformed(ActionEvent e) 
            { 
                // 触发取消编辑的事件,不会调用tableModel的setValue方法。  
                MyButtonEditor.this.fireEditingCanceled(); 
 
                // 这里可以做其它操作。  
                // 可以将table传入,通过getSelectedRow,getSelectColumn方法获取到当前选择的行和列及其它操作等。  
            } 
        }); 
 
    } 
 
    private void initPanel() 
    { 
        this.panel = new JPanel(); 
 
        // panel使用绝对定位,这样button就不会充满整个单元格。  
        this.panel.setLayout(null); 
    } 
 
 
    /**
     * 这里重写父类的编辑方法,返回一个JPanel对象即可(也可以直接返回一个Button对象,但是那样会填充满整个单元格)
     */ 
    @Override 
    public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) 
    { 
        // 只为按钮赋值即可。也可以作其它操作。  
        this.button.setText(value == null ? "" : String.valueOf(value)); 
 
        return this.panel; 
    } 
 
    /**
     * 重写编辑单元格时获取的值。如果不重写,这里可能会为按钮设置错误的值。
     */ 
    @Override 
    public Object getCellEditorValue() 
    { 
        return this.button.getText(); 
    } 
 

修改表格的默认编辑器:

this.table.getColumnModel().getColumn(2).setCellEditor(new MyButtonEditor());

 

这样后就能基本达到效果了。但是还要注意,对列2来说,还需要启用可编辑功能,才行,不然仍然触发不了事件的。

代码片段:

public boolean isCellEditable(int row, int column) 

    // 带有按钮列的功能这里必须要返回true不然按钮点击时不会触发编辑效果,也就不会触发事件。  
    if (column == 2) 
    { 
        return true; 
    } 
    else 
    { 
        return false; 
    } 

三、测试代码:

测试代码的界面是由windowbuilder插件生成的,懒得自己去写干净的代码了,所以下边的代码有点冗余,大家看表格下边的那段代码即可:

package org.sky.table.frame; 
 
import java.awt.EventQueue; 
 
public class TestTable 

 
    private JFrame frame; 
    private JTable table; 
 
    /**
     * Launch the application.
     */ 
    public static void main(String[] args) 
    { 
        EventQueue.invokeLater(new Runnable() 
        { 
            public void run() 
            { 
                try 
                { 
                    TestTable window = new TestTable(); 
                    window.frame.setVisible(true); 
                } 
                catch (Exception e) 
                { 
                    e.printStackTrace(); 
                } 
            } 
        }); 
    } 
 
    /**
     * Create the application.
     */ 
    public TestTable() 
    { 
        this.initialize(); 
    } 
 
    /**
     * Initialize the contents of the frame.
     */ 
    private void initialize() 
    { 
        this.frame = new JFrame(); 
        this.frame.setBounds(100, 100, 450, 300); 
        this.frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
        this.frame.getContentPane().setLayout(null); 
 
        JPanel panel = new JPanel(); 
        panel.setBounds(10, 10, 414, 242); 
        this.frame.getContentPane().add(panel); 
        panel.setLayout(null); 
 
        JScrollPane scrollPane = new JScrollPane(); 
        scrollPane.setBounds(10, 10, 394, 222); 
        panel.add(scrollPane); 
 
        this.table = new JTable(); 
        scrollPane.setViewportView(this.table); 
 
        this.table.setModel(new DefaultTableModel() 
        { 
            @Override 
            public Object getValueAt(int row, int column) 
            { 
                return (row + 1) * (column + 1); 
            } 
 
            @Override 
            public int getRowCount() 
            { 
                return 3; 
            } 
 
            @Override 
            public int getColumnCount() 
            { 
                return 3; 
            } 
 
            @Override 
            public void setValueAt(Object aValue, int row, int column) 
            { 
                System.out.println(aValue + "  setValueAt"); 
            } 
 
            @Override 
            public boolean isCellEditable(int row, int column) 
            { 
                // 带有按钮列的功能这里必须要返回true不然按钮点击时不会触发编辑效果,也就不会触发事件。  
                if (column == 2) 
                { 
                    return true; 
                } 
                else 
                { 
                    return false; 
                } 
            } 
        }); 
 
        this.table.getColumnModel().getColumn(2).setCellEditor(new MyButtonEditor()); 
 
        this.table.getColumnModel().getColumn(2).setCellRenderer(new MyButtonRender()); 
 
        this.table.setRowSelectionAllowed(false);// 禁止表格的选择功能。不然在点击按钮时表格的整行都会被选中。也可以通过其它方式来实现。  
    } 

0 0