swing 구성 요소 소개 (2)

다음은 JFormatted TextField 의 예 입 니 다. 이 예 에서 JFormatted TextField 세 개 는 각각 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 를 구성 할 때 모델 을 지정 할 수 있 습 니 다.
swing 은 세 가지 모델 을 제공 합 니 다:
SpinnerListModel,SpinnerNumberModel,SpinnerDateModel
구 조 는 Spinner Model 입 니 다.
  |_AbstractSpinnerModel
   |_SpinnerListModel,SpinnerNumberModel,SpinnerDateModel
대응 하 는 세 개의 Editor 가 있 습 니 다.
JSpinner. ListEditor, JSpinner. NumberEditor, JSpinner. DateEditor, 세 가 지 는 모두 JSpinner. DefaultEditor 의 하위 클래스 입 니 다.
JSpinner.DefaultEditor
|_JSpinner.ListEditor,JSpinner.NumberEditor,JSpinner.DateEditor
JSpinner 를 사용자 정의 할 수 있 는 공간 이 넓 습 니 다.
편집기 사용자 정의 가 필요 할 때 void setEditor (JComponent editor) 를 사용 할 수도 있 고, JSpinner. Default Editor. getTextField () 를 사용 하여 JFormatted TextField 를 얻 은 다음, 이 JFormatted TextField 를 호출 할 수도 있 습 니 다.
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
이 구성 요 소 는 너무 복잡 해서 아주 간단 하고 간단하게 소개 할 수 밖 에 없다.
하나의 나 무 는 뿌리 노드 와 하위 노드 로 구성 되 어 있 습 니 다. 모두 Default Mutable TreeNode 로 표 시 됩 니 다.
뿌리 노드 는 필수 적 이 며, 하위 노드 는 있어 도 되 고 없어 도 된다.
Default Mutable TreeNode 에 전 달 된 구조 방법 은 Object 입 니 다. JTree 를 구성 할 때 이 Object 의 toString () 을 호출 하여 JTree 에 표 시 된 노드 의 텍스트 를 가 져 옵 니 다.
void add (MutableTreeNode newChild) 를 호출 하여 키 노드 를 추가 합 니 다.
JTree 를 구성 할 때 Default Mutable TreeNode 가 표시 하 는 뿌리 를 구조 방법 JTree (TreeNode root) 에 전달 하면 나 무 를 구성 할 수 있 습 니 다.
JTree 는 Tree Selection Model 로 선택 항목 을 유지 합 니 다. 기본적으로 구현 클래스 Default Tree Selection Model 을 사용 합 니 다.
void addTree Selection Listener (Tree Selection Listener x) 를 통 해 선택 에 반응 할 수 있 습 니 다.
사용자 정의 JTree 모양
void setRootVisible (boolean rootVisible) 은 루트 노드 를 숨 길 지 여 부 를 설정 할 수 있 습 니 다.
void setShows RootHandles (boolean newValue) 설정 노드 앞 에 있 는 추가 번 호 를 표시 할 지 여부
void puutClient Property (Object key, Object value) 노드 간 연결 스타일 설정
노드 아이콘 을 사용자 정의 하려 면 Default TreeCellRenderer 를 사용 할 수 있 습 니 다. 이것 은 JLabel 의 글꼴 입 니 다.
void setClosed Icon (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 set Editable (boolean) 은 트 리 를 현지에서 편집 할 수 있 는 지 설정 할 수 있 습 니 다.
JTree 의 데이터 Model TreeModel 의 void addTreeModelListener (TreeModelListener l) 를 통 해 편집 이 발생 했 을 때 반응 할 수 있 습 니 다.
간단 한 응용 프로그램 은 TreeModel 의 실현 클래스 인 DefaultTree Model 을 사용 할 수 있 습 니 다. 그 구 조 는 JTree 와 마찬가지 로 나무의 뿌리 노드 를 들 여 보 냅 니 다. DefaultTreeModel (TreeNode root).
이 를 만 들 면 JTree 의 또 다른 구조 방법 인 JTree (Tree Model new Model) 로 나 무 를 만 들 수 있 습 니 다.

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 은 주로 셀 에 대해 글 을 씁 니 다. 기본 셀 은 label 입 니 다. JTree 와 마찬가지 로 JTable 을 만 들 때 String 대상 이 아 닌 다른 대상 을 전달 합 니 다.이 대상 의 toString 방법 이 호출 됩 니 다. 되 돌아 오 는 문자열 은 셀 의 label 에 표 시 됩 니 다. 이전 과 마찬가지 로 '렌 더러' 를 통 해 다른 구성 요 소 를 셀 에 표시 할 수 있 습 니 다.편집 상태 에 있 는 셀 의 기본 값 은 텍스트 상자 입 니 다. 편집 상태 에 있 는 셀 편집기 로 다른 구성 요 소 를 지정 할 수 있 습 니 다. (편집기 로 약칭) 특정한 형식의 데이터 에 편집 기 를 지정 할 수 있 습 니 다.한 열의 데이터 에 특정한 편집 기 를 지정 할 수도 있 습 니 다. 편집 기 는 사용자 가 입력 한 합 법성 을 검증 하 는 데 사용 할 수 있 습 니 다. 렌 더러 와 편집기 의 개념 은 JTree 와 비슷 합 니 다.
이 구성 요 소 는 보통 스크롤 창 에 놓 여 있 습 니 다. 스크롤 창의 viewport 로 표를 만 든 다음 스크롤 창 을 메 인 프레임 의 콘 텐 츠 창 (content pane) 에 추가 할 수 있 습 니 다. 그렇지 않 으 면 각각 표 머리 와 표를 프레임 창의 content pane 에 추가 해 야 합 니 다.
이 구성 요 소 는 이른바 모델 로 데 이 터 를 저장 합 니 다. TableModel 은 데 이 터 를 저장 하 는 데 사 용 됩 니 다. JList 와 마찬가지 로 선택 한 항목 을 ListSelection Model 로 저장 합 니 다. 또한 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 에 표 시 됩 니 다. 이전 과 마찬가지 로 '렌 더러' 를 통 해 다른 구성 요 소 를 셀 에 표시 할 수 있 습 니 다.편집 상태 에 있 는 셀 의 기본 값 은 텍스트 상자 입 니 다. 편집 상태 에 있 는 셀 편집기 로 다른 구성 요 소 를 지정 할 수 있 습 니 다. (편집기 로 약칭) 특정한 형식의 데이터 에 편집 기 를 지정 할 수 있 습 니 다.한 열의 데이터 에 특정한 편집 기 를 지정 할 수도 있 습 니 다. 편집 기 는 사용자 가 입력 한 합 법성 을 검증 하 는 데 사용 할 수 있 습 니 다. 렌 더러 와 편집기 의 개념 은 JTree 와 비슷 합 니 다.
이 구성 요 소 는 보통 스크롤 창 에 놓 여 있 습 니 다. 스크롤 창의 viewport 로 표를 만 든 다음 스크롤 창 을 메 인 프레임 의 콘 텐 츠 창 (content pane) 에 추가 할 수 있 습 니 다. 그렇지 않 으 면 각각 표 머리 와 표를 프레임 창의 content pane 에 추가 해 야 합 니 다.
이 구성 요 소 는 이른바 모델 로 데 이 터 를 저장 합 니 다. TableModel 은 데 이 터 를 저장 하 는 데 사 용 됩 니 다. JList 와 마찬가지 로 선택 한 항목 을 ListSelection Model 로 저장 합 니 다. 또한 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();
            }
        });
    }
}

좋은 웹페이지 즐겨찾기