posts - 41,  comments - 40,  trackbacks - 0

import java.awt.Font;
import java.awt.Color;
import java.awt.Toolkit;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.BorderLayout;
import java.awt.event.MouseEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;

import java.util.ArrayList;
import java.util.Enumeration;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.JComboBox;
import javax.swing.UIManager;
import javax.swing.JSplitPane;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.DefaultComboBoxModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.AbstractTableModel;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.border.EtchedBorder;
import javax.swing.border.TitledBorder;

/*********************************************************************
 *
 *
 * TableChooser.java
 *
 * Last modified: 2005-04-26
 *
 * Author: NeedJava
 *
 * E-Mail:
needjava@126.com
 *
 * Address: HeFei-AnHui-China
 *
 * Bug: 如果选中行头拖动,会发现表体不会跟着拖动,除非你拖动表体
 *
 * If you fixed this bug, please let us know, Thanks a lot.
 *
 *
 *********************************************************************/
class TableChooser extends JFrame
{
  private final boolean horizontal;

  private String[] tableTitle;
  private ArrayList primaryBody;
  private ArrayList prepareBody;
  private ArrayList selectBody;

  private ShowTableModel prepareModel;
  private ShowTableModel selectModel;
  private final RowHeaderModel prepareRowHeaderModel;
  private final RowHeaderModel selectRowHeaderModel;

  private final JTable prepareTable;
  private final JTable selectTable;
  private final JTable prepareRowHeaderTable;
  private final JTable selectRowHeaderTable;

  private final static int rowHeight=18;

  private final JScrollPane prepareTableJSP;
  private final JScrollPane selectTableJSP;

  private final JPanel prepareTablePanel;
  private final JPanel selectTablePanel;

  private final JSplitPane splitPane;


