- 浏览: 167312 次
- 来自: 浙江杭州
文章分类
最新评论
-
dzgwt2004:
浏览器Active启用下
页面串口通信代码(activeX) -
q123126:
你好,我下载运行没效果,请问是什么原因呢。收不到也发不出。
页面串口通信代码(activeX) -
niceo:
呵呵!!
吧swing解说的这样。很好很好!!!
我在进行 A ...
swing组件介绍(1) -
lesskao:
<div class='quote_title' ...
swing组件介绍(1) -
wareis:
顶,支持多写些Swing的文章
swing组件介绍(1)
下面是一个JFormattedTextField的例子.在这个例子中的三个JFormattedTextField分别使用了NumberFormat的三个静态方法取得的NumberFormat,当它们失去焦点时,它们显示的文本就会被格式化再重新显示,如果输入的是无效的文本,则文本被重设为上次的有效文本.
除了使用上面讲到的java.text包中的各种formatter,还可以使用javax.swing.text.MaskFormatter来限制用户可以输入的字符
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值的改变作出反应.
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)来构造一棵树.
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类型时编辑器是一个按钮,用以选择颜色*/
24.Jtable 表格组件
没有比这个组件更复杂的了
它由标题头和单元格组成.而单元格又分为编辑状态和非编辑状态.自定义JTable主要是对单元格作文章.默认的单元格是一个label,和JTree一样,如果你在创建JTable的时候传递的是其他对象而不是String对象,则该对象的toString方法将被调用.它返回的字符串就会显示在单元格的label里.同以往一样,可以通过”渲染器”将其他组件显示在单元格里;而编辑状态下的单元格默认是一个文本框.可以通过指定CellEditor来指定其他的组件作为编辑状态下单元格的组件(简称编辑器).你可以为某一种类型的数据指定一种编辑器,也可以为一整列的数据指定特定的编辑器.编辑器可以用作验证用户输入的合法性.对于渲染器和编辑器的概念,是和JTree里的相似的
这个组件一般放在一个滚动窗格里.你可以把一个表格作为滚动窗格的viewport,然后再把滚动窗格添加到主框架的内容窗格(content pane)里.如果你不这样做,那么你必须分别把表格头和表格添加到框架窗口的content pane里.
这个组件也是用所谓的模型来保存它的数据的.TableModel就是用来保存数据的.而它和JList一样,用ListSelectionModel来保存选择了的项.另外它还有TableColumnModel来保存关于列的数据.下面几幅图总结了各部Model和Renderer的父子关系.
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组件的基础知识,包括以下几个核心点: 1. **基础组件**:Swing提供了许多基础组件,如按钮(JButton)、文本框(JTextField)、标签(JLabel)、复选框...
2. **跨平台一致性**:Swing组件是轻量级的,它们不依赖于底层操作系统,从而确保在不同平台上具有一致的外观和行为。 3. **外观和感觉(LookAndFeel)**:用户可以轻松改变程序的视觉样式,实现自定义的LookAnd...
Swing组件是Java编程语言中用于构建用户图形界面(GUI)的一部分,特别是在J2EE(Java 2 Platform, Enterprise Edition)环境中。Swing是Java Foundation Classes (JFC)的一部分,提供了一套丰富的组件库,允许...
Swing组件是Java GUI(图形用户界面)编程中的核心元素,它是Java Foundation Classes (JFC) 的一部分。Swing提供了一系列丰富的组件,用于构建功能强大的桌面应用程序。在本实例中,我们将深入探讨Swing组件的使用...
本文档将对 Java Swing 中的组件进行详细的介绍和分析。 JFrame Java Swing 中的 JFrame 是一个基本的窗口组件,继承自 java.awt.Frame 类。JFrame 提供了一个基本的窗口框架,可以用来创建多种类型的窗口应用程序...
普通swing组件用法
Swing 组件概述 Swing 是 Java 编程语言中的一组图形用户界面(GUI)组件,它们提供了丰富的用户界面元素,帮助开发者快速构建桌面应用程序。Swing 组件可以分为五大类:顶层容器、中间容器、特殊容器、基本组件和...
总之,Java Swing组件全演示旨在通过实际项目引导学习者深入理解Swing组件的使用和界面设计。通过这种方式,开发者不仅可以掌握基本组件的用法,还能培养解决问题和设计高效界面的能力。对于初学者而言,这是一条很...
Swing组件基于AWT,但使用轻量级的组件模型,这意味着它们在内存和性能上更为高效。Swing提供了大量的组件,包括按钮、文本框、列表、表格、菜单等,这些组件使得开发者能够创建出复杂且交互性强的用户界面。 1. **...
Java Swing组件写的游戏客户端Java Swing组件写的游戏客户端 Java Swing组件写的游戏客户端Java Swing组件写的游戏客户端 Java Swing组件写的游戏客户端Java Swing组件写的游戏客户端 Java Swing组件写的游戏客户端...
Swing扩展组件是Java Swing库中的一...同时,Swing组件的事件处理机制和模型-视图-控制器(MVC)设计模式也为程序的可维护性和可扩展性提供了保障。因此,深入理解和使用Swing扩展组件对于Java GUI开发者来说至关重要。
本文主要介绍了基于Java swing组件实现简易计算器的知识点,以下是相关知识点的总结: 1. JFrame组件:JFrame是Java swing组件中的一种顶层容器,用于创建一个窗口框架。通过创建一个JFrame对象,可以创建一个名为...
Swing是Java编程语言中...以上就是Swing组件的一些核心功能和用法,它们共同构成了Swing组件体系,为开发复杂的Java桌面应用提供了强大的支持。通过灵活组合和定制这些组件,开发者可以创建出满足各种需求的用户界面。
常用Swing组件GUI设计,
在本实验报告中,主题是“Java实验报告之图形用户界面程序设计与AWT/Swing组件”,主要目标是让学生熟悉Java GUI设计原理、程序结构,掌握AWT和Swing组件的功能,以及学会应用这些组件来设计应用程序,特别是实现一...
JIDE Common Layer是一套很不错的Swing组件类库,它JIDE软件公司其他产品的基础,于2007年4月开源,在其开源之前是JIDE商业软件中的一部分。它包含将近10万行代码,超过30个的Swing组件和工具。 压缩包中含有对应的...
在这个"Swing组件demo"中,我们可以深入学习Swing组件的使用方法和特性。 Swing组件包括但不限于: 1. **JFrame**: JFrame是窗口的基础类,它为其他组件提供了一个容器。在Swing应用中,通常会创建一个JFrame实例...
本教程将深入探讨Swing组件的实例应用,帮助开发者更好地理解和掌握Swing在实际编程中的运用。 一、Swing组件基础 Swing组件主要由JComponent类及其子类构成,包括按钮(JButton)、文本框(JTextField)、标签...
标题提到的"几个漂亮的SWING组件(源代码)"很可能是包含了一些自定义或者美化过的Swing组件示例,供开发者参考学习。 在Swing组件库中,有许多基础和高级组件,包括但不限于: 1. **JFrame**: 这是大多数Swing...