Java Swing編程:JTable表格
表格是GUI編程中使用較多,但也是最麻煩的一個(gè)控件之一。表格是用來顯示二維數(shù)據(jù),提供編輯,選擇等功能。如果只是顯示數(shù)據(jù),這還是非常easy的,只要在JTable中傳入二維數(shù)組或集合就可以了,eg
- public class SimpleTable
- {
- JFrame jf = new JFrame("簡單表格");
- JTable table;
- //定義二維數(shù)組作為表格數(shù)據(jù)
- Object[][] tableData =
- {
- new Object[]{"李清照" , 29 , "女"},
- new Object[]{"蘇格拉底", 56 , "男"},
- new Object[]{"李白", 35 , "男"},
- new Object[]{"弄玉", 18 , "女"},
- new Object[]{"虎頭" , 2 , "男"}
- };
- //定義一維數(shù)據(jù)作為列標(biāo)題
- Object[] columnTitle = {"姓名" , "年齡" , "性別"};
- public void init()
- {
- //以二維數(shù)組和一維數(shù)組來創(chuàng)建一個(gè)JTable對(duì)象
- table = new JTable(tableData , columnTitle);
- //將JTable對(duì)象放在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();
- }
- }
下面舉個(gè)JTable表格調(diào)整和選擇方式的例子,eg
- public class AdjustingWidth
- {
- JFrame jf = new JFrame("調(diào)整表格列寬");
- JMenuBar menuBar = new JMenuBar();
- JMenu adjustModeMenu = new JMenu("調(diào)整方式");
- JMenu selectUnitMenu = new JMenu("選擇單元");
- JMenu selectModeMenu = new JMenu("選擇方式");
- //定義5個(gè)單選框按鈕,用以控制表格的寬度調(diào)整方式
- JRadioButtonMenuItem[] adjustModesItem = new JRadioButtonMenuItem[5];
- //定義3個(gè)單選框按鈕,用以控制表格的選擇方式
- 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();
- //定義一個(gè)int類型的數(shù)組,用于保存表格所有的寬度調(diào)整方式
- 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;
- //定義二維數(shù)組作為表格數(shù)據(jù)
- Object[][] tableData =
- {
- new Object[]{"李清照" , 29 , "女"},
- new Object[]{"蘇格拉底", 56 , "男"},
- new Object[]{"李白", 35 , "男"},
- new Object[]{"弄玉", 18 , "女"},
- new Object[]{"虎頭" , 2 , "男"}
- };
- //定義一維數(shù)據(jù)作為列標(biāo)題
- Object[] columnTitle = {"姓名" , "年齡" , "性別"};
- public void init()
- {
- //以二維數(shù)組和一維數(shù)組來創(chuàng)建一個(gè)JTable對(duì)象
- table = new JTable(tableData , columnTitle);
- //-----------為窗口安裝設(shè)置表格調(diào)整方式的菜單-----------
- adjustModesItem[0] = new JRadioButtonMenuItem("只調(diào)整表格");
- adjustModesItem[1] = new JRadioButtonMenuItem("只調(diào)整下一列");
- adjustModesItem[2] = new JRadioButtonMenuItem("平均調(diào)整余下列");
- adjustModesItem[3] = new JRadioButtonMenuItem("只調(diào)整最后一列");
- adjustModesItem[4] = new JRadioButtonMenuItem("平均調(diào)整所有列");
- menuBar.add(adjustModeMenu);
- for (int i = 0; i < adjustModesItem.length ; i++)
- {
- //默認(rèn)選中第三個(gè)菜單項(xiàng),即對(duì)應(yīng)表格默認(rèn)的寬度調(diào)整方式
- if (i == 2)
- {
- adjustModesItem[i].setSelected(true);
- }
- adjustBg.add(adjustModesItem[i]);
- adjustModeMenu.add(adjustModesItem[i]);
- final int index = i;
- //為設(shè)置調(diào)整方式的菜單項(xiàng)添加監(jiān)聽器
- adjustModesItem[i].addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent evt)
- {
- //如果當(dāng)前菜單項(xiàng)處于選中狀態(tài),表格使用對(duì)應(yīng)的調(diào)整方式
- if (adjustModesItem[index].isSelected())
- {
- table.setAutoResizeMode(adjustModes[index]);
- }
- }
- });
- }
- //-----------為窗口安裝設(shè)置表格選擇方式的菜單-----------
- selectModesItem[0] = new JRadioButtonMenuItem("無限制");
- selectModesItem[1] = new JRadioButtonMenuItem("單獨(dú)的連續(xù)區(qū)");
- selectModesItem[2] = new JRadioButtonMenuItem("單選");
- menuBar.add(selectModeMenu);
- for (int i = 0; i < selectModesItem.length ; i++)
- {
- //默認(rèn)選中第一個(gè)菜單項(xiàng),即對(duì)應(yīng)表格默認(rèn)的選擇方式
- if (i == 0)
- {
- selectModesItem[i].setSelected(true);
- }
- selectBg.add(selectModesItem[i]);
- selectModeMenu.add(selectModesItem[i]);
- final int index = i;
- //為設(shè)置選擇方式的菜單項(xiàng)添加監(jiān)聽器
- selectModesItem[i].addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent evt)
- {
- //如果當(dāng)前菜單項(xiàng)處于選中狀態(tài),表格使用對(duì)應(yīng)的選擇方式
- if (selectModesItem[index].isSelected())
- {
- table.getSelectionModel().setSelectionMode(selectModes[index]);
- }
- }
- });
- }
- menuBar.add(selectUnitMenu);
- //-----------為窗口安裝設(shè)置表格選擇單元的菜單-----------
- rowsItem.setSelected(table.getRowSelectionAllowed());
- columnsItem.setSelected(table.getColumnSelectionAllowed());
- cellsItem.setSelected(table.getCellSelectionEnabled());
- rowsItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- table.clearSelection();
- //如果該菜單項(xiàng)處于選中狀態(tài),設(shè)置表格的選擇單元是行
- table.setRowSelectionAllowed(rowsItem.isSelected());
- //如果選擇行、選擇列同時(shí)被選中,其實(shí)質(zhì)是選擇單元格
- cellsItem.setSelected(table.getCellSelectionEnabled());
- }
- });
- selectUnitMenu.add(rowsItem);
- columnsItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- table.clearSelection();
- //如果該菜單項(xiàng)處于選中狀態(tài),設(shè)置表格的選擇單元是列
- table.setColumnSelectionAllowed(columnsItem.isSelected());
- //如果選擇行、選擇列同時(shí)被選中,其實(shí)質(zhì)是選擇單元格
- cellsItem.setSelected(table.getCellSelectionEnabled());
- }
- });
- selectUnitMenu.add(columnsItem);
- cellsItem.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- table.clearSelection();
- //如果該菜單項(xiàng)處于選中狀態(tài),設(shè)置表格的選擇單元是單元格
- table.setCellSelectionEnabled(cellsItem.isSelected());
- //該選項(xiàng)的改變會(huì)同時(shí)影響選擇行、選擇列兩個(gè)菜單
- rowsItem.setSelected(table.getRowSelectionAllowed());
- columnsItem.setSelected(table.getColumnSelectionAllowed());
- }
- });
- selectUnitMenu.add(cellsItem);
- jf.setJMenuBar(menuBar);
- //分別獲取表格的三個(gè)表格列,并設(shè)置三列的最小寬度,最佳寬度和最大寬度
- 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對(duì)象放在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來保存表格中的所有狀態(tài)數(shù)據(jù),采用TableColumnModel來保存所有列的數(shù)據(jù)。eg
- public class TestDefaultTableModel
- {
- JFrame mainWin = new JFrame("管理數(shù)據(jù)行、數(shù)據(jù)列");
- 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 actionPerformed(ActionEvent event)
- {
- //獲取所有選中列的索引
- int[] selected = table.getSelectedColumns();
- TableColumnModel columnModel = table.getColumnModel();
- //依次把每一個(gè)選中的列隱藏起來,并使用List把這些列保存起來
- for (int i = selected.length - 1; i >= 0; i--)
- {
- TableColumn column = columnModel.getColumn(selected[i]);
- table.removeColumn(column);
- //把隱藏的列保存起來,確保以后可以顯示出來
- hiddenColumns.add(column);
- }
- }
- });
- 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)
- {
- //創(chuàng)建一個(gè)String數(shù)組作為新增行的內(nèi)容
- 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個(gè)JTable
前面講的表格,單元格都是字符串,這是由于我們傳入的都是DefaultTableModel它最終調(diào)用toString方法來繪制表格,具體自定義單元格的方法如下,eg
- public class TestTableCellRenderer
- {
- JFrame jf = new JFrame("使用單元格繪制器");
- JTable table;
- //定義二維數(shù)組作為表格數(shù)據(jù)
- 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}
- };
- //定義一維數(shù)據(jù)作為列標(biāo)題
- String[] columnTitle = {"姓名" , "年齡" , "性別" , "主頭像" , "是否中國人"};
- public void init()
- {
- //以二維數(shù)組和一維數(shù)組來創(chuàng)建一個(gè)ExtendedTableModel對(duì)象
- ExtendedTableModel model = new ExtendedTableModel(columnTitle , tableData);
- //以ExtendedTableModel來創(chuàng)建JTable
- table = new JTable( model);
- table.setRowSelectionAllowed(false);
- table.setRowHeight(40);
- //獲取第三列
- TableColumn lastColumn = table.getColumnModel().getColumn(2);
- //對(duì)第三列采用自定義的單元格繪制器
- lastColumn.setCellRenderer(new GenderTableCellRenderer());
- //將JTable對(duì)象放在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
- {
- //重新提供一個(gè)構(gòu)造器,該構(gòu)造器的實(shí)現(xiàn)委托給DefaultTableModel父類
- public ExtendedTableModel(String[] columnNames , Object[][] cells)
- {
- super(cells , columnNames);
- }
- //重寫getColumnClass方法,根據(jù)每列的第一個(gè)值來返回其真實(shí)的數(shù)據(jù)類型
- public Class getColumnClass(int c)
- {
- return getValueAt(0 , c).getClass();
- }
- }
- class GenderTableCellRenderer extends JPanel implements TableCellRenderer
- {
- private String cellValue;
- //定義圖標(biāo)的寬度和高度
- 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;
- //設(shè)置選中狀態(tài)下繪制邊框
- if (hasFocus)
- {
- setBorder(UIManager.getBorder("Table.focusCellHighlightBorder"));
- }
- else
- {
- setBorder(null);
- }
- return this;
- }
- //重寫paint方法,負(fù)責(zé)繪制該單元格內(nèi)容
- public void paint(Graphics g)
- {
- //如果表格值為"男"或"male",則繪制一個(gè)男性圖標(biāo)
- if (cellValue.equalsIgnoreCase("男")
- || cellValue.equalsIgnoreCase("male"))
- {
- drawImage(g , new ImageIcon("icon/male.gif").getImage());
- }
- //如果表格值為"女"或"female",則繪制一個(gè)女性圖標(biāo)
- if (cellValue.equalsIgnoreCase("女")
- || cellValue.equalsIgnoreCase("female"))
- {
- drawImage(g , new ImageIcon("icon/female.gif").getImage());
- }
- }
- //繪制圖標(biāo)的方法
- private void drawImage(Graphics g , Image image)
- {
- g.drawImage(image, (getWidth() - ICON_WIDTH ) / 2
- , (getHeight() - ICON_HEIGHT) / 2 , null);
- }
- }
我這里只是實(shí)現(xiàn)了每列不同的控件,大家還可以自定義一個(gè)表格每行每列都是不同的控件,那就要得到單元格再setCellRender。
原文鏈接:http://blog.csdn.net/terryzero/article/details/3838423
【編輯推薦】