  /**
   *
   * 构造函数
   *
   */
  public TableChooser( boolean horizontal )
  {
    this.horizontal=horizontal;

    //设置程序标题栏
    this.setTitle( "选择框" );

    //不给最大化
    //this.setResizable( false );

    //设置程序界面大小
    this.setSize( new Dimension( 500, 400 ) );

    //将程序居中放置(方法1)
    Dimension paneSize=this.getSize();
    Dimension screenSize=Toolkit.getDefaultToolkit().getScreenSize();
    this.setLocation( ( screenSize.width-paneSize.width )/2, ( screenSize.height-paneSize.height )/2 );

    //将程序居中放置(方法2)
    //this.setLocationRelativeTo( null );

    //设置程序关闭的类型,防止关闭
    this.setDefaultCloseOperation( JFrame.DO_NOTHING_ON_CLOSE );

    //设置关闭程序
    this.addWindowListener( new WindowAdapter()
    {
      public void windowClosing( WindowEvent e )
      {
        closeApplication();
      }
    } );

 


    //////////////////////////////
    prepareTable=new JTable();
    selectTable=new JTable();


    //为待选、已选表格设置预设的绘制器
    ShowTableRenderer ShowTableRenderer=new ShowTableRenderer();
    prepareTable.setDefaultRenderer( Object.class, ShowTableRenderer );
    selectTable.setDefaultRenderer( Object.class, ShowTableRenderer );


    //设置是否可以拖动表头
    prepareTable.getTableHeader().setReorderingAllowed( false );
    selectTable.getTableHeader().setReorderingAllowed( false );


    //设置行高
    prepareTable.setRowHeight( rowHeight );
    selectTable.setRowHeight( rowHeight );

 


    //////////////////////////////
    prepareRowHeaderModel=new RowHeaderModel( 0, 1 );
    selectRowHeaderModel=new RowHeaderModel( 0, 1 );


    prepareRowHeaderTable=new JTable( prepareRowHeaderModel );
    selectRowHeaderTable=new JTable( selectRowHeaderModel );


    //为rowHeaderTable设置预设的绘制器
    prepareRowHeaderTable.setDefaultRenderer( Object.class, new RowHeaderRenderer( prepareTable ) );
    selectRowHeaderTable.setDefaultRenderer( Object.class, new RowHeaderRenderer( selectTable ) );


    //将rowHeaderTable固定宽度
    prepareRowHeaderTable.setPreferredScrollableViewportSize( new Dimension( 50, 0 ) );
    selectRowHeaderTable.setPreferredScrollableViewportSize( new Dimension( 50, 0 ) );


    //设置行高
    prepareRowHeaderTable.setRowHeight( rowHeight );
    selectRowHeaderTable.setRowHeight( rowHeight );


    //防止单元格有缝隙
    prepareRowHeaderTable.setIntercellSpacing( new Dimension( 0, 0 ) );
    selectRowHeaderTable.setIntercellSpacing( new Dimension( 0, 0 ) );


    //共用同一个ListSelectionModel,使两边的某行同时选中
    prepareRowHeaderTable.setSelectionModel( prepareTable.getSelectionModel() );
    selectRowHeaderTable.setSelectionModel( selectTable.getSelectionModel() );

 


    //////////////////////////////
    prepareTableJSP=new JScrollPane( prepareTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
    selectTableJSP=new JScrollPane( selectTable, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );


    //将rowHeaderTable作为row header加入JScrollPane的RowHeaderView区域
    prepareTableJSP.setRowHeaderView( prepareRowHeaderTable );
    selectTableJSP.setRowHeaderView( selectRowHeaderTable );


    //左上角修饰
    prepareTableJSP.setCorner( JScrollPane.UPPER_LEFT_CORNER, new RowHeaderCorner( prepareTable, "全选" ) );
    selectTableJSP.setCorner( JScrollPane.UPPER_LEFT_CORNER, new RowHeaderCorner( selectTable, "全选" ) );

 


    //////////////////////////////
    prepareTablePanel=new JPanel();
    selectTablePanel=new JPanel();


    prepareTablePanel.setLayout( new BorderLayout() );
    selectTablePanel.setLayout( new BorderLayout() );


    prepareTablePanel.add( prepareTableJSP, BorderLayout.CENTER );
    selectTablePanel.add( selectTableJSP, BorderLayout.CENTER );


    prepareTablePanel.setBorder( new TitledBorder( new EtchedBorder( EtchedBorder.LOWERED ), "待选人员" ) );
    selectTablePanel.setBorder( new TitledBorder( new EtchedBorder( EtchedBorder.LOWERED ), "已选人员" ) );


    //至少显示6行
    prepareTablePanel.setMinimumSize( new Dimension( 200, 150 ) );
    selectTablePanel.setMinimumSize( new Dimension( 200, 150 ) );

 


    //////////////////////////////
    if( horizontal )
      {
        splitPane=new JSplitPane( JSplitPane.HORIZONTAL_SPLIT, prepareTablePanel, selectTablePanel );
      }
    else{ splitPane=new JSplitPane( JSplitPane.VERTICAL_SPLIT, prepareTablePanel, selectTablePanel );
        }


    //拖动时显示窗口,否则只显示拖动的边框
    splitPane.setContinuousLayout( true );

    //可以点三角形图标只显示一个区域
    splitPane.setOneTouchExpandable( true );

    splitPane.setDividerLocation( 210 );

    //放好主要面板
    this.getContentPane().add( splitPane, BorderLayout.CENTER );


    getTableModel();
  }

 

  /**
   *
   * 得到原始的TableModel
   *
   */
  private final void getTableModel()
  {
    tableTitle=new String[]{ "是否选择", "标号" };
    primaryBody=new ArrayList();
    prepareBody=new ArrayList();
    selectBody=new ArrayList();

    for( int i=1; i<21; i++ )
       {
         Object[] row=new Object[2];

         row[0]=Boolean.FALSE;  //第一列为判断用的布尔值,也可new Boolean( false )

         row[1]=new Double( i );

         primaryBody.add( row );  //一行搞好后,增加进ArrayList中
         prepareBody.add( row );  //将待选内容初始为原始表格
       }


    ////////////////////////////////////////////////////////////////////////
    //
    // 将数据根据需求切分
    //
    ////////////////////////////////////////////////////////////////////////
    prepareModel=new ShowTableModel( prepareBody, tableTitle )
    {
      public void setValueAt( Object value, int row, int col )
      {
        super.setValueAt( value, row, col );  //需要让父来赋值

        Object rowObj = prepareBody.get( row );        //得到主表的那行内容
        int whichRow  = selectBody.indexOf( rowObj );  //查找次表有没有相同的那行记录

        if( this.getValueAt( row, col ).equals( Boolean.TRUE ) )  //如果此行记录的首列内容为选择
          {
            if( whichRow<0 )  //防止次表多次增加那行内容
              {
                selectBody.add( rowObj );
              }
          }
        else{ if( whichRow>=0 )
                {
                  selectBody.remove( whichRow );  //如果首列为取消选择,那么次表删除那行记录
                }
            }

        this.fireTableDataChanged();         //通告主表结构变化
        selectModel.fireTableDataChanged();  //通告次表结构变化

        selectRowHeaderModel.setRowCount( selectBody.size() );  //让次表行头跟着次表行数变化
      }
    };
    prepareTable.setModel( prepareModel );


    selectModel=new ShowTableModel( selectBody, tableTitle )
    {
      public void setValueAt( Object value, int row, int col )
      {
        super.setValueAt( value, row, col );  //需要让父来赋值

        if( this.getValueAt( row, col ).equals( Boolean.FALSE ) )
          {
            selectBody.remove( row );
          }

        prepareModel.fireTableDataChanged();  //通告主表结构变化
        this.fireTableDataChanged();          //通告次表结构变化

        selectRowHeaderModel.setRowCount( selectBody.size() );  //让次表行头跟着次表行数变化
      }
    };
    selectTable.setModel( selectModel );

    prepareRowHeaderModel.setRowCount( prepareBody.size() );
    selectRowHeaderModel.setRowCount( selectBody.size() );
  }

 

  /**
   *
   * 取消所有选择的人员
   *
   */
  private final void deselectAll()
  {
    for( int i=0; i<selectBody.size(); i++ )
       {
         ( (Object[])selectBody.get( i ) )[0]=Boolean.FALSE;  //将所有选择的行的第一列设为false
       }

    selectBody.clear();  //删除已经选择的内容

    prepareModel.fireTableDataChanged();  //通告主表结构变化
    selectModel.fireTableDataChanged();   //通告次表结构变化

    selectRowHeaderModel.setRowCount( selectBody.size() );  //让次表行头跟着次表行数变化
  }

 

  /**
   *
   * 关闭程序
   *
   *
   */
  private void closeApplication()
  {
    Toolkit.getDefaultToolkit().beep();

    int answer=JOptionPane.showConfirmDialog( TableChooser.this, "您真的要退出此系统?", "退出程序", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null );

    if( answer==JOptionPane.YES_OPTION )  //选择“是”
      {
        System.exit( 0 );
      }
    else if( answer==JOptionPane.NO_OPTION )  //选择“否”
           {
             return;
           }
  }


  /**
   *
   * 入口主程序
   *
   */
//*/////////////////////////////////////////////////////////////////////////////
  public static void main( String args[] )
  {
    //改变GUI字体
    Font font=new Font( "宋体", Font.PLAIN, 12 );
    Enumeration keys=UIManager.getLookAndFeelDefaults().keys();
    while( keys.hasMoreElements() )
         {
           Object key=keys.nextElement();

           if( UIManager.get( key ) instanceof Font )
             {
               UIManager.put( key, font );
             }
         }

    //改变ComboBox背景色
    UIManager.put( "ComboBox.foreground", Color.black );
    UIManager.put( "ComboBox.background", Color.white );
    UIManager.put( "ComboBox.disabledForeground", Color.gray );
    UIManager.put( "ComboBox.disabledBackground", Color.white );

    UIManager.put( "Viewport.background", Color.white );

    //new TableChooser( true ).setVisible( true );
    new TableChooser( false ).setVisible( true );
  }
//*/////////////////////////////////////////////////////////////////////////////
}

 

 

/***********************************************************
 *
 * 待选、已选表格行头用的渲染器Renderer
 *
 **********************************************************/
class RowHeaderRenderer extends JLabel implements TableCellRenderer
{
  private JTable refTable;
  private JTableHeader header;

