有时候我们需要在JTable中嵌入JButton,使得点击某个JTable单元格时,用户感觉通过JButton触发了响应事件。下面我们看看为JTable单元格添加按钮效果和响应事件的方法。以下示例实现的效果为:点击jtable中的button,button上的数字自动加1,并将加1后得到的数字正确显示在button上。
一、添加按钮显示效果
JTable中,单元格的数据显示默认是JTable的效果。如果我们想要按钮显示的效果的话,需要实现swing接口:javax.swing.table.TableCellRenderer,来改变单元格默认的渲染方法。
自定义渲染器如下:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 |
package
TableButton
;
import java.awt.BorderLayout ; import java.awt.Component ; import javax.swing.JButton ; import javax.swing.JPanel ; import javax.swing.JTable ; import javax.swing.table.TableCellRenderer ; public class MyButtonRenderer implements TableCellRenderer { private JPanel panel ; private JButton button ; private int num ; public MyButtonRenderer ( ) { initButton ( ) ; initPanel ( ) ; panel. add (button, BorderLayout. CENTER ) ; } private void initButton ( ) { button = new JButton ( ) ; } private void initPanel ( ) { panel = new JPanel ( ) ; panel. setLayout ( new BorderLayout ( ) ) ; } public Component getTableCellRendererComponent ( JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column ) { num = ( Integer ) value ; button. setText (value == null ? "" : String. valueOf (value ) ) ; return panel ; } } |
二、添加按钮响应事件
第1步中我们为表格添加了渲染器,但是渲染器只负责显示效果,要想点击”按钮“之后有响应,还得跟单元格的编辑器有关。点击表格是会触发表格的编辑时间,所以我们按钮的响应事件可以写在编辑器中,我们需要修改表格的默认编辑器实现。
swing中有个类javax.swing.DefaultCellEditor提供对单元格内插入JTextField/JComboBox/JCheckbox这3种控件,但是不提供对JButton的支持(1.7里不支持,不代表以后不会支持),所以我们得用到另外一个类自己写TableCellEditor,这个类是avax.swing.AbstractCellEditor。是不是类名弄晕了?我也是。。。
自定义编辑器如下:
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 |
package
TableButton
;
import java.awt.BorderLayout ; import java.awt.Component ; import java.awt.event.ActionEvent ; import java.awt.event.ActionListener ; import javax.swing.AbstractCellEditor ; import javax.swing.JButton ; import javax.swing.JOptionPane ; import javax.swing.JPanel ; import javax.swing.JTable ; import javax.swing.table.TableCellEditor ; public class MyButtonEditor extends AbstractCellEditor implements TableCellEditor { /** * serialVersionUID */ private static final long serialVersionUID = -6546334664166791132L ; private JPanel panel ; private JButton button ; private int num ; public MyButtonEditor ( ) { initButton ( ) ; initPanel ( ) ; panel. add ( this. button, BorderLayout. CENTER ) ; } private void initButton ( ) { button = new JButton ( ) ; button. addActionListener ( new ActionListener ( ) { public void actionPerformed ( ActionEvent e ) { int res = JOptionPane. showConfirmDialog ( null, "Do you want to add 1 to it?", "choose one", JOptionPane. YES_NO_OPTION ) ; if (res == JOptionPane. YES_OPTION ) { num ++; } //stopped!!!! fireEditingStopped ( ) ; } } ) ; } private void initPanel ( ) { panel = new JPanel ( ) ; panel. setLayout ( new BorderLayout ( ) ) ; } @Override public Component getTableCellEditorComponent ( JTable table, Object value, boolean isSelected, int row, int column ) { num = ( Integer ) value ; button. setText (value == null ? "" : String. valueOf (value ) ) ; return panel ; } @Override public Object getCellEditorValue ( ) { return num ; } } |
需要注意的是得重写TableModel的isCellEditable方法,因为只有为重写Editor的列开启了可编辑功能,单元格才能被编辑,也就才能出发按钮单击事件。在下一段代码中有体现。
另外要注意得禁止掉JTable的行选中功能。否则我们再点击按钮时,JTable不知道是响应为”行选中“还是”按钮单击事件“。
三、测试代码
1
2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 |
package
TableButton
;
import java.awt.Color ; import java.awt.EventQueue ; import javax.swing.JFrame ; import javax.swing.JPanel ; import javax.swing.JScrollPane ; import javax.swing.JTable ; import javax.swing.table.DefaultTableModel ; public class TestTable { private JFrame frame ; private JTable table ; private Object [ ] [ ] data = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } } ; 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 ( ) ; } } } ) ; } public TestTable ( ) { frame = new JFrame ( ) ; frame. setBounds ( 100, 100, 450, 300 ) ; frame. setDefaultCloseOperation ( JFrame. EXIT_ON_CLOSE ) ; frame. getContentPane ( ). setLayout ( null ) ; JPanel panel = new JPanel ( ) ; panel. setBounds ( 10, 10, 414, 242 ) ; frame. getContentPane ( ). add (panel ) ; panel. setLayout ( null ) ; JScrollPane scrollPane = new JScrollPane ( ) ; scrollPane. setBounds ( 10, 10, 394, 222 ) ; panel. add (scrollPane ) ; table = new JTable ( ) ; scrollPane. setViewportView (table ) ; table. setModel ( new DefaultTableModel ( ) { @Override public Object getValueAt ( int row, int column ) { return data [row ] [column ] ; } @Override public int getRowCount ( ) { return 3 ; } @Override public int getColumnCount ( ) { return 3 ; } @Override public void setValueAt ( Object aValue, int row, int column ) { data [row ] [column ] = aValue ; fireTableCellUpdated (row, column ) ; } @Override public boolean isCellEditable ( int row, int column ) { if (column == 2 ) { return true ; } else { return false ; } } } ) ; table. getColumnModel ( ). getColumn ( 2 ). setCellEditor ( new MyButtonEditor ( ) ) ; table. getColumnModel ( ). getColumn ( 2 ). setCellRenderer ( new MyButtonRenderer ( ) ) ; table. setRowSelectionAllowed ( false ) ; } } |
这个部分真的很复杂很容易出错,可能一个不经意的误用就达不到理想效果。建议使用者对着示例代码好好看好好比对。
五、参考文章
From Java Tutorials:How to User Table
From CSDN:JTable 为单元格添加按钮效果和事件效果
想第一时间看到本站更新?请订阅RSS:花痴痴的网站 | 女程序员园地
原创文章,转载请注明: 转载自花痴痴的网站 | 女程序员园地
本文链接地址: java中JTable 为单元格添加按钮显示效果和按钮响应事件