• JTable用法-实例


    前几篇文章介绍了JTable的基本用法,本文实现一个简单的JTable,算是前文的一个总结,并造福供拷贝党们。

    Swing-JTable用法-入门

    Swing-JTable的渲染器与编辑器使用demo

    Swing-JTable检测单元格数据变更事件

    一、主要功能

    1.数据的增删改;

    2.渲染器:“Vegetarian”列存放布尔值,以checkBox形式显示;“Sport”列存放字符串,以comboBox形式显示;

    3.编辑器:“Name”的编辑器实现一个按钮,按下时弹出对话框;

    4.ToolTip:各列和各单元格均具有自己的ToolTip,且单元格ToolTip与其值相关;

    5.事件:检测单元格值的变更,并输出旧值、新值和单元格坐标。

    二、程序设计

    本程序根据功能可分为6部分,以6个类来实现,分别是:

    Gui.java:实现GUI,成员有:1个JTable,2个按钮;

    MyJTable.java:继承自JTable,重载2个方法:getToolTipText和createDefaultTableHeader,分别实现单元格和表头的toolTip;

    MyTableModel.java:继承自DefaultTableModel,重载1个方法:getColumnClass,实现布尔值的checkBox形式显示。表格的基本功能均已被DefaultTableModel类实现,直接使用就好。如果你还需要对单元格可访问性等细节进行精确控制,可以重载相关方法。

    TableCellListener.java:实现对单元格数据变更的检测。这是通过表格的addPropertyChangeListener方法实现的,而不是基于tableModel的addTableModelListener方法。后者的不足之处在前文中已经分析。

    ButtonEditor.java:实现一个基于按钮的编辑器,被按下时弹出对话框;

    ButtonRenderer.java:实现一个渲染器,可定制单元格的配色。

    三、程序代码

    Gui.java

    package DefaultTableModelDemo;
    import java.awt.Dimension;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.AbstractAction;
    import javax.swing.Action;
    import javax.swing.DefaultCellEditor;
    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JComboBox;
    import javax.swing.JComponent;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextField;
    import javax.swing.table.DefaultTableCellRenderer;
    import javax.swing.table.TableColumn;
    import JButtonTableExample.ButtonEditor;
    import JButtonTableExample.ButtonRenderer;
    
    
    public class Gui extends JPanel {
        
        private Object[] tmpRow = {"tmpName", "tmpDescription"};
        private MyJTable table;
        private JButton addBtn;
        private JButton delBtn;
        private MyTableModel model ;
        
         public Gui() {
             table = new MyJTable();
                table.setPreferredScrollableViewportSize(new Dimension(500, 300));
                table.setFillsViewportHeight(true);
                
                //Create the scroll pane and add the table to it.
                JScrollPane scrollPane = new JScrollPane(table);
                //scrollPane.setPreferredSize(new Dimension(500, 600));
                //scrollPane.set
                //Add the scroll pane to this panel.
                add(scrollPane);
                //set tableModel and data
                model = new MyTableModel();
                String[] columnNames = {"Name",
                        "Description",
                        "Sport",
                        "# of Years",
                        "Vegetarian"};
                Object[][] data = {
                        {"Kathy", "Smith",
                         "Snowboarding", new Integer(5), new Boolean(false)},
                        {"John", "Doe",
                         "Rowing", new Integer(3), new Boolean(true)},
                        {"Sue", "Black",
                         "Knitting", new Integer(2), new Boolean(false)},
                        {"Jane", "White",
                         "Speed reading", new Integer(20), new Boolean(true)},
                        {"Joe", "Brown",
                         "Pool", new Integer(10), new Boolean(false)}
                        };
                model.setDataVector(data, columnNames);
                table.setModel(model);
                //添加渲染器
                table.getColumn("Name").setCellRenderer(new ButtonRenderer());
                //添加编辑器
                table.getColumn("Name").setCellEditor( new ButtonEditor());
                //添加按钮
                addBtn = new JButton("增加");
                addBtn.addActionListener(new ActionListener() {
                    
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        // TODO Auto-generated method stub
                        model.addRow(tmpRow);
                    }
                });
                
                delBtn = new JButton("删除");
                delBtn.addActionListener(new ActionListener() {
                    
                    @Override
                    public void actionPerformed(ActionEvent arg0) {
                        // TODO Auto-generated method stub
                        int rowIndex = table.getSelectedRow();
                        if(rowIndex != -1)
                            model.removeRow(rowIndex);
                    }
                });
                
                add(addBtn);
                add(delBtn);
                
                addDataChangeListener();
                
                //设置列
                setSportsColumn();
         }
         
         private void setSportsColumn(){
                String [] itmes = {"Snowboarding", "Rowing", "Knitting", "Speed reading", "Pool"};
                JComboBox<String> comboBox = new JComboBox<String>(itmes);
                DefaultTableCellRenderer renderer =
                        new DefaultTableCellRenderer();
                renderer.setToolTipText("Click for combo box");
                setColumn("Sport", comboBox, renderer);
                TableColumn col = table.getColumn("Sport");
                //setToolTipText("favorit sport is " + );
            }
         
         public void setColumn(String colName, Object editor, Object renderer) {
                int index = table.getColumnModel().getColumnIndex(colName);
                TableColumn modeColumn = table.getColumnModel().getColumn(index);
                if (editor instanceof JComponent) {
                    setEditor(modeColumn, (JComponent)editor);
                }
                else if (editor instanceof DefaultCellEditor) {
                    modeColumn.setCellEditor((DefaultCellEditor)editor);
                }
                
                if (renderer instanceof DefaultTableCellRenderer) {
                    modeColumn.setCellRenderer((DefaultTableCellRenderer)renderer);
                }
                else if (renderer instanceof ButtonRenderer) {
                    modeColumn.setCellRenderer((ButtonRenderer)renderer);
                }
            }
         
         protected void setEditor(TableColumn column, JComponent component){
             if(component instanceof JTextField )
                column.setCellEditor(new DefaultCellEditor((JTextField) component));
             else if(component instanceof JComboBox )
                column.setCellEditor(new DefaultCellEditor((JComboBox<String>) component));
             else if(component instanceof JCheckBox )
                column.setCellEditor(new DefaultCellEditor((JCheckBox) component));
         }
         
         private void addDataChangeListener(){
             //检测单元格数据变更
             Action action = new AbstractAction()
             {
                 public void actionPerformed(ActionEvent e)
                 {
                     TableCellListener tcl = (TableCellListener)e.getSource();
                     int row = tcl.getRow();
                     int col = tcl.getColumn();
                     Object oldValue = tcl.getOldValue();
                     //if(oldValue == null)
                         //oldValue = "";
                     Object newValue = tcl.getNewValue();       
                     //if(newValue == null)
                         //newValue = "";
                     System.out.printf("cell changed at [%d,%d] : %s -> %s%n",row, col, oldValue, newValue);
                 }
             };
             @SuppressWarnings("unused")
            TableCellListener tcl1 = new TableCellListener(table, action);
             System.out.printf("cell changed%n");
         }
         
         private static void createAndShowGUI() {
                //Create and set up the window.
                JFrame frame = new JFrame("Gui");
                frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
                //Create and set up the content pane.
                Gui newContentPane = new Gui();
                newContentPane.setOpaque(true); //content panes must be opaque
                frame.setContentPane(newContentPane);
    
                //Display the window.
                frame.pack();
                frame.setVisible(true);
            }
    
            public static void main(String[] args) {
                //Schedule a job for the event-dispatching thread:
                //creating and showing this application's GUI.
                javax.swing.SwingUtilities.invokeLater(new Runnable() {
                    public void run() {
                        createAndShowGUI();
                    }
                });
            }
    }

    MyTableModel.java

    package DefaultTableModelDemo;
    
    import javax.swing.table.DefaultTableModel;
    
    public class MyTableModel extends DefaultTableModel{
    
        @Override
        public Class<?> getColumnClass(int columnIndex) {
            if (columnIndex == 4)
                return Boolean.class;
            return super.getColumnClass(columnIndex);
        }
    }

    MyJTable.java

    package DefaultTableModelDemo;
    
    import java.awt.event.MouseEvent;
    
    import javax.swing.JTable;
    import javax.swing.table.JTableHeader;
    import javax.swing.table.TableModel;
    
    public class MyJTable extends JTable{
    
        protected String[] columnToolTips = {null,
                null,
                "The person's favorite sport to participate in is : ",
                "The number of years the person has played the sportis : ",
                "If checked, the person eats no meat"};
        
        //Implement table cell tool tips.
        public String getToolTipText(MouseEvent e) {
            String tip = null;
            java.awt.Point p = e.getPoint();
            int rowIndex = rowAtPoint(p);
            int colIndex = columnAtPoint(p);
            int realColumnIndex = convertColumnIndexToModel(colIndex);
            if(rowIndex < 0)
            {
                //System.out.printf("abnormal rowIndex: %n", rowIndex);
                return null;
            }
            
            if (realColumnIndex == 2) { //Sport column
                tip = columnToolTips[2] 
                       + getValueAt(rowIndex, colIndex);
            } 
            else if (realColumnIndex == 3) { //Years column
                tip = columnToolTips[3] + getValueAt(rowIndex, colIndex);
                 
            }else if (realColumnIndex == 4) { //Veggie column
                TableModel model = getModel();
                String firstName = (String)model.getValueAt(rowIndex,0);
                String lastName = (String)model.getValueAt(rowIndex,1);
                Boolean veggie = (Boolean)model.getValueAt(rowIndex,4);
                if (Boolean.TRUE.equals(veggie)) {
                    tip = firstName + " " + lastName
                          + " is a vegetarian";
                } else {
                    tip = firstName + " " + lastName
                          + " is not a vegetarian";
                }
            } else { 
                //You can omit this part if you know you don't 
                //have any renderers that supply their own tool 
                //tips.
                tip = super.getToolTipText(e);
            }
            return tip;
        }
    
        //Implement table header tool tips.
        protected JTableHeader createDefaultTableHeader() {
            return new JTableHeader(columnModel) {
                public String getToolTipText(MouseEvent e) {
                    String tip = null;
                    java.awt.Point p = e.getPoint();
                    int index = columnModel.getColumnIndexAtX(p.x);
                    int realIndex = 
                            columnModel.getColumn(index).getModelIndex();
                    return columnToolTips[realIndex];
                }
            };
        }
        
        
    }

    TableCellListener.java

    package DefaultTableModelDemo;
    import java.awt.event.*;
    import javax.swing.*;
    import java.beans.*;
    
    /*
     *  This class listens for changes made to the data in the table via the
     *  TableCellEditor. When editing is started, the value of the cell is saved
     *  When editing is stopped the new value is saved. When the oold and new
     *  values are different, then the provided Action is invoked.
     *
     *  The source of the Action is a TableCellListener instance.
     */
    public class TableCellListener implements PropertyChangeListener, Runnable
    {
        private JTable table;
        private Action action;
    
        private int row;
        private int column;
        private Object oldValue;
        private Object newValue;
    
        /**
         *  Create a TableCellListener.
         *
         *  @param table   the table to be monitored for data changes
         *  @param action  the Action to invoke when cell data is changed
         */
        
        public TableCellListener(JTable table, Action action)
        {
            this.table = table;
            this.action = action;
            this.table.addPropertyChangeListener( this );
        }
    
        /**
         *  Create a TableCellListener with a copy of all the data relevant to
         *  the change of data for a given cell.
         *
         *  @param row  the row of the changed cell
         *  @param column  the column of the changed cell
         *  @param oldValue  the old data of the changed cell
         *  @param newValue  the new data of the changed cell
         */
        private TableCellListener(JTable table, int row, int column, Object oldValue, Object newValue)
        {
            this.table = table;
            this.row = row;
            this.column = column;
            this.oldValue = oldValue;
            this.newValue = newValue;
        }
    
        /**
         *  Get the column that was last edited
         *
         *  @return the column that was edited
         */
        public int getColumn()
        {
            return column;
        }
    
        /**
         *  Get the new value in the cell
         *
         *  @return the new value in the cell
         */
        public Object getNewValue()
        {
            return newValue;
        }
    
        /**
         *  Get the old value of the cell
         *
         *  @return the old value of the cell
         */
        public Object getOldValue()
        {
            return oldValue;
        }
    
        /**
         *  Get the row that was last edited
         *
         *  @return the row that was edited
         */
        public int getRow()
        {
            return row;
        }
    
        /**
         *  Get the table of the cell that was changed
         *
         *  @return the table of the cell that was changed
         */
        public JTable getTable()
        {
            return table;
        }
    //
    //  Implement the PropertyChangeListener interface
    //
        @Override
        public void propertyChange(PropertyChangeEvent e)
        {
            //  A cell has started/stopped editing
    
            if ("tableCellEditor".equals(e.getPropertyName()))
            {
                if (table.isEditing()){
                    //System.out.printf("tableCellEditor is editing..%n");
                    processEditingStarted();
                }
                else{
                    //System.out.printf("tableCellEditor editing stopped..%n");
                    processEditingStopped();
                }
                    
            }
        }
    
        /*
         *  Save information of the cell about to be edited
         */
        private void processEditingStarted()
        {
            //  The invokeLater is necessary because the editing row and editing
            //  column of the table have not been set when the "tableCellEditor"
            //  PropertyChangeEvent is fired.
            //  This results in the "run" method being invoked
    
            SwingUtilities.invokeLater( this );
        }
        /*
         *  See above.
         */
        @Override
        public void run()
        {
            row = table.convertRowIndexToModel( table.getEditingRow() );
            column = table.convertColumnIndexToModel( table.getEditingColumn() );
            oldValue = table.getModel().getValueAt(row, column);
            //这里应对oldValue为null的情况做处理,否则将导致原值与新值均为空时仍被视为值改变
            if(oldValue == null)
                oldValue = "";
            newValue = null;
        }
    
        /*
         *    Update the Cell history when necessary
         */
        private void processEditingStopped()
        {
            newValue = table.getModel().getValueAt(row, column);
            //这里应对newValue为null的情况做处理,否则后面会抛出异常
            if(newValue == null)
                newValue = "";
            //  The data has changed, invoke the supplied Action
            if (! newValue.equals(oldValue))
            {
                //  Make a copy of the data in case another cell starts editing
                //  while processing this change
    
                
                TableCellListener tcl = new TableCellListener(
                    getTable(), getRow(), getColumn(), getOldValue(), getNewValue());
    
                ActionEvent event = new ActionEvent(
                    tcl,
                    ActionEvent.ACTION_PERFORMED,
                    "");        
                action.actionPerformed(event);
            }
        }
    }

    ButtonEditor.java

    package JButtonTableExample;
    
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import javax.swing.DefaultCellEditor;
    import javax.swing.JButton;
    import javax.swing.JCheckBox;
    import javax.swing.JComponent;
    import javax.swing.JOptionPane;
    import javax.swing.JTable;
    
    public class ButtonEditor extends DefaultCellEditor {
          protected JButton button;//represent the  cellEditorComponent
          private String cellValue;//保存cellEditorValue
    
          public ButtonEditor() {
            super(new JCheckBox());
            button = new JButton();
            button.setOpaque(true);
            button.addActionListener(new ActionListener() {
              public void actionPerformed(ActionEvent e) {
                JOptionPane.showMessageDialog(button, cellValue + ": Ouch!");
                //刷新渲染器
                fireEditingStopped();
              }
            });
          }
    
          public JComponent getTableCellEditorComponent(JTable table, Object value,
              boolean isSelected, int row, int column) {
            //value 源于单元格数值
            cellValue = (value == null) ? "" : value.toString();
            return button;
          }
    
         public Object getCellEditorValue() {
            return new String(cellValue);
          }
        }

    ButtonRenderer.java

    package JButtonTableExample;
    
    import java.awt.Color;
    import javax.swing.JButton;
    import javax.swing.JComponent;
    import javax.swing.JTable;
    import javax.swing.table.TableCellRenderer;
    
    public class ButtonRenderer extends JButton implements TableCellRenderer {
    
          public JComponent getTableCellRendererComponent(JTable table, Object value,
              boolean isSelected, boolean hasFocus, int row, int column) {
              //value 源于editor
              String text = (value == null) ? "" : value.toString();
              //按钮文字
              setText(text);
              //单元格提示
              setToolTipText(text);
              //背景色
              setBackground(Color.BLACK);
              //前景色
              setForeground(Color.green);
            return this;
          }
        }

    运行效果如下:

  • 相关阅读:
    一条语句批量插入多条数据
    VMware Workstation 15 Pro 永久激活密钥
    windows下java项目打包、启动批处理 .bat文件
    java简写名词解释
    windows查看所有进程:netstat -ano
    Java验证jwt token
    【转载】三种方法从 HTTPS 网站导出 SSL 证书链
    使用solr将CSV/XML/DB/JSON数据发布为Rest Service
    检验多个xsd的xml是否合法
    Eclipse 打包运行maven项目
  • 原文地址:https://www.cnblogs.com/pzy4447/p/5229289.html
Copyright © 2020-2023  润新知