swing组件介绍(2)

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

[code]

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();
}
}
[/code]
除了使用上面讲到的java.text包中的各种formatter,还可以使用javax.swing.text.MaskFormatter来限制用户可以输入的字符


[code]
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();
}
}
[/code]
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值的改变作出反应.


[code]
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();
}
}[/code]
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)来构造一棵树.


[code]
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();
}
}

[/code]
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类型时编辑器是一个按钮,用以选择颜色*/

[code]
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();
}
});
}
}


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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值