  private Color headerForeground;
  private Color headerBackground;
  private Font headerFont;

  public RowHeaderRenderer( JTable refTable )
  {
    this.refTable=refTable;
    this.header=refTable.getTableHeader();

    this.headerForeground=header.getForeground();
    this.headerBackground=header.getBackground();
    this.headerFont=header.getFont();
  }

  public Component getTableCellRendererComponent( JTable table,
                                                  Object obj,
                                                  boolean isSelected,
                                                  boolean hasFocus,
                                                  int row,
                                                  int col )
  {
    this.setOpaque( true );

    //设为TableHeader的边框类型
    this.setBorder( UIManager.getBorder( "TableHeader.cellBorder" ) );

    //居中显示文字
    this.setHorizontalAlignment( CENTER );

    //设置背景色为TableHeader的背景色
    this.setBackground( headerBackground );

    if( isSelected )
      {
        //当选取单元格时,在row header上设置成选取颜色
        this.setForeground( Color.white );
        this.setBackground( UIManager.getColor( "ScrollBar.thumbShadow" ) );
        this.setFont( headerFont );
        this.setText( String.valueOf( row+1 )+"*" );    //显示行数
      }
    else{ this.setForeground( headerForeground );
          this.setFont( headerFont );
          this.setText( String.valueOf( row+1 ) );    //显示行数
        }

    return this;
  }
}

 

 

/***********************************************************
 *
 * 待选、已选表格行头用的Model
 *
 **********************************************************/
class RowHeaderModel extends DefaultTableModel
{
  RowHeaderModel( int row, int col )
  {
    super( row, col );
  }

