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 閱讀(945)
評論(0) 編輯 收藏 所屬分類:
Java