`
dzgwt2004
  • 浏览: 167322 次
  • 来自: 浙江杭州
社区版块
存档分类
最新评论

swing组件介绍(2)

    博客分类:
  • java
阅读更多
下面是一个JFormattedTextField的例子.在这个例子中的三个JFormattedTextField分别使用了NumberFormat的三个静态方法取得的NumberFormat,当它们失去焦点时,它们显示的文本就会被格式化再重新显示,如果输入的是无效的文本,则文本被重设为上次的有效文本.


package blog.swing;
import java.awt.GridLayout;
import java.awt.Container;
import javax.swing.BorderFactory;
import javax.swing.*;
import java.text.NumberFormat;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeEvent;

class JFormattedTextFieldDemo implements PropertyChangeListener
{
    JFrame mainFrame;
    JPanel mainPanel;
    JFormattedTextField priceFormattedTextField;
    JFormattedTextField discountFormattedTextField;
    JFormattedTextField paymentFormattedTextField;
    JLabel priceLabel;
    JLabel discountLabel;
    JLabel paymentLabel;
    NumberFormat priceFormat;
    NumberFormat discountFormat;
    NumberFormat paymentFormat;
    public JFormattedTextFieldDemo() {
        mainFrame = new JFrame ( "JFormattedTextFieldDemo" );
        mainPanel = new JPanel ( new GridLayout(3,2) );
        mainPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));

        priceFormat = NumberFormat.getNumberInstance();
        priceFormattedTextField = new JFormattedTextField(priceFormat);
        priceFormattedTextField.setValue(72.023);
        priceFormattedTextField.addPropertyChangeListener("value",this);
        priceLabel = new JLabel ("Price");
        priceLabel.setLabelFor( priceFormattedTextField );
        mainPanel.add( priceLabel );
        mainPanel.add( priceFormattedTextField );

        discountFormat = NumberFormat.getPercentInstance();
        discountFormattedTextField = new JFormattedTextField(discountFormat);
        discountFormattedTextField.setValue(0.75);
        discountFormattedTextField.addPropertyChangeListener("value",this);
        discountLabel = new JLabel ("Discount");
        discountLabel.setLabelFor( discountFormattedTextField );
        mainPanel.add( discountLabel );
        mainPanel.add( discountFormattedTextField );

        paymentFormat = NumberFormat.getCurrencyInstance();
        paymentFormattedTextField = new JFormattedTextField(paymentFormat);
        paymentFormattedTextField.setEditable( false );
        paymentFormattedTextField.addPropertyChangeListener("value",this);
        paymentLabel = new JLabel ("Payment");
        paymentLabel.setLabelFor( paymentFormattedTextField );
        mainPanel.add( paymentLabel );
        mainPanel.add( paymentFormattedTextField );

        mainFrame.getContentPane().add( mainPanel );
        mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible( true );
    }
    public void propertyChange( PropertyChangeEvent e ){
        double price = ((Number)priceFormattedTextField.getValue()).doubleValue();
        double discount = ((Number)discountFormattedTextField.getValue()).doubleValue();
        paymentFormattedTextField.setValue( price*discount );
    }
    public static void main(String[] args) 
    {
        new JFormattedTextFieldDemo();
    }
}

除了使用上面讲到的java.text包中的各种formatter,还可以使用javax.swing.text.MaskFormatter来限制用户可以输入的字符


package blog.swing;
import javax.swing.*;
import javax.swing.text.MaskFormatter;
import java.text.ParseException;
class  MaskFormatterDemo
{
    JFrame mainFrame;
    JFormattedTextField simpleFormattedTextField;
    MaskFormatter mask;
    public MaskFormatterDemo(){
        mainFrame = new JFrame ( "MaskFormatterDemo" );
        try{
            mask = new MaskFormatter("####");
            simpleFormattedTextField = new JFormattedTextField( mask );        
            mainFrame.getContentPane().add( simpleFormattedTextField );
        }catch( ParseException e ){
            e.printStackTrace();
        }
        mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible( true );
    }
    public static void main(String[] args) 
    {
        new MaskFormatterDemo();
    }
}

22.JSpinner
微调组件.
微调组件由Editor,微调按钮,和它的Model组成.
在构造JSpinner时,可以指定它的Model.
swing提供了三个Model:
SpinnerListModel,SpinnerNumberModel,SpinnerDateModel
结构是SpinnerModel
  |_AbstractSpinnerModel
   |_SpinnerListModel,SpinnerNumberModel,SpinnerDateModel
对应有三个Editor:
JSpinner.ListEditor,JSpinner.NumberEditor,JSpinner.DateEditor,三个都是JSpinner.DefaultEditor的子类
JSpinner.DefaultEditor
|_JSpinner.ListEditor,JSpinner.NumberEditor,JSpinner.DateEditor
可以看到,有很大的空间可以自定义一个JSpinner
当你需要自定义它的Editor时,你可以用void setEditor(JComponent editor),也可以用JSpinner.DefaultEditor.getTextField()来取得JFormattedTextField,然后对这个JFormattedTextField来调用方法.
可以通过addChangeListener对JSpinner值的改变作出反应.


package blog.swing;
import java.awt.GridLayout;
import java.awt.Color;
import javax.swing.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
import java.util.Date;
import java.util.Calendar;
import java.text.DecimalFormat;

class JSpinnerDemo implements ChangeListener
{
    JFrame mainFrame;
    JPanel mainPanel;
    JSpinner listSpinner;
    JSpinner numberSpinner;
    JSpinner dateSpinner;
    public JSpinnerDemo() {
        mainFrame = new JFrame ( "JSpinnerDemo" );
        mainPanel = new JPanel ( new GridLayout(3,1) );
        
        String[] listData = { "SpinnerListModel","SpinnerNumberModel","SpinnerDateModel" };
        //使用自定义的Model来实现cycle
        SpinnerModel listModel = new CustomSpinnerListModel(listData);
        listSpinner = new JSpinner( listModel );
        listSpinner.addChangeListener( this );
        mainPanel.add(listSpinner);

        SpinnerModel numberModel = new SpinnerNumberModel(1.0,0.0,2.0,0.1);
        numberSpinner = new JSpinner( numberModel );
        numberSpinner.addChangeListener( this );
        //通过取得JFormattedTextField来自定义Editor
        JSpinner.DefaultEditor editor = (JSpinner.DefaultEditor)numberSpinner.getEditor();
        JFormattedTextField ftf = editor.getTextField();
        ftf.setForeground( Color.red );
        mainPanel.add( numberSpinner );

        Calendar calendar = Calendar.getInstance();
        Date initDate = calendar.getTime();
        calendar.add(Calendar.YEAR,-100);
        Date earliestDate = calendar.getTime();
        calendar.add(Calendar.YEAR,200);
        Date latestDate = calendar.getTime();
        SpinnerModel dateModel = new SpinnerDateModel(initDate,earliestDate,latestDate,Calendar.YEAR);
        dateSpinner = new JSpinner( dateModel );
        dateSpinner.addChangeListener( this );
        //通过setEditor来自定义Editor
        dateSpinner.setEditor( new JSpinner.DateEditor(dateSpinner,"yyyy-MM-dd") );
        mainPanel.add(dateSpinner);

        mainPanel.setBorder( BorderFactory.createEmptyBorder(10,10,10,10) );
        mainFrame.getContentPane().add( mainPanel );
        mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible( true );
    }
    public void stateChanged( ChangeEvent e ){
        JSpinner spinner = (JSpinner)e.getSource();
        System.out.println( spinner.getValue() );
    }
    //自定义的Model,实现Cycle.
    class CustomSpinnerListModel extends SpinnerListModel{
        Object[] values;
        CustomSpinnerListModel( Object[] values ){
            super(values);
            this.values = values;
        }
        public Object getPreviousValue(){
            Object value = super.getPreviousValue();
            return value != null ? value : values[values.length-1];
        }
        public Object getNextValue(){
            Object value = super.getNextValue();
            return value != null ? value : values[0];
        }
    }
    public static void main(String[] args) 
    {
        new JSpinnerDemo();
    }
}

23.JTree
这个组件太复杂了,只能很简单很简单地介绍一下.
一树由根节点和子节点组成.它们都是由DefaultMutableTreeNode表示
根节点是必须的,子节点可有可无.
传给DefaultMutableTreeNode的构造方法的是一个Object.在构造JTree的时候,会调用这个Object的toString()取得显示在JTree上的节点的文本.
调用void add(MutableTreeNode newChild)来增加一个子节点.
在构造JTree时,将用DefaultMutableTreeNode表示的根传入构造方法JTree(TreeNode root) ,这样就可以构造一棵树.
JTree用TreeSelectionModel来维护它的选择项,默认使用的是它的实现类DefaultTreeSelectionModel.
通过它的void addTreeSelectionListener(TreeSelectionListener x)可以对选择作出反应.
自定义JTree的外观
void setRootVisible(boolean rootVisible) 可以设置是否隐藏根节点
void setShowsRootHandles(boolean newValue) 设置是否显示节点前面的加号
void putClientProperty(Object key,Object value)设置节点之间的连线的样式
要自定义节点的图标,可以使用DefaultTreeCellRenderer,它是JLabel的一个字类
void setClosedIcon(Icon icon)设置非展开时的图标
void setOpenIcon(Icon newIcon) 设置节点展开时的图标
void setLeafIcon(Icon newIcon) 设置叶节点的图标
它也有一般Renderer类有的方法:
Component getTreeCellRendererComponent(JTree tree, Object value, boolean sel, boolean expanded, boolean leaf, int row, boolean hasFocus)
通过这个方法可以定义每个节点所显示的组件
JTree的void setEditable(boolean)可以设置是否可以就地编辑该树
通过JTree的数据Model TreeModel的void addTreeModelListener(TreeModelListener l),我们可以在发生编辑的时候作出反应.
简单的应用可以使用TreeModel的实现类DefaultTreeModel.它的构造和JTree一样,也是把树的根节点传进去,DefaultTreeModel(TreeNode root).
创建了它以后,就可以用JTree的另外一个构造方法JTree(TreeModel newModel)来构造一棵树.


package blog.swing;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.tree.*;
class JTreeDemo 
{
    JFrame mainFrame;
    JScrollPane scrollPane;
    JTree simpleTree;
    JButton addButton;
    JButton removeButton;
    JTextField insertField;
    JPanel panel;
    public JTreeDemo() {
        mainFrame = new JFrame ( "JTreeDemo" );
        DefaultMutableTreeNode swing = new DefaultMutableTreeNode("Swing");
        buildTree(swing);
        simpleTree = new JTree(swing);
        simpleTree.getSelectionModel().addTreeSelectionListener(new TreeSelectionListener(){
            public void valueChanged( TreeSelectionEvent e ){
                System.out.println( "selection changed" );
            }
        });
        simpleTree.setRootVisible(false);
        simpleTree.setShowsRootHandles(false);
        simpleTree.putClientProperty("JTree.lineStyle","Horizontal");
        simpleTree.putClientProperty("JTree.lineStyle","None");
        simpleTree.setCellRenderer( new CustomTreeCellRenderer() );
        simpleTree.setEditable( true );
        simpleTree.getModel().addTreeModelListener(new TreeModelListener(){
                public void treeNodesChanged(TreeModelEvent e) {
                    System.out.println("node changed");
                }
                public void treeNodesInserted(TreeModelEvent e) {
                    System.out.println( "node inserted" );
                }
                public void treeNodesRemoved(TreeModelEvent e) {
                    System.out.println("node removed");
                }
                public void treeStructureChanged(TreeModelEvent e) {
                    System.out.println( "strutrued changed" );
                }
            });
        scrollPane = new JScrollPane( simpleTree );

        addButton = new JButton ("add");
        addButton.addActionListener( new ActionListener(){
            public void actionPerformed( ActionEvent e){
                TreePath parentPath = simpleTree.getSelectionPath();
                if( parentPath != null ){
                    DefaultMutableTreeNode parentNode = (DefaultMutableTreeNode)parentPath.getLastPathComponent();
                    DefaultTreeModel model = (DefaultTreeModel)simpleTree.getModel();
                    DefaultMutableTreeNode child = new DefaultMutableTreeNode( insertField.getText() );
                    model.insertNodeInto( child , parentNode,0 );
                    simpleTree.scrollPathToVisible( new TreePath( child.getPath() ) ); 
                }
            }
        });
        removeButton = new JButton ("remove");
        removeButton.addActionListener( new ActionListener(){
            public void actionPerformed( ActionEvent e){
                TreePath path = simpleTree.getSelectionPath();
                if( path != null ){
                    DefaultMutableTreeNode removeNode = (DefaultMutableTreeNode)path.getLastPathComponent();
                    DefaultTreeModel model = (DefaultTreeModel)simpleTree.getModel();
                    model.removeNodeFromParent( removeNode );
                }
            }
        });
        insertField = new JTextField(20);
        panel = new JPanel ( new GridLayout(15,1) );
        panel.add(insertField);
        panel.add( addButton );
        panel.add( removeButton );

        mainFrame.getContentPane().add( panel,BorderLayout.LINE_START );
        mainFrame.getContentPane().add( scrollPane,BorderLayout.LINE_END  );
        mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible( true );
    }
    private void buildTree(DefaultMutableTreeNode root){
        DefaultMutableTreeNode parent;
        DefaultMutableTreeNode child;
        parent = new DefaultMutableTreeNode("Containers");
        child = new DefaultMutableTreeNode("JFrame");
        parent.add(child);
        child = new DefaultMutableTreeNode("JPanel");
        parent.add(child);
        child = new DefaultMutableTreeNode("JDialog");
        parent.add(child);
        root.add(parent);
        parent = new DefaultMutableTreeNode("Components");
        child = new DefaultMutableTreeNode("JButton");
        parent.add(child);
        child = new DefaultMutableTreeNode("JLabel");
        parent.add(child);
        child = new DefaultMutableTreeNode("JList");
        parent.add(child);
        root.add(parent);
    }
    private class CustomTreeCellRenderer extends DefaultTreeCellRenderer{
        public CustomTreeCellRenderer(){
            /*setLeafIcon( new ImageIcon("images/leaf.gif") );
            setOpenIcon( new ImageIcon("images/expand.gif") );
            setClosedIcon( new ImageIcon("images/unexpand.gif") );*/
        }
        public Component getTreeCellRendererComponent(
            JTree tree, Object value,
            boolean sel, boolean expanded,
            boolean leaf, int row, boolean hasFocus){
            JButton button = new JButton ( value.toString() );
            if( leaf )
                button.setIcon(new ImageIcon("images/leaf.gif") );
            else{
                if( expanded )
                    button.setIcon(new ImageIcon("images/expand.gif") );
                else
                    button.setIcon(new ImageIcon("images/unexpand.gif") );
            }
            return button;
        }
    }
    public static void main(String[] args) 
    {
        new JTreeDemo();
    }
}
   

24.Jtable 表格组件
应网友要求,勉强加上JTable的用法讲述.写得不好,望不见怪

没有比这个组件更复杂的了
它由标题头和单元格组成.而单元格又分为编辑状态和非编辑状态.自定义JTable主要是对单元格作文章.默认的单元格是一个label,和JTree一样,如果你在创建JTable的时候传递的是其他对象而不是String对象,则该对象的toString方法将被调用.它返回的字符串就会显示在单元格的label里.同以往一样,可以通过”渲染器”将其他组件显示在单元格里;而编辑状态下的单元格默认是一个文本框.可以通过指定CellEditor来指定其他的组件作为编辑状态下单元格的组件(简称编辑器).你可以为某一种类型的数据指定一种编辑器,也可以为一整列的数据指定特定的编辑器.编辑器可以用作验证用户输入的合法性.对于渲染器和编辑器的概念,是和JTree里的相似的
这个组件一般放在一个滚动窗格里.你可以把一个表格作为滚动窗格的viewport,然后再把滚动窗格添加到主框架的内容窗格(content pane)里.如果你不这样做,那么你必须分别把表格头和表格添加到框架窗口的content pane里.
这个组件也是用所谓的模型来保存它的数据的.TableModel就是用来保存数据的.而它和JList一样,用ListSelectionModel来保存选择了的项.另外它还有TableColumnModel来保存关于列的数据.下面几幅图总结了各部Model和Renderer的父子关系.
下面是例子程序
/*本程序演示了如何自定义自己的渲染器,自已的编辑器,和自己的数据模型
其中渲染器使得数据是Color类型时显示一个带颜色的JLabel
当数据是Color类型时编辑器是一个按钮,用以选择颜色*/

import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.table.*;

class JTableTest 
{
    JFrame mainFrame;
    JPanel mainPanel;
    JTable table;
    JScrollPane scrollPane;
    public JTableTest() {

        mainFrame = new JFrame ( "JTableTest" );
        mainPanel = new JPanel ( new BorderLayout() );

        String[] columnName = { "Name","Age","Favorite Color","Career","Married" };
        Object[][] data = { { "kate", new Integer(34),new Color(255,0,0),"engineer", new Boolean(true) },
                             { "jim", new Integer(56),Color.white,"manager", new Boolean(false) },
                            { "roy", new Integer(23),Color.black,"driver", new Boolean(false) },
                            { "paul", new Integer(33),Color.blue,"teacher", new Boolean(true) }};

        CustomTableModel customModel = new CustomTableModel( data,columnName );//自定义的数据模型
        table = new JTable( customModel ){//在构造方法里传递数据模型作为参数
            public String getToolTipText( MouseEvent e){//设定工具提示
                int row = rowAtPoint( e.getPoint() );
                int column = columnAtPoint( e.getPoint() );
                int realColumn = convertColumnIndexToModel( column );
                if( realColumn == 3 ){
                    TableModel model = getModel();
                    String name = (String)model.getValueAt( row, 0 );
                    String career = (String)model.getValueAt( row, realColumn );
                    return name + "'s" + "career is " + career;
                }
                return null;
            }

            public TableCellEditor getCellEditor(int row, int column) {
                if ((row == 1) && (column == 2)) {
                    return new CustomCellEditor();//好像没起作用?
                }
                return super.getCellEditor(row, column);
            }
        };
        table.getTableHeader().setToolTipText("click here can't sort the contents");//设置标题头的工具提示.排序功能并未实现
        ListSelectionModel rowSm = table.getSelectionModel();
        rowSm.addListSelectionListener( new ListSelectionListener(){
            public void valueChanged( ListSelectionEvent e ){
                ListSelectionModel lsm = (ListSelectionModel)e.getSource();
                System.out.println( lsm.getMaxSelectionIndex() );
            }
        } );

        TableColumn column = table.getColumnModel().getColumn(3);
        JComboBox combox = new JComboBox();
        combox.addItem("engineer");
        combox.addItem("students");
        combox.addItem("driver");
        combox.addItem("teacher");
        column.setCellEditor( new DefaultCellEditor( combox ) );//为一整列指定编辑器

        table.setDefaultEditor( Color.class , new CustomCellEditor() );//为特定的数据类型指定编辑器
        table.setDefaultRenderer( Color.class , new CustomRenderer() );


        TableModel tableModel = table.getModel();
        tableModel.addTableModelListener( new TableModelListener(){
            public void tableChanged( TableModelEvent e ){
                TableModel model = (TableModel)e.getSource();
                int row = e.getFirstRow();
                int column = e.getColumn();

                System.out.println( model.getValueAt( row, column ) );
                System.out.println( model.getColumnName( column ) );
            }
        } );

        mainPanel.add(table.getTableHeader(),BorderLayout.PAGE_START);
        mainPanel.add(table,BorderLayout.CENTER);
        scrollPane = new JScrollPane (mainPanel);//这样,表头会自动添加到滚动空格里;否则,则要使用下面三行将标题头也添加到框架窗口
/*        mainFrame.getContentPane().setLayout(new BorderLayout());
        mainFrame.getContentPane().add(table.getTableHeader(), BorderLayout.PAGE_START);
        mainFrame.getContentPane().add(table, BorderLayout.CENTER);*/


        mainFrame.getContentPane().add( scrollPane );
        mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible( true );
    }
    private class CustomTableModel extends AbstractTableModel{//自定义的数据类型
        String[] columnName;
        Object[][] data;
        CustomTableModel(Object[][] data,String[] columnName){
            this.columnName = columnName;
            this.data = data;
        }
        public Object getValueAt( int rowIndex, int columnIndex ){
            return data[rowIndex][columnIndex];
        }
        public int getColumnCount(){
            return data[0].length;
        }
        public int getRowCount(){
            return data.length;
        }
        public String getColumnName( int columnIndex ){
            return columnName[columnIndex];
        }
        public Class getColumnClass( int columnIndex ){
            return getValueAt(0,columnIndex).getClass();

        }
        public void setValueAt( Object value, int row, int column ){
            data[row][column] = value;
            fireTableCellUpdated(row,column);
        }
        public boolean isCellEditable(int row ,int column){
            return true;
        }
    }
    //自定义的编辑器
    private class CustomCellEditor extends AbstractCellEditor implements TableCellEditor,ActionListener{
        Color currentColor;
        JButton button;
        JColorChooser chooser;
        JDialog dialog;
        CustomCellEditor(){
            button = new JButton ();
            button.addActionListener( this );
            button.setActionCommand("editor");
            chooser = new JColorChooser();
            dialog = JColorChooser.createDialog( button,"pick a color",true,chooser,this,null);
        }
        public void actionPerformed( ActionEvent e ){
            if( e.getActionCommand().equals( "editor" ) ){
                button.setBackground( currentColor );
                chooser.setColor(currentColor);
                dialog.setVisible( true );
                fireEditingStopped();
            }else{                
                
                currentColor = chooser.getColor();
            }
        }
        public Object getCellEditorValue(){
            return currentColor;
        }
        public Component getTableCellEditorComponent( JTable table,Object value,boolean isSelected,int row,int column){
            currentColor = (Color)value;
            return button;
        }
    }
    //自定义的渲染器
    private class CustomRenderer extends JLabel implements TableCellRenderer{
        CustomRenderer(){
            setOpaque(true);
        }
        public Component getTableCellRendererComponent(
            JTable table,Object value,boolean isSelected,
            boolean hasFocus,int row,int column){
                setBackground( (Color)value );
                setToolTipText( "RGB Value: "+((Color)value).getRed()+" "
                    +((Color)value).getGreen()+" "+((Color)value).getBlue() );
                return this;
        }
        
    }
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater( new Runnable(){
            public void run(){
                new JTableTest();
            }
        });
    }
}

  

24.Jtable 表格组件
没有比这个组件更复杂的了
它由标题头和单元格组成.而单元格又分为编辑状态和非编辑状态.自定义JTable主要是对单元格作文章.默认的单元格是一个label,和JTree一样,如果你在创建JTable的时候传递的是其他对象而不是String对象,则该对象的toString方法将被调用.它返回的字符串就会显示在单元格的label里.同以往一样,可以通过”渲染器”将其他组件显示在单元格里;而编辑状态下的单元格默认是一个文本框.可以通过指定CellEditor来指定其他的组件作为编辑状态下单元格的组件(简称编辑器).你可以为某一种类型的数据指定一种编辑器,也可以为一整列的数据指定特定的编辑器.编辑器可以用作验证用户输入的合法性.对于渲染器和编辑器的概念,是和JTree里的相似的
这个组件一般放在一个滚动窗格里.你可以把一个表格作为滚动窗格的viewport,然后再把滚动窗格添加到主框架的内容窗格(content pane)里.如果你不这样做,那么你必须分别把表格头和表格添加到框架窗口的content pane里.
这个组件也是用所谓的模型来保存它的数据的.TableModel就是用来保存数据的.而它和JList一样,用ListSelectionModel来保存选择了的项.另外它还有TableColumnModel来保存关于列的数据.下面几幅图总结了各部Model和Renderer的父子关系.
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.event.*;
import javax.swing.table.*;

class JTableTest 
{
    JFrame mainFrame;
    JPanel mainPanel;
    JTable table;
    JScrollPane scrollPane;
    public JTableTest() {

        mainFrame = new JFrame ( "JTableTest" );
        mainPanel = new JPanel ( new BorderLayout() );

        String[] columnName = { "Name","Age","Favorite Color","Career","Married" };
        Object[][] data = { { "kate", new Integer(34),new Color(255,0,0),"engineer", new Boolean(true) },
                             { "jim", new Integer(56),Color.white,"manager", new Boolean(false) },
                            { "roy", new Integer(23),Color.black,"driver", new Boolean(false) },
                            { "paul", new Integer(33),Color.blue,"teacher", new Boolean(true) }};

        CustomTableModel customModel = new CustomTableModel( data,columnName );//自定义的数据模型
        table = new JTable( customModel ){//在构造方法里传递数据模型作为参数
            public String getToolTipText( MouseEvent e){//设定工具提示
                int row = rowAtPoint( e.getPoint() );
                int column = columnAtPoint( e.getPoint() );
                int realColumn = convertColumnIndexToModel( column );
                if( realColumn == 3 ){
                    TableModel model = getModel();
                    String name = (String)model.getValueAt( row, 0 );
                    String career = (String)model.getValueAt( row, realColumn );
                    return name + "'s" + "career is " + career;
                }
                return null;
            }

            public TableCellEditor getCellEditor(int row, int column) {
                if ((row == 1) && (column == 2)) {
                    return new CustomCellEditor();//好像没起作用?
                }
                return super.getCellEditor(row, column);
            }
        };
        table.getTableHeader().setToolTipText("click here can't sort the contents");//设置标题头的工具提示.排序功能并未实现
        ListSelectionModel rowSm = table.getSelectionModel();
        rowSm.addListSelectionListener( new ListSelectionListener(){
            public void valueChanged( ListSelectionEvent e ){
                ListSelectionModel lsm = (ListSelectionModel)e.getSource();
                System.out.println( lsm.getMaxSelectionIndex() );
            }
        } );

        TableColumn column = table.getColumnModel().getColumn(3);
        JComboBox combox = new JComboBox();
        combox.addItem("engineer");
        combox.addItem("students");
        combox.addItem("driver");
        combox.addItem("teacher");
        column.setCellEditor( new DefaultCellEditor( combox ) );//为一整列指定编辑器

        table.setDefaultEditor( Color.class , new CustomCellEditor() );//为特定的数据类型指定编辑器
        table.setDefaultRenderer( Color.class , new CustomRenderer() );


        TableModel tableModel = table.getModel();
        tableModel.addTableModelListener( new TableModelListener(){
            public void tableChanged( TableModelEvent e ){
                TableModel model = (TableModel)e.getSource();
                int row = e.getFirstRow();
                int column = e.getColumn();

                System.out.println( model.getValueAt( row, column ) );
                System.out.println( model.getColumnName( column ) );
            }
        } );

        mainPanel.add(table.getTableHeader(),BorderLayout.PAGE_START);
        mainPanel.add(table,BorderLayout.CENTER);
        scrollPane = new JScrollPane (mainPanel);//这样,表头会自动添加到滚动空格里;否则,则要使用下面三行将标题头也添加到框架窗口
/*        mainFrame.getContentPane().setLayout(new BorderLayout());
        mainFrame.getContentPane().add(table.getTableHeader(), BorderLayout.PAGE_START);
        mainFrame.getContentPane().add(table, BorderLayout.CENTER);*/


        mainFrame.getContentPane().add( scrollPane );
        mainFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        mainFrame.pack();
        mainFrame.setLocationRelativeTo(null);
        mainFrame.setVisible( true );
    }
    private class CustomTableModel extends AbstractTableModel{//自定义的数据类型
        String[] columnName;
        Object[][] data;
        CustomTableModel(Object[][] data,String[] columnName){
            this.columnName = columnName;
            this.data = data;
        }
        public Object getValueAt( int rowIndex, int columnIndex ){
            return data[rowIndex][columnIndex];
        }
        public int getColumnCount(){
            return data[0].length;
        }
        public int getRowCount(){
            return data.length;
        }
        public String getColumnName( int columnIndex ){
            return columnName[columnIndex];
        }
        public Class getColumnClass( int columnIndex ){
            return getValueAt(0,columnIndex).getClass();

        }
        public void setValueAt( Object value, int row, int column ){
            data[row][column] = value;
            fireTableCellUpdated(row,column);
        }
        public boolean isCellEditable(int row ,int column){
            return true;
        }
    }
    //自定义的编辑器
    private class CustomCellEditor extends AbstractCellEditor implements TableCellEditor,ActionListener{
        Color currentColor;
        JButton button;
        JColorChooser chooser;
        JDialog dialog;
        CustomCellEditor(){
            button = new JButton ();
            button.addActionListener( this );
            button.setActionCommand("editor");
            chooser = new JColorChooser();
            dialog = JColorChooser.createDialog( button,"pick a color",true,chooser,this,null);
        }
        public void actionPerformed( ActionEvent e ){
            if( e.getActionCommand().equals( "editor" ) ){
                button.setBackground( currentColor );
                chooser.setColor(currentColor);
                dialog.setVisible( true );
                fireEditingStopped();
            }else{                
                
                currentColor = chooser.getColor();
            }
        }
        public Object getCellEditorValue(){
            return currentColor;
        }
        public Component getTableCellEditorComponent( JTable table,Object value,boolean isSelected,int row,int column){
            currentColor = (Color)value;
            return button;
        }
    }
    //自定义的渲染器
    private class CustomRenderer extends JLabel implements TableCellRenderer{
        CustomRenderer(){
            setOpaque(true);
        }
        public Component getTableCellRendererComponent(
            JTable table,Object value,boolean isSelected,
            boolean hasFocus,int row,int column){
                setBackground( (Color)value );
                setToolTipText( "RGB Value: "+((Color)value).getRed()+" "
                    +((Color)value).getGreen()+" "+((Color)value).getBlue() );
                return this;
        }
        
    }
    public static void main(String[] args) 
    {
        SwingUtilities.invokeLater( new Runnable(){
            public void run(){
                new JTableTest();
            }
        });
    }
}
分享到:
评论

相关推荐

    swing组件介绍(一)

    在"swing组件介绍(一)"这篇博文中,作者可能涵盖了Swing组件的基础知识,包括以下几个核心点: 1. **基础组件**:Swing提供了许多基础组件,如按钮(JButton)、文本框(JTextField)、标签(JLabel)、复选框...

    swing组件的详细介绍

    2. **跨平台一致性**:Swing组件是轻量级的,它们不依赖于底层操作系统,从而确保在不同平台上具有一致的外观和行为。 3. **外观和感觉(LookAndFeel)**:用户可以轻松改变程序的视觉样式,实现自定义的LookAnd...

    j2ee的应用-swing组件介绍

    Swing组件是Java编程语言中用于构建用户图形界面(GUI)的一部分,特别是在J2EE(Java 2 Platform, Enterprise Edition)环境中。Swing是Java Foundation Classes (JFC)的一部分,提供了一套丰富的组件库,允许...

    Swing组件应用实例

    Swing组件是Java GUI(图形用户界面)编程中的核心元素,它是Java Foundation Classes (JFC) 的一部分。Swing提供了一系列丰富的组件,用于构建功能强大的桌面应用程序。在本实例中,我们将深入探讨Swing组件的使用...

    javaswing组件大全.pdf

    本文档将对 Java Swing 中的组件进行详细的介绍和分析。 JFrame Java Swing 中的 JFrame 是一个基本的窗口组件,继承自 java.awt.Frame 类。JFrame 提供了一个基本的窗口框架,可以用来创建多种类型的窗口应用程序...

    普通swing组件用法

    普通swing组件用法

    常用Swing组件一览表

    Swing 组件概述 Swing 是 Java 编程语言中的一组图形用户界面(GUI)组件,它们提供了丰富的用户界面元素,帮助开发者快速构建桌面应用程序。Swing 组件可以分为五大类:顶层容器、中间容器、特殊容器、基本组件和...

    Java Swing 组件全演示

    总之,Java Swing组件全演示旨在通过实际项目引导学习者深入理解Swing组件的使用和界面设计。通过这种方式,开发者不仅可以掌握基本组件的用法,还能培养解决问题和设计高效界面的能力。对于初学者而言,这是一条很...

    Swing组件介绍(非常全)

    Swing组件基于AWT,但使用轻量级的组件模型,这意味着它们在内存和性能上更为高效。Swing提供了大量的组件,包括按钮、文本框、列表、表格、菜单等,这些组件使得开发者能够创建出复杂且交互性强的用户界面。 1. **...

    Java Swing组件写的游戏客户端.zip

    Java Swing组件写的游戏客户端Java Swing组件写的游戏客户端 Java Swing组件写的游戏客户端Java Swing组件写的游戏客户端 Java Swing组件写的游戏客户端Java Swing组件写的游戏客户端 Java Swing组件写的游戏客户端...

    Swing 扩展组件 Swing 扩展组件

    Swing扩展组件是Java Swing库中的一...同时,Swing组件的事件处理机制和模型-视图-控制器(MVC)设计模式也为程序的可维护性和可扩展性提供了保障。因此,深入理解和使用Swing扩展组件对于Java GUI开发者来说至关重要。

    基于Java swing组件实现简易计算器

    本文主要介绍了基于Java swing组件实现简易计算器的知识点,以下是相关知识点的总结: 1. JFrame组件:JFrame是Java swing组件中的一种顶层容器,用于创建一个窗口框架。通过创建一个JFrame对象,可以创建一个名为...

    Swing组件下载(常用组件)

    Swing是Java编程语言中...以上就是Swing组件的一些核心功能和用法,它们共同构成了Swing组件体系,为开发复杂的Java桌面应用提供了强大的支持。通过灵活组合和定制这些组件,开发者可以创建出满足各种需求的用户界面。

    常用Swing组件GUI设计

    常用Swing组件GUI设计,

    java实验报告之图形用户界面程序设计与 AWT/Swing组件

    在本实验报告中,主题是“Java实验报告之图形用户界面程序设计与AWT/Swing组件”,主要目标是让学生熟悉Java GUI设计原理、程序结构,掌握AWT和Swing组件的功能,以及学会应用这些组件来设计应用程序,特别是实现一...

    Swing组件类库 JIDE Common Layer

    JIDE Common Layer是一套很不错的Swing组件类库,它JIDE软件公司其他产品的基础,于2007年4月开源,在其开源之前是JIDE商业软件中的一部分。它包含将近10万行代码,超过30个的Swing组件和工具。 压缩包中含有对应的...

    swing 组件 demo

    在这个"Swing组件demo"中,我们可以深入学习Swing组件的使用方法和特性。 Swing组件包括但不限于: 1. **JFrame**: JFrame是窗口的基础类,它为其他组件提供了一个容器。在Swing应用中,通常会创建一个JFrame实例...

    swing各个组件实例演示

    本教程将深入探讨Swing组件的实例应用,帮助开发者更好地理解和掌握Swing在实际编程中的运用。 一、Swing组件基础 Swing组件主要由JComponent类及其子类构成,包括按钮(JButton)、文本框(JTextField)、标签...

    几个漂亮的SWING组件(源代码)

    标题提到的"几个漂亮的SWING组件(源代码)"很可能是包含了一些自定义或者美化过的Swing组件示例,供开发者参考学习。 在Swing组件库中,有许多基础和高级组件,包括但不限于: 1. **JFrame**: 这是大多数Swing...

Global site tag (gtag.js) - Google Analytics