  public boolean isCellEditable( int row, int col )
  {
    return false;  //整个行头不给编辑
  }
}

 

 

/***********************************************************
 *
 * 待选、已选表格左上角Corner
 *
 **********************************************************/
class RowHeaderCorner extends JLabel
{
  private JTable table;

  RowHeaderCorner( JTable table, String title )
  {
    super( title, JLabel.CENTER );

    this.table=table;

    this.addMouseListener( new MouseAdapter()
    {
      public void mousePressed( MouseEvent e )
      {
        tableSelectAll();
      }
    } );

    this.setBorder( UIManager.getBorder( "TableHeader.cellBorder" ) );
  }

  private void tableSelectAll()
  {
    table.selectAll();
  }
}

 

 

/***********************************************************
 *
 * 待选、已选表格用的渲染器Renderer
 *
 **********************************************************/
class ShowTableRenderer extends DefaultTableCellRenderer
{
  public Component getTableCellRendererComponent( JTable table,
                                                  Object obj,
                                                  boolean isSelected,
                                                  boolean hasFocus,
                                                  int row,
                                                  int col )
  {
    super.getTableCellRendererComponent( table,
                                         obj,
                                         isSelected,
                                         hasFocus,
                                         row,
                                         col );

    this.setHorizontalAlignment( JLabel.CENTER );  //居中显示文字

    return this;
  }
}

 

 

/***********************************************************
 *
 * 待选、已选表格用的Model
 *
 **********************************************************/
class ShowTableModel extends AbstractTableModel
{
  private ArrayList tableBody;
  private String[] tableTitle;

  ShowTableModel( ArrayList body, String[] title )
  {
    this.tableBody  = body;
    this.tableTitle = title;
  }

  public Object getValueAt( int row, int col )
  {
    if( row>=0&&row<tableBody.size()&&col>=0&&col<tableTitle.length )  //控制很严
      {
        return ( (Object[])tableBody.get( row ) )[col];
      }
    else{ return null;
        }
  }

  public void setValueAt( Object value, int row, int col )
  {
    ( (Object[])tableBody.get( row ) )[col]=value;
  }

  public int getColumnCount()
  {
    return tableTitle.length;
  }

  public String getColumnName( int col )
  {
    if( col>=0&&col<tableTitle.length )
      {
        return tableTitle[col];
      }
    else{ return "";
        }
  }

  public Class getColumnClass( int col )
  {
    if( col==0 )  //第一列为选择框
      {
        return Boolean.class;
      }

    return Object.class;
  }

  public int getRowCount()
  {
    return tableBody.size();
  }

  public boolean isCellEditable( int row, int col )
  {
    return ( col==0 );  //如果是第一列给编辑,其他不给
  }
}

posted on 2007-07-08 22:03 NeedJava 阅读(880) 评论(0)  编辑  收藏 所属分类: Java

只有注册用户登录后才能发表评论。


网站导航: