5. Java GUI Control 4

곰주·2022년 10월 13일
0
post-thumbnail

시험... 언제 끝날까......
시작도 안 했찌만 빨리 끝났으면 하는..... 히히

목차

  • Table Control
  • Tree Control
  • 1. Table Control

    기능

    Table 형태로 데이터를 저장할 수 있다.

    메서드

    Method 기능
    int getColumnCount() 열의 수 반환
    int getRowCount() 행의 수 반환
    Object getValueAt(int row, int column) row, column 위치에 있는 해당 데이터 반환
    String getColumnName(int column) 열 제목 반환
    int getSelectedRow() Table의 선택 행 번호 반환
    int getSelectedColumn() Table의 선택 열 번호 반환

    Table Control 예제 프로그램

  • "Insert" Button을 클릭하면 순위, 영화 제목, 관객 동원을 순위 입력값과 같은 행에 삽입 한다.
  • "Update" Button을 클릭하면 Table에서 선택한 행의 순위, 영화 제목, 관객 동원 데이터를 수정 한다.
  • "Delete" Button을 클릭하면 Table에서 선택한 행의 순위, 영화 제목, 관객 동원 데이터를 삭제 한다.
  • Source

    // Setting jTable1 Control Property
     jTable1.setModel(new javax.swing.table.DefaultTableModel(
                new Object [][] {
                    { new Integer(1), "로마의 휴일",  new Integer(1000000)},
                    { new Integer(2), "타이타닉",  new Integer(800000)},
                    { new Integer(3), "죽은 시인의 사회",  new Integer(600000)},
                    { new Integer(4), "쉬리",  new Integer(400000)},
                    {null, null, null}
                },
                new String [] {
                    "순위", "영화 제목", "관객 동원"
                }
            ) {
                Class[] types = new Class [] {
                    java.lang.Integer.class, java.lang.String.class, java.lang.Integer.class
                };
    
                public Class getColumnClass(int columnIndex) {
                    return types [columnIndex];
                }
            });
            jTable1.addMouseListener(new java.awt.event.MouseAdapter() {
                public void mouseClicked(java.awt.event.MouseEvent evt) {
                    jTable1MouseClicked(evt);
                }
            });
            
    // jTable1MouseClicked() Event Handler
    private void jTable1MouseClicked(java.awt.event.MouseEvent evt) {
    	int iCntRow = 0;
        iCntRow = jTable1.getSelected();	// 선택된 행 번호 반환.
        
        txtOrder.setText(jTable1.getValueAt(iCntRow, 0).toString());	// 순위 반환
        txtMovie.setText(jTable1.getValueAt(iCntRow, 1).toString());	// 영화 제목 반환
        txtGallery.setText(jTable1.getValueAt(iCntRow, 2).toString());	// 관객 동원 반환
    }
    
    // [Insert] Button Event Handler
    private void btnInsertActionPerformed(java.awt.event.ActionEvent evt) {
    	int iCntRow = 0;
        int iOrder = 0;
        int iGallery = 0;
        
        iCntRow = jTable1.getRowCount();
        for (int idx = 0; idx <jTabl1.getRowCount(); idx++) {
        	// Check the values in column 0 of each row
            if (jTable1.getValueAt(idx, 0) == null) {
            	iCntRow = idx;
                break;
            }
        }
        
        iOrder = Integer.parseInt(txtOrder.getText());
        jTable1.setValue(iOrder, iCntRow, 0);	// 순위 Setting
        
        jTable1.setValue(txtMovie.getText(), iCntRow, 1);	// 영화 제목 Setting
        
        iGallery = Integer.paresInt(txtGallery.getText());
        jTable1.setValueAt(iGallery, iCntRow, 2);	// 관객 동원 Setting
    }
    
    // [Update] Button Event Handler
    private void btnUpdateActionPerformed(java.awt.event.ActionEvent evt) {
    	int iCntRow = 0;
        int iOrder = 0;
        int iGallery = 0;
        
        iCntRow = jTable1.getSelectedRow();	// 선택된 행 번호 반환
        
        iOrder = Integer.parseInt(txtOrder.getText());
        jTable1.setValueAt(iOrder, iCntRow, 0);		// 순위 Setting
        
        jTable1.setValueAt(txtMovie.getText(), iCntRow, 1);	// 영화 제목 Setting
        
        iGallery = Integer.parseInt(txtGallery.getText());
        jTable1.setValueAt(iGallery, iCntRow, 2);	// 관객 동원 Setting
    }
    
    // [Delete] Button Event Handler
    private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {
    	MakeRowData objRowData;
        Vector myVC = new Vector();
        
        int iCntRow = 0;
        iCntRow = jTable1.getSelectedRow();		// 선택된 행의 번호 반환
        
        DefaultTableModel jTableModel = (DefaultTableModel)jTable1.getModel();
        
        // Step 1 : jTable -> myVC
        for (int iRow = 0; iRow < jTable1.getRowCount(); iRow++) {
        	objRowData = new MakeRowData();
            objRowData.strMovie = jTable1.getValueAt(iRow, 1).toString();
            objRowData.iGallery = Integer.parseInt(jTable1.getValueAt(iRow, 2).toString();
            myVC.add(objRowData);
        } else {
        	break;
        }
        
        // Step 2: Remove selected Row
        myVC.removeElementAt(iCntRow);
        jTableModel.removeRow(iCntRow);
        
        // Step 3 : myVC -> jTable1
        for (int idx = 0; idx < myVC.size(); idx++ {
        	objRowData = (MakeRowData)myVC.get(idx);
            jTable1.setValueAt(idx + 1, idx, 0);
            jTable1.setValueAt(objRowData.strMovie, idx, 1);
            jTable1.setValueAt(objRowData.iGallery, idx, 2);
        }
        
        // Step 4 : Add one dummy row to jTable1
        String[] strRecord = new String[jTable1.getColumnCount()];
        jTableModel.addRow(strRecord);
        
        txtOrder.setText(null);
        txtMovie.setText(null);
        txtGallery.setText(null);
    }
    
    public class MakeRowData {
    	public String strMovie;
        public int iGallery;
    }
    

    Design

    Table Model Property 세팅하기

    실행 결과

    (1) run

    (2) 순위, 영화 제목, 관객 동원을 입력 후 Insert 버튼 클릭

    (3) 로마의 휴일 선택 후 수정하고 Update 버튼 클릭

    선택 수정 후 버튼 클릭

    (4) 한신 선택 후 Delete 버튼 클릭

    선택 버튼 클릭

    자... 조건을 더 추가해 보도록 하겠다!

    조건 1 : 동일한 영화 제목(데이터)이 삽입되지 않도록 하기. (중복 데이터X)
    조건 2: 관객 동원 "수"에 따라 내림차순으로 정렬하기.

    Source

    import java.util.Collections;
    import java.util.Comparator;
    import java.util.Vector;
    import javax.swing.table.DefaultTableModel;
    
    // 기존 코드에서 수정하였다.
    // [Insert] Button Event Handler
    private void btnInsertActionPerformed(java.awt.event.ActionEvent evt) {
    	int iCntRow = 0;
        int iOrder = 0;
        int iGallery = 0;
        
        iCntRow = jTable1.getRowCount();
        for (int idx = 0; idx <iCntRow; idx++) {
        	// Check the values in column 0 of each row
            if (jTable1.getValueAt(idx, 0) == null) {
            	iCntRow = idx;
                break;
            }
        }
        
        // 같은 데이터(영화 제목)가 들어가지 않도록...
        
        for (int idx = 0; idx < iCntRow; idx++) {
        	if (jTable1.getValueAt(idx, 1).equals(txtMovie.getText())) {
            	System.out.println("이미 등록된 영화!");
            	break;
            } else {
    	        iOrder = Integer.parseInt(txtOrder.getText());
            	jTable1.setValue(iOrder, iCntRow, 0);	// 순위 Setting
                
        		jTable1.setValue(txtMovie.getText(), iCntRow, 1);	// 영화 제목 Setting
                
        		iGallery = Integer.paresInt(txtGallery.getText());
        		jTable1.setValueAt(iGallery, iCntRow, 2);	// 관객 동원 Setting
            }
        }
    }
    
    // [Sort] Button Event Handler (Vector 사용)
    private void btnSortActionPerformed(java.awt.event.ActionEvent evt) {
    	MakeRowData objRowData;
        Vector myVC = new Vector();
        
    	// 1. jTable1 -> myVC
        for (int iRow = 0; iRow <jTable1.getRowCount(); iRow++) {
        	if(jTable1.getValueAt(iRow, 0) != null) {
            	objRowData = new MakeRowData();
                objRowData.strMovie = jTable1.getValueAt(iRow, 1).toString();
                objRowData.iGallery = Integer.parseInt(jTable1.getValueAt(iRow, 2).toString());
                
                myVC.add(objRowData);
            } else {
            	break;
            }
        }
        
    	// 2. Sorting
        Collections.sort(myVC, new GalleryDescCompare());    
        
        // 3. myVC -< jTable1
        for (int idx = 0; idx < myVC.size(); idx++) {
        	objRowData = (MakeRowData)myVC.get(idx);
            jTable1.setValue(idx + 1, idx, 0);
            jTable1.setValueAt(objRowData.strMovie, idx, 1);
            jTable1.setValueAt(objRowData.iGallery, idx, 2);
        }
        
        // 4. Initalize TextField
        txtOrer.setText(null);
        txtMovie.setText(null);
        txtGallery.setText(null);
    }
    
    public class MakeRowData {
    	public String strMovie;
        public int iGallery;
    }
    
    public class GalleryDescCompare implements Comparator {
    	public int compate(Object arg0, Object arg1) {
        	// 오름차순 : Ascending(<) , 내림차순 : Descending(>)
            if (((MakeRowData)arg0).iGallery > (MakeRowData)arg1).iGallery) {
            	return -1;
            } else if (((MakeRowData)arg0).iGallery == ((MakeRowData)arg1).iGallery) {
            	return Integer.compare(((MakeRowData)arg0).iGallery, ((MakeDataRow)arg1).iGallery);
            } else {
            	return 1;
            }
        } 
    }
    

    Sort하는 또다른 방법

    // [Sort] Button Event Handler (ArrayList 사용)
    private void btnSortActionPerformed(java.awt.event.ActionEvent evt) {
    	TableRowSoter<TableModel> objSorter = new TableRowSorter<>(jTable1.getModel()); 
        // jTable이 가지고 있는 Model을 인스턴스화하여 objSorter라는 객체를 생성한 것임.
        jTable1.setRowSorter(objSorter);
        List<RowSorter.SortKey> SortKeys = new ArrayList<>();
        
        int columnIndexToSort = 2;  // 관객 동원 수로 sorting 하는 것이니까 2. ( 0 : 순위, 1 : 영화 제목)
        SortKeys.add(new RowSorter.SortKey(columnIndexToSort, SortOder.DESCENDING));  // 내림차순.
        objSorter.setSortKeys(SortKeys);
        objSorter.sort()
        
        for (int idx = 0; idx < jTable1.getRowCount(); idx++) {
        	if (jTable1.getValueAt(idx, 0) != null) {
            	jTable1.setValueAt(idx + 1, idx, 0);  // 순위 재조정
            } else {
            	break;
            }
        }
    }

    실행 결과

    (1) run

    (2) 로마의 휴일 추가해 보기...

    콘솔 창을 확인해 보면, 중복된 데이터는 추가되지 않는 것을 볼 수 있음!


    (3) 한신 추가하고 Sort 버튼 클릭


    2. Tree Control

    기능

    계층적인 자료를 보여 줄 수 있다. 폴더 구조와 같이 트리 형태의 데이터 구조이다.

    Tree 구조

  • Root 노드
  • Child 노드
  • Parent 노드
  • Model

    (1) Tree Model

    Tree 노드 간의 관계를 알려 주는 메서드가 정의되어 있는 인터페이스로, 데이터 보관 및 관리 담당이다.

    (2) Default Tree Model

    Tree Model의 모든 메서드를 미리 구현한다.

    (3) Method

    Method Function Object getChild(Object parent, int index) Parent Node의 자식들 중에 index에 해당하는 자식 노드 반환 int getChildCount(Object parent) 자식 노드 수 반환 boolean isLeaf(Object node) 말단 노드 여부 반환 ### TreeSelectionModel (1) 노드 선택 관리

    (2) Mode

  • SINGLE_TREE_ SELECTION : 한번에 한 노드만 선택
  • CONTIGUOUS_TREE_ SELECTION : 연속된 여러 노드 선택
  • DISCONTIGUOUS_TREE_ SELECTION : 연속하지 않은 여러 노드 선택
  • (3) Method

    Method Function
    void setSelectionPath(TreePath path) 한번에 하나의 노드 선택
    TreePath getSelectionPath() 선택한 노드의 path 반환
    void getSelectionPaths(TreePath[] paths) 여러 개의 노드를 다 선택
    TreePath[] getSelectionPaths() 선택한 여러 노드의 path 반환

    TreeNode

    (1) 노드의 상하관계 표현

    (2) DefaultMutableTreeNode

    (3) Method

    Method Function
    int getParent() 부모 노드 index 반환
    int getChildAt() 자식 노드 index 반환
    void add(MutableTreeNode newChild) 기존의 tree의 말단 노드로 newChild 추가
    void add(MutableTreeNode newChild, int index) 기존의 tree의 index 위치에 newChild 추가
    void remove(int index) index 위치에 노드 삭제
    void remove(MutableTreeNode aChild) aChild 노드 삭제
    void removeAllChildren() 모든 Child 노드 삭제
    void insetNodeInto(MutableTreeNode newChild, MutableTreeNode parent, int index) Paren 노드의 index 위치에 자식 노드로 newChild 추가
    void reload() 변경된 node를 포함한 전체 Tree 구조 반영
    void nodeStructureChanged(TreeNode node) Node의 하위 노드만을 업데이트

    ## Tree Control 예제 프로그램
  • Tree 폴더를 클릭 하면 Path(Label)에 Tree의 선택한 폴더의 경로를 출력한다.
  • Tree Expanded(tree 확장 시 발생), Tree Collapsed(tree 축소 시 발생) 이벤트를 활용한다.
  • Source

    import javax.swing.tree.*;
    
    // jTree1ValueChanged() Event Handler
    private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) {
    	DefaultMutableTreeNode node;
        node = (DefaultMutableTreeNode)jTree1.getLastSelectedPathComponent();
        
        if (node == null) {
        	return;
        }
        
        lblPath.setText("Path: " + node.getUserObject() + "선택 ! \n");
    }
    
    // jTree1TreeCollapsed() Event Handler
    private void jTree1TreeCollapsed(javax.swing.event.TreeExpansionEvent evt) {
    	lblPath.setText("Path: " + evt.getPath() + "\n");
    }
    
    // jTree1TreeExpanded() EventHandler
    private void jTree1Expanded(javax.swing.event.TreeExpansionEvent evt) {
    	lblPath.setText("Path: " + evt.getPath() + "\n");
    }

    Design

    Tree Event 설정

    실행 결과

    (1) run

    (2) colors 폴더 선택

    (3) Tree Collapsed, Tree Expanded

    Expanded Collapsed

    조건 추가해 보기...
    [추가] Button[삭제] Button 추가하기. 추가 버튼 클릭 시, 선택한 폴더의 Child Node로 "새 폴더"를 추가하고, 삭제 버튼 클릭 시 선택한 폴더를 삭제하는 기능을 추가하여 보자.

    Source

    import javax.swing.tree.*;
    import java.util.*;
    
    // 코딩 한 부분의 소스코드만 가져왔습닏아...
    public class MainFrame extends javax.swing.JFrame {
    	// Settingn Member Variable
        DefaultTreeModel dftTreeModel = null;
        DefaultTreeSelectionModel dftTreeSelectionModel = new DefaultSelectionModel();
        DefaultMutableTreeNode rootNode = new DefaultMutableTreeNode("강의자료");
        DefaultMutableTreeNode comNode = new DefaultTreeNode("컴퓨터언어");
        
        public MainFrame() {
        	intitComponents();
            
            // Selection Mode = SINGLE_SELECTION_MODE Setting
            dftTreeSelectionModel.setSelectionMode(1);
            
            // Create 컴퓨터언어 노드의 Child 노드
            Vector<DefaultMutableTreeNode> myVC = new Vector<>();
            String[] objFolder = {"Java", "C#", "JSP"};
            
            for (int idx = 0; idx < objFolder.length; idx++) {
            	// Create node object to add Vector element
                myVC.add(new DefaultMutableTreeNode(objFolder[idx]));
                comNode.add(myVC.get(idx));
            }
            
            // Add comNode as child node of rootNode
            rootNode.add(comNode);
            
            // Setting rootNode as DefaultTreeModel
            dftTreeModel = new DefaultModel(rootNode);
            
            // Setting dftTreeModel as TreeModel of jTree1
            jTree1.setModel(dftTreeModel);
            jTree1.setEditable(true);
            jScrollPane1.getViewport().add(jTree1, null);
        }
    }
    
    // jTree1ValueChanged() Event Handler
    private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) {
    	DefaultMutableTreeNode node;
        node = (DefaultMutableTreeNode)jTree1.getLastSelectedPathComponent();
        
        if (node == null) {
        	return;
        }
        
        lblPath.setText("Path: " + node.getUserObject() + "선택 ! \n");
    }
    
    // jTree1TreeCollapsed() Event Handler
    private void jTree1TreeCollapsed(javax.swing.event.TreeExpansionEvent evt) {
    	lblPath.setText("Path: " + evt.getPath() + "\n");
    }
    
    // jTree1TreeExpanded() EventHandler
    private void jTree1Expanded(javax.swing.event.TreeExpansionEvent evt) {
    	lblPath.setText("Path: " + evt.getPath() + "\n");
    }
    
    // [추가] Button Event Handler
    private void btnInsertActionPerformed(java.awt.event.ActionEvent evt) {
    	int index = 0;  // 추가된 새 폴더의 인덱스 저장하는 변수
        
        DefaultMutableTreeNode select_Node;
        select_Node = (DefaultMutableTreeNode)jTree1.getLastSelectedPathComponent();
        
        DefaultMutableTreeNode newFolder = new DefaultMutableTreeNode("새 폴더");
       index = select_Node.getChildCount();
       dftTreeModel.insertNodeInto(newFolder, select_Node, index);
       
       jTree1.setModel(dftTreeModel);
       jTree1.setSelectionModel(dftTreeSelectionModel);
       jScrollPane1.getViewport().add(jTree1, null);
    }
    
    // [삭제] Button Event Handler
    private void btnDeleteActionPerformed(java.awt.event.ActionEvent evt) {
    	DefaultMutableTreeNode select_Node;
        select_Node = (DefaultMutableTreeNode)jTree1.getLastSelectedPathComponent();
        
        dftTreeModel.removeNodeFromParent(select_Node);	// 선택한 노드 삭제
        
        jTree1.setModel(dftTreeModel);
        jTree1.setSelectionModel(dftTreeSelectionModel);
        jScrollPane1.getViewport().add(jTree1, null);
    }

    Design

    Tree Event 설정

    실행 결과

    (1) run

    (2) 컴퓨터언어 -> C# 클릭

    (3) 추가 버튼, 삭제 버튼 클릭

    추가 C# 선택 후 삭제
    profile
    아기코쟁이 🧑🏻‍💻

    0개의 댓글