不想多说什么相关的知识,我说不清也不想抄书,如果想明明白白的知道的话可以去翻书,只是现在Swing的相关的教程实在不多,我也是只是略懂些皮毛,为了便于以后自己翻阅便动手写了一个简单的程序,先看截图
JTable的单元有观看模式和编辑模式两个种,默认情况下双击表格中的某一单元格便能进入编辑模式,此时可以对单元格内的内容进行编辑,但默认情况下并没有提供保存的功能。
现在演示的这个表格中“编号”一栏是只读,即你不能编辑,而且在未选中时背景色为黄色。
“价格”一栏的观看模式是在数值前显示一个美元符号,编辑模式时只接收double类型的值,如果输入错误会还原进入编辑前的值。
“类型”一栏显示的了一个JComboBox控件。
“在售”一栏显示的了一个JCheckBox控件。
“试读文件”一栏的观看模式表示的一个字符串用于表示文件的所在位置,编辑模式则显示一个文本框和按钮,即可以直接输入文件位置也可以通过按钮弹出一个文件打开对话框来指定文件。
“删除”一栏就是显示放入一个按钮用于删除这一行。
关于代码我就不多解释了,喽里八嗦不如直接看代码来的明白,我认为我的代码应该不难明白。
TableFrame.java
import javax.swing.JFrame; public class TableFrame extends JFrame { private TableManager manager; public static void main(String[] args) { // TODO Auto-generated method stub TableFrame frm = new TableFrame(); frm.setVisible(true); } public void initProgram() { manager = new TableManager(); } public TableFrame() { initProgram(); this.setTitle("自定义表格列控件演示"); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); this.setContentPane(new TablePanel(manager)); this.pack(); this.setLocationRelativeTo(null); } }
TablePanel.java
import java.awt.BorderLayout; import java.awt.Dimension; import java.util.ArrayList; import javax.swing.AbstractCellEditor; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; import javax.swing.table.TableColumnModel; import column.ButtonColumn; import column.CheckBoxColumn; import column.ComboColumn; import column.FileColumn; import column.LabelColumn; import column.MoneyColumn; public class TablePanel extends JPanel { private int pWidth = 740; private int pHeight = 480; private TableManager manager; private JTable table; public TablePanel(TableManager manager) { this.manager = manager; this.setLayout(new BorderLayout()); this.setPreferredSize(new Dimension(pWidth,pHeight)); initUI(); } private void initUI() { initTable(); this.add(new InfoPanel(this),BorderLayout.SOUTH); } private void initTable() { table = new JTable(manager.getDtm());//初始化表格控件并设置表格模型 JScrollPane jsp = new JScrollPane(table);//把表格控件放入滚动条面板 table.setRowHeight(20); new LabelColumn(table.getColumn("编号")); new MoneyColumn(table.getColumn("价格")); new ComboColumn(table.getColumn("类别"),manager.getTypeList()); new CheckBoxColumn(table.getColumn("在售")); new FileColumn(table.getColumn("试读文件")); new ButtonColumn(table.getColumn("操作")); this.add(jsp); } public TableManager getManager() { return this.manager; } }
InfoPanel.java
import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.Date; import javax.swing.BorderFactory; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JTextField; import entity.Book; public class InfoPanel extends JPanel { private int pWidth = 640; private int pHeight = 200; private TablePanel mainPanel; private JTextField tfNumber; private JTextField tfName; private JTextField tfPrice; private JTextField tfPublisher; private JTextField tfLogDate; private JTextField tfStroge; private JTextField tfFile; private JCheckBox chkOnShopping; private JComboBox cboType; public InfoPanel(TablePanel mainPanel) { this.mainPanel = mainPanel; this.setPreferredSize(new Dimension(pWidth,pHeight)); this.setLayout(new BorderLayout()); this.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5)); initUI(); } private void initUI() { this.add(setInfoPanel()); this.add(setButtonPanel(),BorderLayout.SOUTH); } private JPanel setInfoPanel() { JPanel pa = new JPanel(); pa.setLayout(new FlowLayout(FlowLayout.LEFT)); pa.setBorder(BorderFactory.createTitledBorder("记录信息")); pa.add(addControlComponent("编号:",tfNumber = new JTextField(),100)); pa.add(addControlComponent("书名:",tfName = new JTextField(),150)); pa.add(addControlComponent("价格:",tfPrice = new JTextField(),80)); pa.add(addControlComponent("类别:",cboType = new JComboBox(mainPanel.getManager().getTypeList()),70)); pa.add(addControlComponent("出版社:",tfPublisher = new JTextField(),170)); pa.add(addControlComponent("库存数:",tfStroge = new JTextField(),70)); pa.add(addControlComponent("在售:",chkOnShopping = new JCheckBox(),30)); pa.add(addControlComponent("登记日期:",tfLogDate = new JTextField(),70)); pa.add(addControlComponent("试读文件:",tfFile = new JTextField(),270)); return pa; } private JPanel addControlComponent(String lbl,JComponent com,int width) { JPanel pa = new JPanel(); pa.add(new JLabel(lbl)); pa.add(com); com.setPreferredSize(new Dimension(width,22)); return pa; } private JPanel setButtonPanel() { JPanel pa = new JPanel(); pa.setPreferredSize(new Dimension(getWidth(),40)); pa.setLayout(new FlowLayout(FlowLayout.RIGHT)); pa.add(setButton("新增")); pa.add(setButton("输出到控制台")); pa.add(setButton("退出")); return pa; } private JButton setButton(String name) { JButton btn = new JButton(name); btn.setPreferredSize(new Dimension(120,25)); btn.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub actionCommand(arg0.getActionCommand()); } }); return btn; } private void actionCommand(String command) { if(command.equals("新增")) { if(validateInput()) { Book book = new Book(); book.setId(Integer.parseInt(tfNumber.getText())); book.setName(tfName.getText()); book.setFile(tfFile.getText()); book.setLogDate(tfLogDate.getText()); book.setOnShopping(chkOnShopping.isSelected()); book.setPrice(Double.valueOf(tfPrice.getText())); book.setPublisher(tfPublisher.getText()); book.setStroge(Integer.valueOf(tfStroge.getText())); book.setType(cboType.getSelectedItem().toString()); mainPanel.getManager().add(book); } } if(command.equals("输出到控制台")) { mainPanel.getManager().output(); } if(command.equals("退出")) { System.exit(0); } } private boolean validateInput() { if(tfNumber.equals("")) { return errorMsg("编号必须输入!",tfNumber);} if(tfName.equals("")) { return errorMsg("书名必须输入!",tfName);} if(tfStroge.equals("")) { return errorMsg("库存数必须输入!",tfName);} return true; } private boolean errorMsg(String msg,JComponent com) { JOptionPane.showConfirmDialog(null, msg,"验证信息",JOptionPane.ERROR_MESSAGE); com.requestFocus(); com.setFocusable(true); return false; } }
TableManager.java
import java.util.ArrayList; import java.util.List; import java.util.Vector; import javax.swing.table.DefaultTableColumnModel; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableColumn; import entity.Book; public class TableManager{ private DefaultTableModel dtm; public DefaultTableModel getDtm() { return dtm; } public void setDtm(DefaultTableModel dtm) { this.dtm = dtm; } public TableManager(){ dtm = new DefaultTableModel(); dtm.addColumn("编号"); dtm.addColumn("书名"); dtm.addColumn("价格"); dtm.addColumn("类别"); dtm.addColumn("出版社"); dtm.addColumn("库存数"); dtm.addColumn("在售"); dtm.addColumn("登记日期"); dtm.addColumn("试读文件"); dtm.addColumn("操作"); loadData(); } public void loadData() { Vector v = new Vector(); v.add("000"); v.add("bbb"); v.add("12.3"); v.add("计算机"); v.add("bbb"); v.add("28"); v.add(true); dtm.addRow(v); Vector v2 = new Vector(); v2.add("001"); v2.add("bbb"); v2.add("45.2"); v2.add("医疗"); v2.add("bbb"); v2.add("435"); v2.add("false"); dtm.addRow(v2); Vector v3 = new Vector(); v3.add("002"); v3.add("bbb"); v3.add("45.2"); v3.add("医疗"); v3.add("bbb"); v3.add("12"); v3.add("true"); dtm.addRow(v3); } public Vector<String> getTypeList() { Vector<String> list = new Vector<String>(); list.add("体育"); list.add("科技"); list.add("计算机"); list.add("历史"); list.add("医疗"); return list; } public void output() { Vector taVaule = dtm.getDataVector(); for(int i=0;i<taVaule.toArray().length;i++) { Vector v = (Vector)taVaule.toArray()[i]; for(int j=0;j<v.toArray().length;j++) System.out.print(v.toArray()[j]+" | "); System.out.println(""); } } public void add(Book book) { // TODO Auto-generated method stub Vector<String> v = new Vector<String>(); v.add(book.getId()+""); v.add(book.getName()); v.add(book.getPrice()+""); v.add(book.getType()); v.add(book.getPublisher()); v.add(book.getStroge()+""); v.add(book.isOnShopping()+""); v.add(book.getLogDate()); v.add(book.getFile()); dtm.addRow(v); } }
ButtonColumn.java
package column; import java.awt.Component; import java.awt.FlowLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.EventObject; import javax.swing.AbstractCellEditor; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class ButtonColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer ,ActionListener{ private JButton renderButton; private JButton editorButton; private DefaultTableModel dtm; private int row; public ButtonColumn(TableColumn tc) { renderButton = new JButton(); editorButton = new JButton(); editorButton.setFocusable(false); editorButton.addActionListener(this); tc.setCellEditor(this); tc.setCellRenderer(this); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { // TODO 当单元格处于编辑状态时 editorButton.setText("删除"); dtm = (DefaultTableModel)table.getModel(); this.row = row; return editorButton; } @Override public Object getCellEditorValue() { // TODO 当单元格的编辑状态结束后调用此方法内的代码 return null; } @Override public boolean shouldSelectCell(EventObject arg0) { // TODO Auto-generated method stub return super.shouldSelectCell(arg0); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // TODO 当单元格处于展示状态时 renderButton.setText("删除"); renderButton.setBackground(hasFocus?UIManager.getColor("Button.background"):table.getSelectionBackground()); return renderButton; } @Override public void actionPerformed(ActionEvent arg0) { this.fireEditingStopped();//立即终止此单元格的编辑状态,使表格模型可以自动更新 dtm.removeRow(this.row); } }
CheckBoxColumn.java
package column; import java.awt.Component; import java.awt.FlowLayout; import javax.swing.AbstractCellEditor; import javax.swing.JCheckBox; import javax.swing.JPanel; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class CheckBoxColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { private JCheckBox renderCheck; private JCheckBox editorCheck; public CheckBoxColumn(TableColumn tc) { renderCheck = new JCheckBox(); editorCheck = new JCheckBox(); tc.setCellEditor(this); tc.setCellRenderer(this); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { // TODO 当单元格处于编辑状态时 editorCheck.setSelected((Boolean)value); editorCheck.setBackground(table.getSelectionBackground()); return editorCheck; } @Override public Object getCellEditorValue() { // TODO 当单元格的编辑状态结束后调用此方法内的代码 return editorCheck.isSelected(); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // TODO 当单元格处于展示状态时 renderCheck.setSelected(Boolean.valueOf(value.toString())); renderCheck.setBackground(isSelected ? table.getSelectionBackground():table.getBackground()); renderCheck.setBackground(hasFocus ? table.getSelectionBackground():table.getBackground()); return renderCheck; } }
ComboColumn.java
package column; import java.awt.Component; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.util.EventObject; import java.util.Vector; import javax.swing.AbstractCellEditor; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JTable; import javax.swing.UIManager; import javax.swing.event.CellEditorListener; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class ComboColumn extends AbstractCellEditor implements TableCellEditor,TableCellRenderer { private JComboBox renderCbo; private JComboBox editorCbo; public ComboColumn(TableColumn tc,Vector list) { tc.setCellEditor(this); tc.setCellRenderer(this); renderCbo = new JComboBox(list); editorCbo = new JComboBox(list); } public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { renderCbo.setBackground(isSelected?table.getSelectionBackground():table.getBackground()); renderCbo.setForeground(isSelected?table.getSelectionForeground():table.getForeground()); renderCbo.setBackground(hasFocus?table.getSelectionBackground():table.getBackground()); renderCbo.setSelectedItem(value); return renderCbo; } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { editorCbo.setSelectedItem(value); return editorCbo; } public Object getCellEditorValue() { return editorCbo.getSelectedItem(); } }
FileColumn.java
package column; import java.awt.Component; import javax.swing.AbstractCellEditor; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class FileColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { private JLabel label; private FileInputPanel fileInputPanel; public FileColumn(TableColumn tc) { label = new JLabel(); fileInputPanel = new FileInputPanel(); tc.setCellEditor(this); tc.setCellRenderer(this); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { // TODO 当单元格处于编辑状态时 if(value!=null) fileInputPanel.setFile(value.toString()); return fileInputPanel; } @Override public Object getCellEditorValue() { // TODO 当单元格的编辑状态结束后调用此方法内的代码 return fileInputPanel.getFile(); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // TODO 当单元格处于展示状态时 if(value!=null) label.setText(value.toString()); label.setOpaque(true); label.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground()); label.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); return label; } }
FileInputPanel.java
package column; import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.JButton; import javax.swing.JFileChooser; import javax.swing.JPanel; import javax.swing.JTextField; public class FileInputPanel extends JPanel { private JTextField tfFile; private JButton btnFile; public void setFile(String file) { tfFile.setText(file);} public String getFile() { return tfFile.getText();} public FileInputPanel() { this.setLayout(new BorderLayout()); this.add(tfFile = new JTextField()); this.add(btnFile = new JButton("..."),BorderLayout.EAST); btnFile.setPreferredSize(new Dimension(20,getHeight())); btnFile.addActionListener(new ActionListener(){ @Override public void actionPerformed(ActionEvent arg0) { // TODO Auto-generated method stub JFileChooser jfc = new JFileChooser("."); int res = jfc.showOpenDialog(null); if(res==JFileChooser.APPROVE_OPTION) tfFile.setText(jfc.getSelectedFile().getPath()); } }); } }
LabelColumn.java
package column; import java.awt.Color; import java.awt.Component; import javax.swing.AbstractCellEditor; import javax.swing.JLabel; import javax.swing.JTable; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class LabelColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { private JLabel renderLabel; public LabelColumn(TableColumn tc) { renderLabel = new JLabel(); tc.setCellEditor(this); tc.setCellRenderer(this); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { // TODO Auto-generated method stub return null; } @Override public Object getCellEditorValue() { // TODO Auto-generated method stub return null; } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // TODO Auto-generated method stub if(value!=null) renderLabel.setText(value.toString()); renderLabel.setOpaque(true); renderLabel.setBackground(isSelected ? table.getSelectionBackground() : new Color(255,255,200)); renderLabel.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground()); return renderLabel; } }
MoneyColumn.java
package column; import java.awt.Component; import java.util.EventObject; import javax.swing.AbstractCellEditor; import javax.swing.JCheckBox; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.JTable; import javax.swing.JTextField; import javax.swing.SwingConstants; import javax.swing.table.TableCellEditor; import javax.swing.table.TableCellRenderer; import javax.swing.table.TableColumn; public class MoneyColumn extends AbstractCellEditor implements TableCellEditor, TableCellRenderer { private JLabel renderLabel; private JTextField editorTextField; private double temp; public MoneyColumn(TableColumn tc) { renderLabel = new JLabel(); renderLabel.setOpaque(true); renderLabel.setHorizontalAlignment(SwingConstants.RIGHT); editorTextField = new JTextField(); tc.setCellEditor(this); tc.setCellRenderer(this); } public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column) { // TODO 当单元格处于编辑状态时 editorTextField.setText(value.toString()); return editorTextField; } @Override public Object getCellEditorValue() { // TODO 当单元格的编辑状态结束后调用此方法内的代码 Double price = null; try{ price = Double.valueOf(editorTextField.getText()); }catch (NumberFormatException e) { JOptionPane.showConfirmDialog(null, "输入的数据有误,有输入数值型数据!","格式错误",JOptionPane.ERROR_MESSAGE); price = temp; }finally { return price; } } @Override public boolean shouldSelectCell(EventObject arg0) { // 当单元格进入编辑状态前执行此处代码 // 将单元格内的字符保存成double类型的变量,以便在输入错误时恢复输入之前时的值 temp = Double.valueOf(editorTextField.getText()); return super.shouldSelectCell(arg0); } @Override public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) { // TODO 当单元格处于展示状态时 renderLabel.setText("$"+value.toString()); renderLabel.setBackground(isSelected ? table.getSelectionBackground():table.getBackground()); return renderLabel; } }
我的QQ:52137124