Java Swing组件编程之JTable表格用法实例详解
作者:toto1297488504
这篇文章主要介绍了Java Swing组件编程之JTable表格用法,结合实例形式详细分析了Swing组件中JTable表格的常见定义与使用方法,需要的朋友可以参考下
本文实例讲述了Java Swing组件编程之JTable表格用法。分享给大家供大家参考,具体如下:
表格是GUI编程中使用较多,但也是最麻烦的一个控件之一。表格是用来显示二维数据,提供编辑,选择等功能。如果只是显示数据,这还是非常easy的,只要在JTable中传入二维数组或集合就可以了。
示例1:
package awtDemo; import javax.swing.JFrame; import javax.swing.JScrollPane; import javax.swing.JTable; public class SimpleTable { JFrame jf = new JFrame("简单表格 - www.jb51.net"); JTable table; //定义二维数组作为表格数据 Object[][] tableData = { new Object[]{"李清照" , 29 , "女"}, new Object[]{"苏格拉底", 56 , "男"}, new Object[]{"李白", 35 , "男"}, new Object[]{"弄玉", 18 , "女"}, new Object[]{"虎头" , 2 , "男"} }; //定义一维数据作为列标题 Object[] columnTitle = {"姓名" , "年龄" , "性别"}; public void init() { //以二维数组和一维数组来创建一个JTable对象 table = new JTable(tableData , columnTitle); //将JTable对象放在JScrollPane中,并将该JScrollPane放在窗口中显示出来 jf.add(new JScrollPane(table)); jf.pack(); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } public static void main(String[] args) { new SimpleTable().init(); } }
运行效果:
下面举个JTable表格调整和选择方式的例子。
示例2:
package awtDemo; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ButtonGroup; import javax.swing.JCheckBoxMenuItem; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JRadioButtonMenuItem; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.ListSelectionModel; import javax.swing.table.TableColumn; public class AdjustingWidth { JFrame jf = new JFrame("调整表格列宽 - www.jb51.net"); JMenuBar menuBar = new JMenuBar(); JMenu adjustModeMenu = new JMenu("调整方式"); JMenu selectUnitMenu = new JMenu("选择单元"); JMenu selectModeMenu = new JMenu("选择方式"); //定义5个单选框按钮,用以控制表格的宽度调整方式 JRadioButtonMenuItem[] adjustModesItem = new JRadioButtonMenuItem[5]; //定义3个单选框按钮,用以控制表格的选择方式 JRadioButtonMenuItem[] selectModesItem = new JRadioButtonMenuItem[3]; JCheckBoxMenuItem rowsItem = new JCheckBoxMenuItem("选择行"); JCheckBoxMenuItem columnsItem = new JCheckBoxMenuItem("选择列"); JCheckBoxMenuItem cellsItem = new JCheckBoxMenuItem("选择单元格"); ButtonGroup adjustBg = new ButtonGroup(); ButtonGroup selectBg = new ButtonGroup(); //定义一个int类型的数组,用于保存表格所有的宽度调整方式 int[] adjustModes = new int[]{ JTable.AUTO_RESIZE_OFF, JTable.AUTO_RESIZE_NEXT_COLUMN, JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS, JTable.AUTO_RESIZE_LAST_COLUMN, JTable.AUTO_RESIZE_ALL_COLUMNS }; int[] selectModes = new int[]{ ListSelectionModel.MULTIPLE_INTERVAL_SELECTION , ListSelectionModel.SINGLE_INTERVAL_SELECTION , ListSelectionModel.SINGLE_SELECTION }; JTable table; //定义二维数组作为表格数据 Object[][] tableData = { new Object[]{"李清照" , 29 , "女"}, new Object[]{"苏格拉底", 56 , "男"}, new Object[]{"李白", 35 , "男"}, new Object[]{"弄玉", 18 , "女"}, new Object[]{"虎头" , 2 , "男"} }; //定义一维数据作为列标题 Object[] columnTitle = {"姓名" , "年龄" , "性别"}; public void init() { //以二维数组和一维数组来创建一个JTable对象 table = new JTable(tableData , columnTitle); //-----------为窗口安装设置表格调整方式的菜单----------- adjustModesItem[0] = new JRadioButtonMenuItem("只调整表格"); adjustModesItem[1] = new JRadioButtonMenuItem("只调整下一列"); adjustModesItem[2] = new JRadioButtonMenuItem("平均调整余下列"); adjustModesItem[3] = new JRadioButtonMenuItem("只调整最后一列"); adjustModesItem[4] = new JRadioButtonMenuItem("平均调整所有列"); menuBar.add(adjustModeMenu); for (int i = 0; i < adjustModesItem.length ; i++) { //默认选中第三个菜单项,即对应表格默认的宽度调整方式 if (i == 2) { adjustModesItem[i].setSelected(true); } adjustBg.add(adjustModesItem[i]); adjustModeMenu.add(adjustModesItem[i]); final int index = i; //为设置调整方式的菜单项添加监听器 adjustModesItem[i].addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { //如果当前菜单项处于选中状态,表格使用对应的调整方式 if (adjustModesItem[index].isSelected()) { table.setAutoResizeMode(adjustModes[index]); } } public void actionPerformed1(ActionEvent e) { // TODO 自动生成的方法存根 } }); } //-----------为窗口安装设置表格选择方式的菜单----------- selectModesItem[0] = new JRadioButtonMenuItem("无限制"); selectModesItem[1] = new JRadioButtonMenuItem("单独的连续区"); selectModesItem[2] = new JRadioButtonMenuItem("单选"); menuBar.add(selectModeMenu); for (int i = 0; i < selectModesItem.length ; i++) { //默认选中第一个菜单项,即对应表格默认的选择方式 if (i == 0) { selectModesItem[i].setSelected(true); } selectBg.add(selectModesItem[i]); selectModeMenu.add(selectModesItem[i]); final int index = i; //为设置选择方式的菜单项添加监听器 selectModesItem[i].addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { //如果当前菜单项处于选中状态,表格使用对应的选择方式 if (selectModesItem[index].isSelected()) { table.getSelectionModel().setSelectionMode(selectModes[index]); } } }); } menuBar.add(selectUnitMenu); //-----------为窗口安装设置表格选择单元的菜单----------- rowsItem.setSelected(table.getRowSelectionAllowed()); columnsItem.setSelected(table.getColumnSelectionAllowed()); cellsItem.setSelected(table.getCellSelectionEnabled()); rowsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { table.clearSelection(); //如果该菜单项处于选中状态,设置表格的选择单元是行 table.setRowSelectionAllowed(rowsItem.isSelected()); //如果选择行、选择列同时被选中,其实质是选择单元格 cellsItem.setSelected(table.getCellSelectionEnabled()); } }); selectUnitMenu.add(rowsItem); columnsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { table.clearSelection(); //如果该菜单项处于选中状态,设置表格的选择单元是列 table.setColumnSelectionAllowed(columnsItem.isSelected()); //如果选择行、选择列同时被选中,其实质是选择单元格 cellsItem.setSelected(table.getCellSelectionEnabled()); } }); selectUnitMenu.add(columnsItem); cellsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { table.clearSelection(); //如果该菜单项处于选中状态,设置表格的选择单元是单元格 table.setCellSelectionEnabled(cellsItem.isSelected()); //该选项的改变会同时影响选择行、选择列两个菜单 rowsItem.setSelected(table.getRowSelectionAllowed()); columnsItem.setSelected(table.getColumnSelectionAllowed()); } }); selectUnitMenu.add(cellsItem); jf.setJMenuBar(menuBar); //分别获取表格的三个表格列,并设置三列的最小宽度,最佳宽度和最大宽度 TableColumn nameColumn = table.getColumn(columnTitle[0]); nameColumn.setMinWidth(40); TableColumn ageColumn = table.getColumn(columnTitle[1]); ageColumn.setPreferredWidth(50); TableColumn genderColumn = table.getColumn(columnTitle[2]); genderColumn.setMaxWidth(50); //将JTable对象放在JScrollPane中,并将该JScrollPane放在窗口中显示出来 jf.add(new JScrollPane(table)); System.out.println(table.getModel()); jf.pack(); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } public static void main(String[] args) { new AdjustingWidth().init(); } }
运行效果:
和JList,JTree类似,JTable采用TableModel来保存表格中的所有状态数据,采用TableColumnModel来保存所有列的数据。
示例3:
package awtDemo; import java.awt.BorderLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.ArrayList; import javax.swing.JFrame; import javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; public class TestDefaultTableModel { JFrame mainWin = new JFrame("管理数据行、数据列 - www.jb51.net"); final int COLUMN_COUNT = 5; DefaultTableModel model; JTable table; //用于保存被隐藏列的List集合 ArrayList<TableColumn> hiddenColumns = new ArrayList<TableColumn>(); public void init() { model = new DefaultTableModel(COLUMN_COUNT ,COLUMN_COUNT); for (int i = 0; i < COLUMN_COUNT ; i++ ) { for (int j = 0; j < COLUMN_COUNT ; j++ ) { model.setValueAt("老单元格值 " + i + " " + j , i , j); } } table = new JTable(model); mainWin.add(new JScrollPane(table), BorderLayout.CENTER); //为窗口安装菜单 JMenuBar menuBar = new JMenuBar(); mainWin.setJMenuBar(menuBar); JMenu tableMenu = new JMenu("管理"); menuBar.add(tableMenu); JMenuItem hideColumnsItem = new JMenuItem("隐藏选中列"); hideColumnsItem.addActionListener(new ActionListener() { public void actionPerformed1(ActionEvent event) { //获取所有选中列的索引 int[] selected = table.getSelectedColumns(); TableColumnModel columnModel = table.getColumnModel(); //依次把每一个选中的列隐藏起来,并使用List把这些列保存起来 for (int i = selected.length - 1; i >= 0; i--) { TableColumn column = columnModel.getColumn(selected[i]); table.removeColumn(column); //把隐藏的列保存起来,确保以后可以显示出来 hiddenColumns.add(column); } } @Override public void actionPerformed(ActionEvent e) { // TODO 自动生成的方法存根 } }); tableMenu.add(hideColumnsItem); JMenuItem showColumnsItem = new JMenuItem("显示隐藏列"); showColumnsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //把所有隐藏列依次显示出来 for (TableColumn tc : hiddenColumns) { //依次把所有隐藏的列显示出来 table.addColumn(tc); } //清空保存隐藏列的List集合 hiddenColumns.clear(); } }); tableMenu.add(showColumnsItem); JMenuItem addColumnItem = new JMenuItem("插入选中列"); addColumnItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //获取所有选中列的索引 int[] selected = table.getSelectedColumns(); TableColumnModel columnModel = table.getColumnModel(); //依次把选中的列添加到JTable之后 for (int i = selected.length - 1; i >= 0; i--) { TableColumn column = columnModel.getColumn(selected[i]); table.addColumn(column); } } }); tableMenu.add(addColumnItem); JMenuItem addRowItem = new JMenuItem("增加行"); addRowItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //创建一个String数组作为新增行的内容 String[] newCells = new String[COLUMN_COUNT]; for (int i = 0; i < newCells.length; i++) { newCells[i] = "新单元格值 " + model.getRowCount() + " " + i; } //向TableModel中新增一行。 model.addRow(newCells); } }); tableMenu.add(addRowItem); JMenuItem removeRowsItem = new JMenuItem("删除选中行"); removeRowsItem.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { //获取所有选中行 int[] selected = table.getSelectedRows(); //依次删除所有选中行 for (int i = selected.length - 1; i >= 0; i--) { model.removeRow(selected[i]); } } }); tableMenu.add(removeRowsItem); mainWin.pack(); mainWin.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); mainWin.setVisible(true); } public static void main(String[] args) { new TestDefaultTableModel().init(); } }
运行效果:
但要注意列的增加,只是将原来隐藏的列显示,而不是真正增加列,你要新增的话那就重新new个JTable
前面讲的表格,单元格都是字符串,这是由于我们传入的都是DefaultTableModel它最终调用toString方法来绘制表格,具体自定义单元格的方法如下,
示例4:
public class TestTableCellRenderer { JFrame jf = new JFrame("使用单元格绘制器"); JTable table; //定义二维数组作为表格数据 Object[][] tableData = { new Object[]{"李清照" , 29 , "女" , new ImageIcon("icon/3.gif") , true}, new Object[]{"苏格拉底", 56 , "男" , new ImageIcon("icon/1.gif") , false}, new Object[]{"李白", 35 , "男" , new ImageIcon("icon/4.gif") , true}, new Object[]{"弄玉", 18 , "女" , new ImageIcon("icon/2.gif") , true}, new Object[]{"虎头" , 2 , "男" , new ImageIcon("icon/5.gif") , true} }; //定义一维数据作为列标题 String[] columnTitle = {"姓名" , "年龄" , "性别" , "主头像" , "是否中国人"}; public void init() { //以二维数组和一维数组来创建一个ExtendedTableModel对象 ExtendedTableModel model = new ExtendedTableModel(columnTitle , tableData); //以ExtendedTableModel来创建JTable table = new JTable( model); table.setRowSelectionAllowed(false); table.setRowHeight(40); //获取第三列 TableColumn lastColumn = table.getColumnModel().getColumn(2); //对第三列采用自定义的单元格绘制器 lastColumn.setCellRenderer(new GenderTableCellRenderer()); //将JTable对象放在JScrollPane中,并将该JScrollPane放在窗口中显示出来 jf.add(new JScrollPane(table)); jf.pack(); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); jf.setVisible(true); } public static void main(String[] args) { new TestTableCellRenderer().init(); } }
class ExtendedTableModel extends DefaultTableModel { //重新提供一个构造器,该构造器的实现委托给DefaultTableModel父类 public ExtendedTableModel(String[] columnNames , Object[][] cells) { super(cells , columnNames); } //重写getColumnClass方法,根据每列的第一个值来返回其真实的数据类型 public Class getColumnClass(int c) { return getValueAt(0 , c).getClass(); } }
class GenderTableCellRenderer extends JPanel implements TableCellRenderer { private String cellValue; //定义图标的宽度和高度 final int ICON_WIDTH = 23; final int ICON_HEIGHT = 21; public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { cellValue = (String)value; //设置选中状态下绘制边框 if (hasFocus) { setBorder(UIManager.getBorder("Table.focusCellHighlightBorder")); } else { setBorder(null); } return this; } //重写paint方法,负责绘制该单元格内容 public void paint(Graphics g) { //如果表格值为"男"或"male",则绘制一个男性图标 if (cellValue.equalsIgnoreCase("男") || cellValue.equalsIgnoreCase("male")) { drawImage(g , new ImageIcon("icon/male.gif").getImage()); } //如果表格值为"女"或"female",则绘制一个女性图标 if (cellValue.equalsIgnoreCase("女") || cellValue.equalsIgnoreCase("female")) { drawImage(g , new ImageIcon("icon/female.gif").getImage()); } } //绘制图标的方法 private void drawImage(Graphics g , Image image) { g.drawImage(image, (getWidth() - ICON_WIDTH ) / 2 , (getHeight() - ICON_HEIGHT) / 2 , null); } }
我这里只是实现了每列不同的控件,大家还可以自定义一个表格每行每列都是不同的控件,那就要得到单元格再setCellRender。
更多关于java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java字符与字符串操作技巧总结》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》
希望本文所述对大家java程序设计有所帮助。