您的位置:首页 > 其它

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

2013-11-22 22:17 344 查看
一、添加按钮显示效果

在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);// 禁止表格的选择功能。不然在点击按钮时表格的整行都会被选中。也可以通过其它方式来实现。

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: