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;
      }
    }

运行效果如下:

时间: 2024-10-25 08:30:11

JTable用法-实例的相关文章

vertica从其他表迁移数据到新表(insert into 语句用法实例)

前面一篇开始学习solr的时候,做了个入门的示例http://blog.csdn.net/zjc/article/details/24414271 .虽然可以检索出内容,但总和想象的结果有差异--比如,检索"天龙"两个字,按常规理解,就应该只出来<天龙八部>才对,可是竟然也会把<倚天屠龙记>检出来.后来研究了一下,发现系统是这样处理的:无论是抽索引时还是分析检索词时,都把所有文字按单字拆开.这样,刚好<倚天屠龙记>里包含"天"和&

Struts2常量的具体用法实例

通常struts2加载struts2常量的顺序如下: 1. struts-default.xml:该文件保存在struts2-core-2.0.6.jar文件中.2. struts-plugin.xml:该文件保存在struts2-Xxx-2.0.6.jar等Struts2插件JAR文件中.3. struts.xml:该文件是Web应用默认的Struts2配置文件.4. struts.properties:该文件是Web应用默认的Struts2配置文件.5. web.xml:该文件是Web应用的

JavaScript中字符串分割函数split用法实例

这篇文章主要介绍了JavaScript中字符串分割函数split用法,实例分析了javascript中split函数操作字符串的技巧,非常具有实用价值,需要的朋友可以参考下 本文实例讲述了JavaScript中字符串分割函数split用法.分享给大家供大家参考.具体如下: 先来看下面这段代码: <script type="text/javascript"> var str="How are you doing today?" document.write

angularjs中ng-repeat-start与ng-repeat-end用法实例

angularjs中ng-repeat-start与ng-repeat-end用法实例 <!DOCTYPE html> <html lang="zh-CN" ng-app="app"> <head> <meta charset="utf-8"> <title>ng-repeat-start 与 ng-repeat-end的用法</title> <link rel=&qu

XSD(XML Schema Definition)用法实例介绍以及C#使用xsd文件验证XML格式

XSD(XML Schema Definition)用法实例介绍以及C#使用xsd文件验证XML格式 http://blog.csdn.net/gdjlc/article/details/11374787 2013-09-08 12:16 2824人阅读 评论(0) 收藏 举报 分类: XML(5) 版权声明:本文为博主原创文章,未经博主允许不得转载. XML Schema 语言也称作 XML Schema 定义(XML Schema Definition,XSD),作用是定义 XML 文档的合

php教程之Smarty模板用法实例

分享下php之Smarty模板的使用方法. 剖析了smarty模板的使用方法,对于学习smarty的朋友有一定的参考价值. 详情如下: 一.模板中的注释每一个Smarty模板文件,都是通过Web前台语言(xhtml,css和javascript等)结合Smarty引擎的语法开发的.用到的web前台开发的语言和原来的完全一样,注释也没有变化.Smarty注释语法是'左结束符变量值*'和'*右结束符变量值',在这两个定界符之间的内容都是注释内容,可以包含一行或多行,并且用户浏览网页查看原代码时不会看

jquery.cycle.js简单用法实例

样式: a{text-decoration: none;} *{margin:0; padding:0;} /*容器设置*/ .player { width:216px; height:248px; background:url(http://i2.itc.cn/20120117/2cc0_da8f6c82_c8da_693d_7714_9533a013006a_3.jpg) no-repeat; background-color:#ede1d1; position:relative; padd

PHP中__get()和__set()的用法实例详解

PHP中__get()和__set()的用法实例详解 在PHP5中,预定义了两个函数“__get()”和“__set()”来获取和赋值其属性,对每个字段进行set和get的操作.只需要加上两个魔术方法即可 php面向对象_get(),_set()的用法 一般来说,总是把类的属性定义为private,这更符合 现实的逻辑.但是,对属性的读取和赋值操作是非常频繁的,因此在PHP5中,预定义了两个函数“__get()”和“__set()”来获取和赋值其属 性.类似于java中的javabean的操作,

sys_refcursor的用法实例

--创建过程,参数为sys_refcursor,为out型 create or replace procedure aabbsys_refcursor(o out sys_refcursor) is begin open o for select * from basplumain; end; --- --测试过程,使用aabbsys_refcursor传出的值 create or replace procedure aabb_test_sys_refcursor(return out int)