190520_Day28 정렬2


//InQueueTest
package com.encore.j0517;

import java.util.Scanner;

public class IntQueueTester {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        IntQueue s = new IntQueue(64);    // 최대 64개를 인큐할 수 있는 큐

        while (true) {
            System.out.println("현재 데이터 수:" + s.size() + " / "
                                                              + s.capacity());
            System.out.print("1.인큐 2.디큐 3.피크 4.덤프 0.종료:");

            int menu = scan.nextInt();
            if (menu == 0) break;

            int x;
            switch (menu) {
             case 1:                             // 인큐
                System.out.print("데이터:");
                x = scan.nextInt();
                try {
                    s.enque(x);
                 } catch (IntQueue.OverflowIntQueueException e) {
                    System.out.println("큐가 가득 찼습니다.");
                }
                break;

             case 2:                             // 디큐
                try {
                     x = s.deque();
                    System.out.println("디큐한 데이터는 " + x + "입니다.");
                 } catch (IntQueue.EmptyIntQueueException e) {
                    System.out.println("큐가 비어 있습니다.");
                }
                break;

             case 3:                             // 피크
                try {
                     x = s.peek();
                    System.out.println("피크한 데이터는 " + x + "입니다.");
                 } catch (IntQueue.EmptyIntQueueException e) {
                    System.out.println("큐가 비어 있습니다.");
                }
                break;

             case 4:                             // 덤프
                s.dump();
                break;
            }
        }
    }
}
//InQueue
package com.encore.j0517;

//정수 데이터를 담는 큐
public class IntQueue {
    private int max;            // 큐의 용량
    private int front;            // 첫 번째 요소 커서
    private int rear;            // 마지막 요소 커서
    private int num;            // 현재 데이터 수
    private int[] que;            // 큐 본체

    // 실행 시 예외:큐가 비어 있음
    public class EmptyIntQueueException extends RuntimeException {
        public EmptyIntQueueException() { }
    }

    // 실행 시 예외:큐가 가득 참
    public class OverflowIntQueueException extends RuntimeException {
        public OverflowIntQueueException() { }
    }

    // 생성자
    public IntQueue(int capacity) {
        num = front = rear = 0;
        max = capacity;
        try {
            que = new int[max];                // 큐 본체용 배열을  생성
        } catch (OutOfMemoryError e) {        // 생성할 수 없음
            max = 0;
        }
    }

    // 큐에 데이터를 인큐
    public int enque(int x) throws OverflowIntQueueException {
        if (num >= max)
            throw new OverflowIntQueueException();            // 큐가 가득 참
        que[rear++] = x;
        num++;
        if (rear == max)
            rear = 0;
        return x;
    }

    // 큐에서 데이터를 디큐
    public int deque() throws EmptyIntQueueException {
        if (num <= 0)
            throw new EmptyIntQueueException();                // 큐가 비어 있음
        int x = que[front++];
        num--;
        if (front == max)
            front = 0;
        return x;
    }

    // 큐에서 데이터를 피크 (프런트 데이터를 들여다봄)
    public int peek() throws EmptyIntQueueException {
        if (num <= 0)
            throw new EmptyIntQueueException();                // 큐가 비어 있음
        return que[front];
    }

    // 큐에서 x를 검색하여 인덱스(찾지 못하면 -1)를 반환
    public int indexOf(int x) {
        for (int i = 0; i < num; i++) {
            int idx = (i + front) % max;
            if (que[idx] == x)                                // 검색 성공
                return idx;
        }
        return -1;                                            // 검색 실패
    }

    // 큐를 비움
    public void clear() {
        num = front = rear = 0;
    }

    // 큐의 용량을 반환
    public int capacity() {
        return max;
    }

    // 큐에 쌓여 있는 데이터 수를 반환
    public int size() {
        return num;
    }

    // 큐가 비어 있나요?
    public boolean isEmpty() {
        return num <= 0;
    }

    // 큐가 가득 찼나요?
    public boolean isFull() {
        return num >= max;
    }

    // 큐 안의 모든 데이터를 프런트 → 리어 순으로 출력
    public void dump() {
        if (num <= 0)
            System.out.println("큐가 비어 있습니다.");
        else {
            for (int i = 0; i < num; i++)
                System.out.print(que[(i + front) % max] + " ");
            System.out.println();
        }
    }
}
  • 덤프는 데이터가 들어가 있는 공간~! (전체가 아닌 공간 안에 데이터가 있는 공간만!)
  • throw 는 return과 같음, 던지는 값이 Exception이란걸 보여주는 것

재귀(recursive)

  • 어떤 사건이 자기 자신 포함, 다시 자기 자신을 사용하여 정의

  • 메소드 내에서 자기메소드 호출

  • 프로그램을 간결하게(가독성을 이야기 하는것이 아님) , 코드라인 수를 줄일 수 있다.

  • 중요) 인자와 리턴이 명확하지 않으면 잘못된 결과, 또는 무한 반복(명확해야함!)

  • 종료조건을 넣어주어야 한다!

  • int gildong(int x)
    {
        gildong();
    }
  • public class RecursiveTest {
    
    
  int count=1;
  void gildong() {
      System.out.println("동에번쩍 서에번쩍~!!");
      if(count >= 10)return; //종료조건!!

      count++;

      gildong();//재귀호출!!  : 끝나는 조건이 없다면 StackOverflowError발생!!
  }

  public static void main(String[] args) {
      RecursiveTest rt = new RecursiveTest();
      rt.gildong();
  }

}






  팩토리얼

- 1부터 어떤 양의 정수 n까지의 정수를 모두 곱한것

- n = 3 , n! = 3 * 2 * 1

- 0! = 1 ,  n! = n * (n-1)

```java
package j0520;

import java.util.Scanner;

public class FactorialTest
{
    int factorial(int n)
    {
        if(n>0)
            return n * factorial(n-1); // 재귀호출
        else
            return 1; // 종료조건 (되돌아오기 기능)
    }//factorial


    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("1 이상의 정수 입력하세요");
            int n = sc.nextInt(10);
        FactorialTest ft = new FactorialTest();
            System.out.println( n + "의 팩토리얼 값은 " + ft.factorial(n) + "입니다.");
    }
}
//MyThrowDefine Test
package j0520;


class A
{
    void hello(String name)
    {
        if(name == null)
        {
        throw new NullPointerException(); // 강제 예외발생, void반환형에서는 return문과 같이 메소드를 제어
        }
        System.out.println("안녕, " + name);

    }
}
class My
{
    A a;
    public My()
    {
    A a = new A();
    }


    void callTest(String name)
    {
        try
        {
            a.hello(name);
        }catch (NullPointerException e) {
            System.out.println("이름 값을 전달하세요");
        }
    }
}
public class MyThrowDefineTest
{
    public static void main(String[] args)
    {
        My m = new My();
        String str = null;

        if(str == null)
        {
            System.out.println("#반드시 이름을 입력하세요");
            return;
        }
        m.callTest(str);
    }
}
//하노이

public class HanoiTest {
/*

<중간(값)수 구하기>
 - 조건 : 규칙적인(일정한) 수의 나열

 예)   1 2 3 의 중간값  : 2
     -------
     전체총합: 6
     왼쪽     : 1
     오른쪽  : 3   ===> 6-1-3  : 2

     4 5 6 7 8
     ---------
     전체총합: 30
     왼쪽     : 9
    오른쪽   : 15    ===> 30-9-15: 6 


move (3, 1, 3)     {1,2,3}원반을 1막대  ---> 3막대

     move(2, 1, 2)   {1,2}원반을 1막대  ---> 2막대
          move(1,1,3)   {1}원반을 1막대 --->  3막대  
              >>>  if문 false
                       >>>★  1       1 ------> 3
              >>>  if문 false
                       >>>★ 2            1 ------> 2    
          move(1,3,2)   {1}원반을 3막대 ---> 2막대
              >>>  if문 false
                       >>>★  1       3 ------> 2
              >>>  if문 false
     -----------------------------------------------
      >>>★ 3                 1 ------> 3
     -----------------------------------------------

     move(2, 2, 3) 
          move(1, 2, 1)
              >>> if문 false
                       >>>★ 1        2 ------> 1 
              >>> if문 false
                >>> ★2            2 ------> 3
          move(1, 1, 3)
              >>> if문 false
                       >>>★ 1        1 ------> 3
              >>> if문 false


*/    
    void move(int no, int x, int y) {
        //no:이동할 원반(원반갯수)  ,  x: 좌측기둥(막대)   , y: 우측기둥(막대)

        if(no>1)
            move(no-1, x,  6-x-y);

        System.out.println("["+no+"원반 옮기기]>> ["+x+"]번기둥 ----> ["+y+"]번기둥");

        if(no>1)
            move(no-1, 6-x-y, y);
              //  2, 2, 3
    }//move

    public static void main(String[] args) {
         HanoiTest ht = new HanoiTest();
         ht.move(5, 1, 3);//원반 3개를   1번막대에서 3번막대로 이동!!
    }

}

단순 삽입 정렬

  • 선택요소 : 2번째 요소부터 선택 1씩 증가
  • 선택요소를 그보다 더 앞쪽 알맞은 위치에 삽입하는 작업을 반복

선택정렬

import java.util.Scanner;

public class SelectionSortTest {
    void swap(int[]a, int idx1, int idx2) {//배열의 데이터 교환
        int temp = a[idx1];
        a[idx1]= a[idx2];
        a[idx2]= temp;
    }//swap    

   void selectionSort(int[]a, int n){
       for(int i=0; i<n-1; i++) {//
           int min=i;//min인덱스                                    0 , 1, 2, 3 (맨앞번지를 최소값이라고 간주)
           for(int j=i+1; j<n; j++) {//최소값 구하기  j= 1 , 2, 3, 4
             //[23,12,9,8,10]
             // 0   1 2 3  4
               if(a[j] < a[min]) {//기준최소값 보다 작은 값을 발견시
                   min = j;
               }
           }
           swap(a,i,min);
           //[8,12,9,23,10]
          //  0  1 2  3  4
       }
   }//selectionSort

   public static void main(String[] args) {
       Scanner scan = new Scanner(System.in);    

       System.out.println("==선택정렬==");
       System.out.print("요소수: ");
       int num = scan.nextInt();
       int []array = new int[num];

       for (int i = 0; i < array.length; i++) {
           System.out.print("array["+i+"]:");
           array[i]= scan.nextInt();
       }

       SelectionSortTest sst= new SelectionSortTest();
          sst.selectionSort(array, num);
       System.out.println("===== 선택정렬 후 결과 =====");
       for (int i = 0; i < array.length; i++) {
          System.out.println("array["+i+"]="+ array[i]);
       }    
   }
}

버블정렬

import java.util.Scanner;

public class BubbleSortTest {

/*

     int[] arr =   8   1   3   4   5   6   2
       인덱스        :  [0] [1] [2] [3] [4] [5] [6]





     int[] arr =   1   3   6   4   7   8   9
       인덱스        :  [0] [1] [2] [3] [4] [5] [6] 
                                      -------
                                  -------
                              -------
                          -------
                           4   6
                       ------
                  -------
    1회전 결과)     1   3   4   6   7   8   9
                                     ------
                                 ------
                             ------
                         -------
                     -------                                                        
    2회전 결과)     1   3   4   6   7   8   9   ===> 교환이 한번도 실행하지 않음!!


*/


    void swap(int[]a, int idx1, int idx2) {//배열의 데이터 교환
        int temp = a[idx1];
        a[idx1]= a[idx2];
        a[idx2]= temp;
    }//swap

    void bubbleSort(int[]a, int n) {
        int cnt=0;
        for(int i=0; i<n-1; i++) {//비교할 왼쪽 데이터, 정렬된 데이터(아래 for문을 1회 반복할때마다 최소값을 저장) 

            for(int j=n-1;  j>i; j--) {
            //비교할 오른쪽 데이터 [끝번지:(끝번지-1)], [(끝번지-1):(끝번지-2)]

                //비교횟수
                cnt++;
                if(a[j-1] > a[j]) {//오름차순의 경우
                    swap(a, j-1,  j);
                }
            }

        }
        System.out.println("비교횟수==>"+ cnt);
    }//bubbleSort



    public static void main(String[] args) {
       Scanner scan = new Scanner(System.in);    

       System.out.println("==버블정렬==");
       System.out.print("요소수: ");
       int num = scan.nextInt();
       int []array = new int[num];

       for (int i = 0; i < array.length; i++) {
           System.out.print("array["+i+"]:");
           array[i]= scan.nextInt();
       }

       BubbleSortTest bst = new BubbleSortTest();
         bst.bubbleSort(array, num);
       System.out.println("===== 버블정렬 후 결과 =====");
       for (int i = 0; i < array.length; i++) {
          System.out.println("array["+i+"]="+ array[i]);
       }
    }//main
}

버블정렬

import java.util.Scanner;

public class BubbleSortTest2 {

/*

     int[] arr =   8   1   3   4   5   6   2
       인덱스        :  [0] [1] [2] [3] [4] [5] [6]





     int[] arr =   1   3   6   4   7   8   9
       인덱스        :  [0] [1] [2] [3] [4] [5] [6] 
                                      -------
                                  -------
                              -------
                          -------
                           4   6
                       ------
                  -------
    1회전 결과)     1   3   4   6   7   8   9     : exchg ==> 1
                                     ------
                                 ------
                             ------
                         -------
                     -------                                                        
    2회전 결과)     1   3   4   6   7   8   9   ===> 교환이 한번도 실행하지 않음!!
                                                 : exchg ==> 0

*/


    void swap(int[]a, int idx1, int idx2) {//배열의 데이터 교환
        int temp = a[idx1];
        a[idx1]= a[idx2];
        a[idx2]= temp;
    }//swap

    void bubbleSort(int[]a, int n) {
        int cnt=0;
        for(int i=0; i<n-1; i++) {//비교할 왼쪽 데이터, 정렬된 데이터(아래 for문을 1회 반복할때마다 최소값을 저장) 


            int exchg = 0;//교환0번
            for(int j=n-1;  j>i; j--) {
            //비교할 오른쪽 데이터 [끝번지:(끝번지-1)], [(끝번지-1):(끝번지-2)]

                //비교횟수
                cnt++;
                if(a[j-1] > a[j]) {//오름차순의 경우
                    exchg++;        
                    swap(a, j-1,  j);
                }
            }//안쪽for
            if(exchg==0)break;  //이미 정렬이 되어있다면

        }//바깥for

        System.out.println("비교횟수==>"+ cnt);
    }//bubbleSort



    public static void main(String[] args) {
       Scanner scan = new Scanner(System.in);    

       System.out.println("==버블정렬==");
       System.out.print("요소수: ");
       int num = scan.nextInt();
       int []array = new int[num];

       for (int i = 0; i < array.length; i++) {
           System.out.print("array["+i+"]:");
           array[i]= scan.nextInt();
       }

       BubbleSortTest2 bst = new BubbleSortTest2();
         bst.bubbleSort(array, num);
       System.out.println("===== 버블정렬 후 결과 =====");
       for (int i = 0; i < array.length; i++) {
          System.out.println("array["+i+"]="+ array[i]);
       }
    }//main
}
Exception 위에는 Throwable이 있음
프로그램적으로 고칠 수 없는 것 : error
프로그램 실행 중 예기치 못한 경우 : Exception

RuntimeException 이 0으로 나눌때의 발생( int a = b/c; 에서 발생하는 ) 하는 ArrayIndexOutOfBoundsException의 부모임.

'클라우드 기반 웹 개발자 과정 공부 > JAVA' 카테고리의 다른 글

190520_Day28 정렬  (0) 2019.05.20
190506_Day23 복습 , 채팅방  (0) 2019.05.10
190509_Day22 소켓  (0) 2019.05.09
190508_Day21 복습, java.net  (0) 2019.05.08
190507 복습, 스레드, 수정 필요  (0) 2019.05.07

190520_Day28

//InQueueTest
package com.encore.j0517;

import java.util.Scanner;

public class IntQueueTester {
    public static void main(String[] args) {
        Scanner scan = new Scanner(System.in);
        IntQueue s = new IntQueue(64);    // 최대 64개를 인큐할 수 있는 큐

        while (true) {
            System.out.println("현재 데이터 수:" + s.size() + " / "
                                                              + s.capacity());
            System.out.print("1.인큐 2.디큐 3.피크 4.덤프 0.종료:");

            int menu = scan.nextInt();
            if (menu == 0) break;

            int x;
            switch (menu) {
             case 1:                             // 인큐
                System.out.print("데이터:");
                x = scan.nextInt();
                try {
                    s.enque(x);
                 } catch (IntQueue.OverflowIntQueueException e) {
                    System.out.println("큐가 가득 찼습니다.");
                }
                break;

             case 2:                             // 디큐
                try {
                     x = s.deque();
                    System.out.println("디큐한 데이터는 " + x + "입니다.");
                 } catch (IntQueue.EmptyIntQueueException e) {
                    System.out.println("큐가 비어 있습니다.");
                }
                break;

             case 3:                             // 피크
                try {
                     x = s.peek();
                    System.out.println("피크한 데이터는 " + x + "입니다.");
                 } catch (IntQueue.EmptyIntQueueException e) {
                    System.out.println("큐가 비어 있습니다.");
                }
                break;

             case 4:                             // 덤프
                s.dump();
                break;
            }
        }
    }
}
//InQueue
package com.encore.j0517;

//정수 데이터를 담는 큐
public class IntQueue {
    private int max;            // 큐의 용량
    private int front;            // 첫 번째 요소 커서
    private int rear;            // 마지막 요소 커서
    private int num;            // 현재 데이터 수
    private int[] que;            // 큐 본체

    // 실행 시 예외:큐가 비어 있음
    public class EmptyIntQueueException extends RuntimeException {
        public EmptyIntQueueException() { }
    }

    // 실행 시 예외:큐가 가득 참
    public class OverflowIntQueueException extends RuntimeException {
        public OverflowIntQueueException() { }
    }

    // 생성자
    public IntQueue(int capacity) {
        num = front = rear = 0;
        max = capacity;
        try {
            que = new int[max];                // 큐 본체용 배열을  생성
        } catch (OutOfMemoryError e) {        // 생성할 수 없음
            max = 0;
        }
    }

    // 큐에 데이터를 인큐
    public int enque(int x) throws OverflowIntQueueException {
        if (num >= max)
            throw new OverflowIntQueueException();            // 큐가 가득 참
        que[rear++] = x;
        num++;
        if (rear == max)
            rear = 0;
        return x;
    }

    // 큐에서 데이터를 디큐
    public int deque() throws EmptyIntQueueException {
        if (num <= 0)
            throw new EmptyIntQueueException();                // 큐가 비어 있음
        int x = que[front++];
        num--;
        if (front == max)
            front = 0;
        return x;
    }

    // 큐에서 데이터를 피크 (프런트 데이터를 들여다봄)
    public int peek() throws EmptyIntQueueException {
        if (num <= 0)
            throw new EmptyIntQueueException();                // 큐가 비어 있음
        return que[front];
    }

    // 큐에서 x를 검색하여 인덱스(찾지 못하면 -1)를 반환
    public int indexOf(int x) {
        for (int i = 0; i < num; i++) {
            int idx = (i + front) % max;
            if (que[idx] == x)                                // 검색 성공
                return idx;
        }
        return -1;                                            // 검색 실패
    }

    // 큐를 비움
    public void clear() {
        num = front = rear = 0;
    }

    // 큐의 용량을 반환
    public int capacity() {
        return max;
    }

    // 큐에 쌓여 있는 데이터 수를 반환
    public int size() {
        return num;
    }

    // 큐가 비어 있나요?
    public boolean isEmpty() {
        return num <= 0;
    }

    // 큐가 가득 찼나요?
    public boolean isFull() {
        return num >= max;
    }

    // 큐 안의 모든 데이터를 프런트 → 리어 순으로 출력
    public void dump() {
        if (num <= 0)
            System.out.println("큐가 비어 있습니다.");
        else {
            for (int i = 0; i < num; i++)
                System.out.print(que[(i + front) % max] + " ");
            System.out.println();
        }
    }
}
  • 덤프는 데이터가 들어가 있는 공간~! (전체가 아닌 공간 안에 데이터가 있는 공간만!)

  • throw 는 return과 같음, 던지는 값이 Exception이란걸 보여주는 것


재귀(recursive)

  • 어떤 사건이 자기 자신 포함, 다시 자기 자신을 사용하여 정의

  • 메소드 내에서 자기메소드 호출

  • 프로그램을 간결하게(가독성을 이야기 하는것이 아님) , 코드라인 수를 줄일 수 있다.

  • 중요) 인자와 리턴이 명확하지 않으면 잘못된 결과, 또는 무한 반복(명확해야함!)

  • 종료조건을 넣어주어야 한다!

  • int gildong(int x)
    {
        gildong();
    }
  • public class RecursiveTest {
    
    
  int count=1;
  void gildong() {
      System.out.println("동에번쩍 서에번쩍~!!");
      if(count >= 10)return; //종료조건!!

      count++;

      gildong();//재귀호출!!  : 끝나는 조건이 없다면 StackOverflowError발생!!
  }

  public static void main(String[] args) {
      RecursiveTest rt = new RecursiveTest();
      rt.gildong();
  }

}






  팩토리얼

- 1부터 어떤 양의 정수 n까지의 정수를 모두 곱한것
- n = 3 , n! = 3 * 2 * 1
- 0! = 1 ,  n! = n * (n-1)

```java
package j0520;

import java.util.Scanner;

public class FactorialTest
{
    int factorial(int n)
    {
        if(n>0)
            return n * factorial(n-1); // 재귀호출
        else
            return 1; // 종료조건 (되돌아오기 기능)
    }//factorial


    public static void main(String[] args)
    {
        Scanner sc = new Scanner(System.in);
        System.out.println("1 이상의 정수 입력하세요");
            int n = sc.nextInt(10);
        FactorialTest ft = new FactorialTest();
            System.out.println( n + "의 팩토리얼 값은 " + ft.factorial(n) + "입니다.");
    }
}
//MyThrowDefine Test
package j0520;


class A
{
    void hello(String name)
    {
        if(name == null)
        {
        throw new NullPointerException(); // 강제 예외발생, void반환형에서는 return문과 같이 메소드를 제어
        }
        System.out.println("안녕, " + name);

    }
}
class My
{
    A a;
    public My()
    {
    A a = new A();
    }


    void callTest(String name)
    {
        try
        {
            a.hello(name);
        }catch (NullPointerException e) {
            System.out.println("이름 값을 전달하세요");
        }
    }
}
public class MyThrowDefineTest
{
    public static void main(String[] args)
    {
        My m = new My();
        String str = null;

        if(str == null)
        {
            System.out.println("#반드시 이름을 입력하세요");
            return;
        }
        m.callTest(str);
    }
}
//하노이

public class HanoiTest {
/*

<중간(값)수 구하기>
 - 조건 : 규칙적인(일정한) 수의 나열

 예)   1 2 3 의 중간값  : 2
     -------
     전체총합: 6
     왼쪽     : 1
     오른쪽  : 3   ===> 6-1-3  : 2

     4 5 6 7 8
     ---------
     전체총합: 30
     왼쪽     : 9
    오른쪽   : 15    ===> 30-9-15: 6 


move (3, 1, 3)     {1,2,3}원반을 1막대  ---> 3막대

     move(2, 1, 2)   {1,2}원반을 1막대  ---> 2막대
          move(1,1,3)   {1}원반을 1막대 --->  3막대  
              >>>  if문 false
                       >>>★  1       1 ------> 3
              >>>  if문 false
                       >>>★ 2            1 ------> 2    
          move(1,3,2)   {1}원반을 3막대 ---> 2막대
              >>>  if문 false
                       >>>★  1       3 ------> 2
              >>>  if문 false
     -----------------------------------------------
      >>>★ 3                 1 ------> 3
     -----------------------------------------------

     move(2, 2, 3) 
          move(1, 2, 1)
              >>> if문 false
                       >>>★ 1        2 ------> 1 
              >>> if문 false
                >>> ★2            2 ------> 3
          move(1, 1, 3)
              >>> if문 false
                       >>>★ 1        1 ------> 3
              >>> if문 false


*/    
    void move(int no, int x, int y) {
        //no:이동할 원반(원반갯수)  ,  x: 좌측기둥(막대)   , y: 우측기둥(막대)

        if(no>1)
            move(no-1, x,  6-x-y);

        System.out.println("["+no+"원반 옮기기]>> ["+x+"]번기둥 ----> ["+y+"]번기둥");

        if(no>1)
            move(no-1, 6-x-y, y);
              //  2, 2, 3
    }//move

    public static void main(String[] args) {
         HanoiTest ht = new HanoiTest();
         ht.move(5, 1, 3);//원반 3개를   1번막대에서 3번막대로 이동!!
    }

}

단순 삽입 정렬

  • 선택요소 : 2번째 요소부터 선택 1씩 증가
  • 선택요소를 그보다 더 앞쪽 알맞은 위치에 삽입하는 작업을 반복

선택정렬

import java.util.Scanner;

public class SelectionSortTest {
    void swap(int[]a, int idx1, int idx2) {//배열의 데이터 교환
        int temp = a[idx1];
        a[idx1]= a[idx2];
        a[idx2]= temp;
    }//swap    

   void selectionSort(int[]a, int n){
       for(int i=0; i<n-1; i++) {//
           int min=i;//min인덱스                                    0 , 1, 2, 3 (맨앞번지를 최소값이라고 간주)
           for(int j=i+1; j<n; j++) {//최소값 구하기  j= 1 , 2, 3, 4
             //[23,12,9,8,10]
             // 0   1 2 3  4
               if(a[j] < a[min]) {//기준최소값 보다 작은 값을 발견시
                   min = j;
               }
           }
           swap(a,i,min);
           //[8,12,9,23,10]
          //  0  1 2  3  4
       }
   }//selectionSort

   public static void main(String[] args) {
       Scanner scan = new Scanner(System.in);    

       System.out.println("==선택정렬==");
       System.out.print("요소수: ");
       int num = scan.nextInt();
       int []array = new int[num];

       for (int i = 0; i < array.length; i++) {
           System.out.print("array["+i+"]:");
           array[i]= scan.nextInt();
       }

       SelectionSortTest sst= new SelectionSortTest();
          sst.selectionSort(array, num);
       System.out.println("===== 선택정렬 후 결과 =====");
       for (int i = 0; i < array.length; i++) {
          System.out.println("array["+i+"]="+ array[i]);
       }    
   }
}

버블정렬

import java.util.Scanner;

public class BubbleSortTest {

/*

     int[] arr =   8   1   3   4   5   6   2
       인덱스        :  [0] [1] [2] [3] [4] [5] [6]





     int[] arr =   1   3   6   4   7   8   9
       인덱스        :  [0] [1] [2] [3] [4] [5] [6] 
                                      -------
                                  -------
                              -------
                          -------
                           4   6
                       ------
                  -------
    1회전 결과)     1   3   4   6   7   8   9
                                     ------
                                 ------
                             ------
                         -------
                     -------                                                        
    2회전 결과)     1   3   4   6   7   8   9   ===> 교환이 한번도 실행하지 않음!!


*/


    void swap(int[]a, int idx1, int idx2) {//배열의 데이터 교환
        int temp = a[idx1];
        a[idx1]= a[idx2];
        a[idx2]= temp;
    }//swap

    void bubbleSort(int[]a, int n) {
        int cnt=0;
        for(int i=0; i<n-1; i++) {//비교할 왼쪽 데이터, 정렬된 데이터(아래 for문을 1회 반복할때마다 최소값을 저장) 

            for(int j=n-1;  j>i; j--) {
            //비교할 오른쪽 데이터 [끝번지:(끝번지-1)], [(끝번지-1):(끝번지-2)]

                //비교횟수
                cnt++;
                if(a[j-1] > a[j]) {//오름차순의 경우
                    swap(a, j-1,  j);
                }
            }

        }
        System.out.println("비교횟수==>"+ cnt);
    }//bubbleSort



    public static void main(String[] args) {
       Scanner scan = new Scanner(System.in);    

       System.out.println("==버블정렬==");
       System.out.print("요소수: ");
       int num = scan.nextInt();
       int []array = new int[num];

       for (int i = 0; i < array.length; i++) {
           System.out.print("array["+i+"]:");
           array[i]= scan.nextInt();
       }

       BubbleSortTest bst = new BubbleSortTest();
         bst.bubbleSort(array, num);
       System.out.println("===== 버블정렬 후 결과 =====");
       for (int i = 0; i < array.length; i++) {
          System.out.println("array["+i+"]="+ array[i]);
       }
    }//main
}

버블정렬

import java.util.Scanner;

public class BubbleSortTest2 {

/*

     int[] arr =   8   1   3   4   5   6   2
       인덱스        :  [0] [1] [2] [3] [4] [5] [6]





     int[] arr =   1   3   6   4   7   8   9
       인덱스        :  [0] [1] [2] [3] [4] [5] [6] 
                                      -------
                                  -------
                              -------
                          -------
                           4   6
                       ------
                  -------
    1회전 결과)     1   3   4   6   7   8   9     : exchg ==> 1
                                     ------
                                 ------
                             ------
                         -------
                     -------                                                        
    2회전 결과)     1   3   4   6   7   8   9   ===> 교환이 한번도 실행하지 않음!!
                                                 : exchg ==> 0

*/


    void swap(int[]a, int idx1, int idx2) {//배열의 데이터 교환
        int temp = a[idx1];
        a[idx1]= a[idx2];
        a[idx2]= temp;
    }//swap

    void bubbleSort(int[]a, int n) {
        int cnt=0;
        for(int i=0; i<n-1; i++) {//비교할 왼쪽 데이터, 정렬된 데이터(아래 for문을 1회 반복할때마다 최소값을 저장) 


            int exchg = 0;//교환0번
            for(int j=n-1;  j>i; j--) {
            //비교할 오른쪽 데이터 [끝번지:(끝번지-1)], [(끝번지-1):(끝번지-2)]

                //비교횟수
                cnt++;
                if(a[j-1] > a[j]) {//오름차순의 경우
                    exchg++;        
                    swap(a, j-1,  j);
                }
            }//안쪽for
            if(exchg==0)break;  //이미 정렬이 되어있다면

        }//바깥for

        System.out.println("비교횟수==>"+ cnt);
    }//bubbleSort



    public static void main(String[] args) {
       Scanner scan = new Scanner(System.in);    

       System.out.println("==버블정렬==");
       System.out.print("요소수: ");
       int num = scan.nextInt();
       int []array = new int[num];

       for (int i = 0; i < array.length; i++) {
           System.out.print("array["+i+"]:");
           array[i]= scan.nextInt();
       }

       BubbleSortTest2 bst = new BubbleSortTest2();
         bst.bubbleSort(array, num);
       System.out.println("===== 버블정렬 후 결과 =====");
       for (int i = 0; i < array.length; i++) {
          System.out.println("array["+i+"]="+ array[i]);
       }
    }//main
}
Exception 위에는 Throwable이 있음
프로그램적으로 고칠 수 없는 것 : error
프로그램 실행 중 예기치 못한 경우 : Exception

RuntimeException 이 0으로 나눌때의 발생( int a = b/c; 에서 발생하는 ) 하는 ArrayIndexOutOfBoundsException의 부모임.

'클라우드 기반 웹 개발자 과정 공부 > JAVA' 카테고리의 다른 글

190520_Day28 정렬2  (0) 2019.05.21
190506_Day23 복습 , 채팅방  (0) 2019.05.10
190509_Day22 소켓  (0) 2019.05.09
190508_Day21 복습, java.net  (0) 2019.05.08
190507 복습, 스레드, 수정 필요  (0) 2019.05.07

190506_Day23 복습


소켓

  • java.net.Socket
  • 서로 다른 JVM간의 통신수단 ( 비유 : 휴대폰 )
  • 스트림을 기반으로 하는 통신!
  • Stream - InputStream (읽기)
  • Stream - OutputStream(쓰기)
  • Socket s = new Socket();
  • InputStream is = s.getInputStream();
  • OutputStream os = s.getOutputStream();
  • os.write(); // 스트림에 쓰기 작업
  • is.read(); // 스트림으로부터 읽기 작업

<서버> : JVM 192.168.0.y 엄마객체, (서비스)응답객체

<클라이언트> : JVM 192.168.0.x 아이객체, 때쟁이객체, 서비스요청객체

<클라이언트> <서버>
1. ServerSocket ss = new ServerSocket(3000); // ip .y PC에서 소켓서비스를 준비하겠음! , port ( 0 ~ 65535 )
2. ss.accept(); // 클라이언트가 접속하길 대기( 블로킹상태 )
3. Socket s = new Socket( "192.168.0.y", 3000 ): //네트워크상에서 서비스PC찾기, 서비스종류(포트번호) 3-1 Socket s = ss.accept(); //접속한 클라이언트의 소켓 정보 리턴
=>접속요청!
4. BufferedReader in = BufferedReader(new InputStreamReader(s.getInputStream)); 4. BufferedReader in;
=> in : 서버가 전달한 메시지 읽기 => in : 클라이언트가 전달한 메시지 읽기
OutputStream out = s.getOutputStream(); OutputStream out;
=> out : 서버에게 메시지 쓰기 => out : 클라이언트에 메시지 쓰기
공통 : 5. 쓰기, 6 : 읽기, 7 : 쓰기, 8 : 읽기
tf값을 [스트림에 쓰기] 5. write -------------------------> 6. String str = readLine();
8. String str = readLine() ; <-------------------------- 7. Write("hello\n".getBytes());
ta.append(str + "\n")
대화명 값을 [스트림에 쓰기] 9.write -------------------------> 길동이 10.String str = readLine() // 길동이
String str = readLine(); <-------------------------- 11. Write("길동이 \n".getBytes)
ta.append(str + "\n")
  • 이건 1:1 방식이고 여러명 하려면 Vector사용 , 위의 표 수정 필요

'클라우드 기반 웹 개발자 과정 공부 > JAVA' 카테고리의 다른 글

190520_Day28 정렬2  (0) 2019.05.21
190520_Day28 정렬  (0) 2019.05.20
190509_Day22 소켓  (0) 2019.05.09
190508_Day21 복습, java.net  (0) 2019.05.08
190507 복습, 스레드, 수정 필요  (0) 2019.05.07

190509_Day22 소켓


RMI

SOCKET

네트워크 중 두가지가 있다.

  • TCP : 전화기,데이터 손실 없는 신뢰성
  • UDP : 우편
  • 오늘은 TCP~!

img

  • Socket이라는것은 양쪽이 가지고 있는 전화기 같은것(통신수단)

  • <TCP전송방식>

    1. 연결방식
      • 연결기반(connection-oriented)
      • 연결 후 통신(전화기)
      • 1:1 통신방식
    2. 특징
      • 데이터의 경계를 구분 안 함.(byte-stream)
      • 신뢰성 있는 데이터 전송
      • 데이터의 전송순서가 보장.
      • 데이터의 수신여부를 확인함(데이터가 손실되면 재전송)
      • 패킷을 관리할 필요가 없음
      • UDP보다 전송속도가 느림
    3. 관련 클래스
      • Socket, ServerSocket

    <TCP소켓프로그래밍>

    1. 서버 프로그램: 서버소켓을 사용, 서버 컴퓨터의 특정포트에서
      클라이언트의 연결요청을 처리할 준비
    2. 클라이언트 프로그램: 접속할 서버의 IP주소와 포트 정보를 가지고 소켓을 생성해서
      서버에 연결을 요청.
    3. 서버소켓은 클라이언트의 연결요청을 받으면 서버에 새로운 소켓을 생성해서
      클라이언트의 소켓과 연결되도록 한다.
    4. 클라이언트의 소켓과 서버의 소켓이 일대일 통신.

<Socket프로그램>

  • Socket은 전화기!!
  • Server와 Client사이에 통신하려면 Socket을 통해 연결

=>Server ( 클라이언트의 연결 대기 상태를 표현 )

  • ServerSocket객체를 가져야 함.

  • //=>Server
    ServerSocket ss = new ServerSocket(서비스 할 포트넘버 예5000); //[작업순서1]
    //만약 '서버소켓'객체를 실행하는 JVM의 IP가 192.168.0.x라고 했을 때 이는 PC를 구별하는 번호
    //192.168.0.x의 5000번 포트로 소켓 서비스를 실행하겠음!
    Socket s = ss.accept();// 연결대기상태표현, 클라이언의트 접속 대기 : [2]
    
    //'서버' => '클라이언트'에게 메시지 전달
    
    OutputStream out = s.getOutputStream(); // 클라이언트에 메세지 전송
    out.write("전송할 메세지");//[4]
    
    InputStream in = s.getInputStream();//클라이언트가 전달한 메시지 읽어오기
    in.read(); //스트림으로부터 읽기 작업[7]
  • //=>Client
    //Socket객체를 생성
    Socket s = new Socket("HOST정보", port번호);//서버소켓 연결 요청 [3]
    InputStream in = s.getInputStream(); //서버가 전달한 메세지 읽어오기
    in.read();//스트림으로부터 읽기 작업[5]
    OutputStream out = s.getOutputStream();//서버에 메시지 전송
    out.write("나도안녕"); //스트림에 쓰기 작업 [6]
    
  • package j0509;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStream;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.Socket;
    import java.net.UnknownHostException;
    
    public class EchoClient
    {
    
    
  public static void main(String[] args) throws UnknownHostException, IOException
  {
      Socket s = new Socket("localhost", 5000);

      System.out.println("서버연결 성공");

      //[4] 소켓을 통헤 입출력 (통신) 하기 위한 객체 생성
      InputStream is = s.getInputStream(); // 읽기 객체
      //읽기작업을 편하게 하기 위해
      BufferedReader in = new BufferedReader(new InputStreamReader(is));
      OutputStream out = s.getOutputStream(); // 쓰기 객체

      //[5]write [6]read [7]write [8]read 서버와 클라가 각각 번달아가며

      //[6]메시지 읽기
      String msg = in.readLine();
      System.out.println("from Server => " + msg);

      //[7]메시지 보내기
      String toMsg="햄벅\n";
      out.write(toMsg.getBytes());

  }//클라이언트main    

}


- ```java
  package j0509;

  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.InputStreamReader;
  import java.io.OutputStream;
  import java.net.ServerSocket;
  import java.net.Socket;

  public class EchoServer
  {
      // 주된 업무 : 소켓 서비스
      // 필요자원 : ServerSocket!
      // 응답대기 : accept()
      // 소켓채널에 대한 입출력
      // 출력 write : 데이터 보내기 
      // 입력 read : 데이터 읽기


      public static void main(String[] args) throws IOException
      {
          //[1]
              ServerSocket ss = new ServerSocket(5000);
              //서버 소켓을 실행하는 JVM이 갖는 ip주소와 명시된 port 번호로 소켓서비스를 시작할 준비

              System.out.println( "서버 시작 (접속대기중) ......" );
              Socket s = ss.accept(); //[2] 클라이언트 접속 대기 메소드
              // s : 접속한 클라이언트의 소켓정조가 저장

              String addr = s.getInetAddress().getHostAddress(); // Client ip알아내기
              System.out.println("클라이언트 접속 성공!");

              //[4] 소켓을 통헤 입출력 (통신) 하기 위한 객체 생성
              InputStream is = s.getInputStream(); // 읽기 객체
              //읽기작업을 편하게 하기 위해
              BufferedReader in = new BufferedReader(new InputStreamReader(is));
              OutputStream out = s.getOutputStream(); // 쓰기 객체

              //[5]write [6]read [7]write [8]read 서버와 클라가 각각 번달아가며

              //[5]메시지 보내기
              String msg = " 점심 뭐 먹니? \n"; //\n이 구분자 안보내면 줄 안바뀌어서 readLine()이 계속 대기함
              out.write(msg.getBytes());

              //[8]메시지 읽기
              String fromMsg = in.readLine();
              System.out.println("From client[" + addr + "]" + fromMsg);



      }//서버main    

  }
  • ava.net.BindException 이런 에러 자주 발생한다. 같은 포트에 똑같이 접속 요구하면 이렇게 된다. => CMD로 서버 틀고 이클립스로 Client 실행하는 방식으로 해결

  • 그런데 이 방식으로는 주고 받는 것은 불가하고, 한개식 받는 방법 밖에 없다

  • 이를 해결하기 위해 쓰레드!

  • <서버>

    • (소켓)클라이언트 접속 대기
    • 클라이언트 한개가 메시지를 쓰면
      ----read()----->
      접속된 모든 클라이언트에게 메시지
      ----writeAll()---->
  • package j0509;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Vector;
    
    import j0509.Server.Service;
    
    public class Server implements Runnable //외부클래스 : 소켓을 통한 접속서비스 ( 접속대기 )
    {
        ServerSocket ss;
        Vector <Service>v; //접속한 클라이언트 관리
    
        public Server()
        {
            System.out.println("Server Start......");
            v = new Vector<>();
            try
            {
                ss = new ServerSocket(3000); // [1] 서버소켓 객체 생성
                new Thread(this).start();
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }//외부 클래스 생성자
    
        public void run() //여러 클라이언트 접속
        {
            try
            {
                while(true)
                {
                Socket s = ss.accept(); // [2] 클라이언트 접속 대기 ( 클라이언트 프로그램 : new Socket()과 매핑 ) 
    //            Service serv = new Service(s); // 이걸 아래처럼 한줄로!
    //            v.add(serv);
                v.add(new Service(s));
                }
            } catch (IOException e)
            {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }
    
        //===============================================
        class Service extends Thread // 내부클래스 : 소켓을 통한 입출력 서비스
        {
            //※ Service객체 한개 == 클라이언트 한개!
    
            BufferedReader in; // 소켓을 통해서 읽기
            OutputStream out; // 소켓에 쓰기
    
            String clientAddr;
            String nickName;
    
            public Service(Socket s)
            {
                try
                {
                    //★☆ [4]소켓 입출력 객체 생성
                    in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                    out = s.getOutputStream();
                    clientAddr = s.getInetAddress().getHostAddress();
                    start();
                } catch (IOException e)
                {
                    e.printStackTrace();
                }
    
            } //내부 클래스 생성자
    
            public void run() //클라이언트가 보내는 여러메시지를 읽어주는 기능
            {
            try
                {
                while(true)
                {
                        String msg = in.readLine();
    
                        //모니터링
                        System.out.println(" [ " + clientAddr +" ] > > > " + msg);
    
                        String arr[] = msg.split("\\|");
                        //arr = { "100", "홍길동"} arr = { "200", "안녕하세요"}
                        switch (arr[0])
                        {
                        case "100": //대화명 전달
                            nickName = arr[1];
                            break;
    
                        case "200" : //메시지 전달
                            messageAll(" [ " + nickName +" ] " + arr[1]); // [홍길동] -> 안녕하세요
                        }
    
                }
    //                    messageAll(msg);
                        // [6]번혹은 [8]번이 될 수 있다. 클라이언트가 tf보낸 메시지 읽기
                    } catch (IOException e)
                    {
                        System.out.println("[#클라이언트가 접속을 끊었습니다.]");
                    } 
    
    
      }//내부run

      public void messageTo(String msg) throws IOException //특정 클라이언트에 메시지 보내기
      {
          out.write((msg+"\n").getBytes()); //[7] 실제 클라이언트에게 메시지 보내기
      }//messageTo

      public void messageAll(String msg) //접속한 모든 클라이언트에게 메시지 보내기
      {
          for(int i = 0; i < v.size(); i++) // 전체 클라이언트 (Service벡터)
          {
              //i = 0 길동, i = 1 라임, i = 2 주원

              Service serv = v.get(i);
              try
              {
                  serv.messageTo(msg);
              } catch (IOException e)
              {
                  //에러발생 => 클라이언트가 접속 끊음!(소켓은 사라졌지만, Service객체가 벡터에 존재)
                  //접속 끊긴 클라이언트를 벡터에서 삭제
                  v.remove(i--);

// e.printStackTrace();
System.out.println("[#클라이언트가 접속을 끊었습니다.]");
}
}
}//messageAll

  } //내부 클래스 end
  //===============================================

  public static void main(String[] args)
  {
      new Server();
  }

}


- ```java
  package j0509;

  import java.awt.Font;
  import java.awt.event.ActionEvent;
  import java.awt.event.ActionListener;
  import java.io.BufferedReader;
  import java.io.IOException;
  import java.io.InputStreamReader;
  import java.io.OutputStream;
  import java.net.Socket;
  import java.net.UnknownHostException;

  import javax.swing.JButton;
  import javax.swing.JFrame;
  import javax.swing.JOptionPane;
  import javax.swing.JPanel;
  import javax.swing.JScrollPane;
  import javax.swing.JTextArea;
  import javax.swing.JTextField;

  public class ChatClient extends JFrame implements ActionListener, Runnable
  {
      //프레임 Center => JTextArea (서버가 보낸 메시지를 출력)
      //프레임 South => JTextField (서버에게 보낼 메시지)

      JTextArea ta;
      JScrollPane scroll_ta;

      JTextField tf_send;
      OutputStream out;//소켓쓰기
      BufferedReader in;//소켓읽기
      JButton bt_change;

      JPanel southp, northp;

      public ChatClient()
      {
          setTitle("대화방");
          ta = new JTextArea();
          scroll_ta = new JScrollPane(ta);
          tf_send = new JTextField(15);
              tf_send.setFont(new Font("굴림체", Font.BOLD, 20));

          bt_change = new JButton("대화명 변경");
          /*
           * 최초 대화명 길동이
           * [길동이]안녕하세요
           * 
           * 에서
           * 
           * <미션>
           * 대화명변경 버튼 클릭시
           *     입력대화상자 보이고
           *     변경 대화명 입력
           *     대화명 변경
           */    


          add("Center", scroll_ta); //JScrollPane필요한 컴포넌트 : JList, JTable, JTextArea
          add("South", tf_send);

          setBounds(300,200,300,600);
          setVisible(true);
          setDefaultCloseOperation(EXIT_ON_CLOSE);
          connectProcess(); //in out 객체 생성
          new Thread(this).start(); // in객체 사용

          String nickname = JOptionPane.showInputDialog(this, "대화명");
          toServer("100|" + nickname);

          tf_send.addActionListener(this);
      }//생성자
      @Override
      public void actionPerformed(ActionEvent e)
      {
          String msg = tf_send.getText();
          toServer("200|"+msg);//"200|안녕하세요??"
          tf_send.setText("");

      }

      public void connectProcess() //서버소켓과 연결하는 작업
      {
          try
          {
              Socket s = new Socket("localhost", 3000); // [3] 서버소켓 연결

              //★4. 소켓 입출력 객체 생성
              out = s.getOutputStream();
              in = new BufferedReader(new InputStreamReader(s.getInputStream())) ;
          } catch (UnknownHostException e)
          {
              // TODO Auto-generated catch block
              e.printStackTrace();
          } catch (IOException e)
          {
              // TODO Auto-generated catch block
              e.printStackTrace();
          }
      }
      public void toServer(String msg)//서버에게 메시지 보내기
      {
          try
          {
              out.write((msg + "\n").getBytes()); //[5] 메시지 보내기 writhe
          } catch (IOException e)
          {
              e.printStackTrace();
          }
      }

      @Override
      public void run()
      {//스레드 사용이유? GUI와 상관없이 (동시에) 서버가 보내는 메시지를 대기해야 하기 때문
          try
          {
              while(true)
              {
                      String msg = in.readLine();//[8]
                      ta.append(msg + "\n");
              }
          } catch (IOException e)
          {
              e.printStackTrace();
          }


      }

      public static void main(String[] args)
      {
          new ChatClient();
      }//main



  }
  • //이건 대화명 변경
    package com.encore.j0509;
    
    import java.io.BufferedReader;
    import java.io.IOException;
    import java.io.InputStreamReader;
    import java.io.OutputStream;
    import java.net.ServerSocket;
    import java.net.Socket;
    import java.util.Vector;
    
    public class Server implements Runnable{
      //외부클래스: 1.소켓을 통한 접속서비스(접속대기)
      //          2.접속한 클라이언트를 관리(Vector통해)
    
       ServerSocket ss;
       Vector<Service>  v; //접속한 클라이언트 관리
    
       public Server() {
          System.out.println("Server Start......");
          v = new Vector<>();
         try {
            ss = new ServerSocket(3000);//★1. 서버소켓 객체생성        
            new Thread(this).start();
         } catch (IOException e) {
            e.printStackTrace();
         }
       }//외부클래스 생성자
    
       public void run() {//여러 클라이언트 접속에 대한 대기
           try {
            while(true) {
                 Socket s = ss.accept();//★2. 클라이언트 접속대기  (클라이언트 프로그램: new Socket()과 매핑)
                 //Service serv = new Service(s);
                 //v.add(serv);
                 v.add(new Service(s));
               }
        } catch (IOException e) {
            e.printStackTrace();
        }
       }//외부 run
    
       //---------------------------------------------------------------------------
          class Service extends Thread{//내부클래스: 소켓을 통한 입출력 서비스
              //※ Service객체 한개 == 클라이언트 한개!!
    
              BufferedReader in;//소켓통해 읽기
              OutputStream out;//소켓에 쓰기
    
              String clientAddr;
              String nickName;
    
              public Service(Socket s) {
    
                 try {
                    //★4 소켓 입출력 객체 생성 
                     in = new BufferedReader(new InputStreamReader(s.getInputStream()));
                     out = s.getOutputStream();
                     clientAddr = s.getInetAddress().getHostAddress();
                     start();
                } catch (IOException e) {
                    e.printStackTrace();
                }             
              }//내부클래스 생성자
    
              public void run() {//클라이언트가 보내는 여러메시지를 읽어주는 기능
    
                 try {
                    while(true) {
                        String msg =in.readLine();//★6. 클라이언트가 tf를 통해 보낸 메시지 읽기
                        //msg ==> "100|홍길동"   "200|안녕하세요"
                        //모니터링
                        System.out.println("["+clientAddr+"]>>>"+ msg);
    
                        String arr[] = msg.split("\\|");
                        //arr={"100","홍길동"}    arr={"200","안녕하세요"}
                        switch(arr[0]) {
                          case "100"://대화명 전달
                                      nickName = arr[1];
                                      break;
                          case "200"://메시지 전달
                              messageAll("["+nickName+"]▶ "+arr[1]);// [홍길동]▶ 안녕하세요
                        }
    
                     }
                } catch (IOException e) {
                    //e.printStackTrace();
                    System.out.println("[#클라이언트 접속 끊음]");
                }
    
              }//내부run
    
              public void messageTo(String msg) throws IOException {
              //특정 클라이언트에게 메시지 보내기
                  out.write(  (msg+"\n").getBytes() );//★7. 실제 클라이언트에게 메시지 보내기
              }//messageTo
    
              public void messageAll(String msg) {
              //접속한 모든 클라이언트에게 메시지 보내기
                  for(int i=0; i<v.size(); i++) {//전체 클라이언트(Service벡터)
                      //i=0길동    1라임      2주원     3유신
    
                      Service serv = v.get(i);
                      try {
                        serv.messageTo(msg);
                      } catch (IOException e) {
                          //에러발생  ----> 클라이언트 접속 끊음!!(소켓은 사라졌지만 Service객체가 벡터에존재)
                          v.remove(i--);//접속끊긴 클라이언트를 벡터에서 삭제!!
                          //e.printStackTrace();
                          System.out.println("[#클라이언트 접속 끊음]");
                      }
                  }//for
    
              }//messageAll
    
    
    }//내부클래스 end
 //---------------------------------------------------------------------------

 public static void main(String[] args) {
    new Server();
 }

}


- | 로 자르고 싶다면 \ \ | 로 잘라야 한다.






















































궁금상자

  • Runnable과 Thread 차이
    Thread클래스 상속받으면 다른 클래스 상속 불가이기에 Runnable인터페이스 구현하는것이 일반적
    Runnable인터페이스 구현하면 재사용성과 일관성 유지의 장점이 있다.
    Runnnable사용시 Thread 선언해줘야 함!

  • 내부클래스 이유?

  • 상속 extends 와 implements

    
    
    

190508_Day21 복습

<스레드>

  • 프로세스내에서 순차적으로 동작하는 문장들의 단일집합(메소드)

  • 사용이유? 하나의 응용프로그램내에서 독립적으로 동시 실행(기다리지 않는) 하는 기능이 존재

  • 구현방법) 클래스 Thread, 인터페이스 Runnable

    class MyThread1 extends Thread { public void member() { Thread.start(); //혹은 start(); Thread내부니까 } public void run() //스레드 메소드 { //동시실행할 문장들 } } class Mythread2 implements Runnable { public void run() //스레드 메소드 { //동시실행할 문장들 } public void member() { Thread t = new Thread(this); t.start(); // new Thread(this).start(); } }
  • 호출방법) run()메소드를 직접 호출하는것이 아님!

    • start()메소드에게 위임해야 함! (thread 클래스 밑에 있음)

  • 문제) 위의 두개의 run()메소드를 start()를 통해 호출하시오!

    MyThread1 m1 = new MyThread1(); //스레드객체 MyThread2 m2 = new MyThread2(); //Runnable객체 m1.start(); //됨 m2.start(); //안됨
    • 스레드 객체를 별도로 반드시 생성!

    • Thread t = new Thread(Runnable객체의 위치);

    • Thread t = new Thread (m2);

    • t.start();

    • 위의 코드를 줄여서 : new Thread(m2).start();

package j0508; class MyThread extends Thread{ public MyThread(String name) { super(name); // 이렇게 안하면 이름 출력되지 않는다. new Thread(String name); 을 호출한것 } //스레드 특징 메소드 ---> run : start()메소드를 통해 호출해야 동시 실행이 가능!! public void run() { try { for(int i=1; i<11; i++) { Thread.sleep(500);//0.5초 대기 System.out.println(getName()+" : "+ i); } } catch (InterruptedException e) { e.printStackTrace(); } }//run } public class ThreadTest2 { public static void main(String[] args) { //스레드의 기본이름 : Thread-0 Thread-1 Thread-2 //스레드에 이름 부여하기!! MyThread t1 = new MyThread("비키스레드"); MyThread t2 = new MyThread("진주스레드"); MyThread t3 = new MyThread("용진스레드"); //스레드 우선 순위 부여 (1~10) 10:가장 높고, 기본값은 5 t2.setPriority(Thread.MAX_PRIORITY); t3.setPriority(Thread.MIN_PRIORITY); t1.setPriority(Thread.NORM_PRIORITY); t1.start(); t2.start(); t3.start(); } }

    • TVContribution.java => 방송국(main)

    • Customer.java => 경쟁적인 모금자(스레드)

    • Account.java => 모금함(저금통)

    package j0508; public class TVContribution { public static void main(String[] args) //모금자 5명을 모집 { Account account = new Account(); // Customer c1 = new Customer(account); // Customer c2 = new Customer(account); // Customer c3 = new Customer(account); // Customer c4 = new Customer(account); // Customer c5 = new Customer(account); //c1부터 c5까지는 Thread객체 //1차원 배열 객체생성식 : 자료형 []배열명 = new 자료형[배열크기]; Customer[] customers = new Customer[5]; // customers = {null, null, null, null, null}; for(int i = 0; i < customers.length; i++) { customers[i] = new Customer(account); } //모금 시작 for (int i = 0; i < customers.length; i++) { // c1.start(); == customers[0].start(); customers[i].start(); // 스레드 시작 } //실행한 스레드가 종료할때까지 return 기다리자! try { for (int i = 0; i < customers.length; i++) { customers[i].join(); } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } System.out.println("총 모금액 : " + account.getTotal()); } }package j0508; public class Customer extends Thread//모금자 (스레드 - 경쟁적인) { Account account; public Customer(Account account) { this.account = account; } @Override public void run() { try { for( int i = 1; i <= 200; i++ ) { Thread.sleep(50);//0.05초 간격 account.deposit(1000); //모금 System.out.println(getName() + " : " + i + "회" ); if(account.getTotal() >= 500000) { break; } }//for } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }package j0508; public class Account // 모금함(저금통) { private int total; public synchronized void deposit(int account) { total += account; /* * LOAD total * ADD account * SAVE total * * 동기화 (Synchronized) * -메소드 동기화 * (메소드에 진입한 스레드가 있을 경우 다른 스레드들은 대기(LOCK)하게 하는 역할) * -블럭 동기화 ( 특정영역 동기화 ) * synchronized(동기화객체){} * * 예) synchronized(this) * { * total += account; * } 도 가능 */ } public int getTotal() { return total; } }package j0508; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JLabel; public class MoveThreadTest extends JFrame implements ActionListener, Runnable{ JLabel la; JButton bt_start,bt_stop; int x,y; Thread t1; boolean start;//기본값 false; public MoveThreadTest() { setTitle("진주푸푸가 움직인다고?!"); ImageIcon icon = new ImageIcon("src/image/jin.png"); bt_start = new JButton("시작"); bt_stop = new JButton("정지"); la = new JLabel(icon); //bt_start.setBounds(x, y, width, height); bt_start.setBounds(20,420, 80,30); bt_stop.setBounds(120,420, 80,30); la.setBounds(x, y, 80, 70); setLayout(null); add(bt_start); add(bt_stop); add(la); setBounds(200,200, 500,500); setVisible(true); setDefaultCloseOperation(EXIT_ON_CLOSE); bt_start.addActionListener(this); bt_stop.addActionListener(this); }//생성자 public void run() { //값 이동 // la.setLocation(5,0,56,56); try { while(true) { if(!start)break; System.out.println(x); if(x<=400) { x+=5; la.setLocation(x,0); Thread.sleep(20); }else if(y<=400) { y+=5; la.setLocation(x,y); Thread.sleep(20); } } } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } } @Override public void actionPerformed(ActionEvent e) { Object ob = e.getSource(); if(ob==bt_start) { start=true; t1 = new Thread(this); t1.start(); }else if(ob == bt_stop) { start=false; // t1.stop(); } } public static void main(String[] args) { new MoveThreadTest(); } }

 


 

  • java.net.*;

    <InetAddress>

    • IP주소를 다루기 위한 클래스 XXX.XXX.XXX.XXX XXX: 0~255

    주요메소드) byte[] getAddress() static InetAddress[] getAllByName(String host) static InetAddress getByName(String host) String getHostAddress() String getHostName() <URL> Uniform Resource Location

    http://www.gildong.co.kr:80/test/hello.jsp?name=gildong&age=13&job=student#index1

    프로토콜: 자원에 접근하기 위해 서버와 통신하는데 사용되는 통신규약(http) 호스트명: 자원을 제공하는 서버의 이름 www.gildong.co.kr 포트번호: 통신에 사용되는 서버의 포트번호 80 경로명: 접근하려는 자원이 저장된 서버상의 위치 /test/ 파일명: 접근하려는 자원의 이름 hello.jsp 쿼리(query): URL에서 '?'이후의 부분 name=gildong&age=13&job=student 참조(anchor): URL에서 #이후의 부분

    <URLConnection>

    • 어플리케이션과 URL간의 통신연결을 나타내는 클래스의 최상위 클래스

    • URLConnection을 사용해서 연결하고자 하는 자원에 접근하고 읽고 쓰기를 할 수 있다.

package j0508; import java.io.BufferedReader; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.MalformedURLException; import java.net.URL; public class URLTest { public static void main(String[] args) { String total = null; try { URL url = new URL("https://www.naver.com/index.html"); System.out.println("프로토콜 : " + url.getProtocol()); System.out.println("호스트 : " + url.getHost()); System.out.println("서비스파일 : " + url.getFile()); InputStream is = url.openStream(); //웹소스 읽기 => 화면 콘솔 출력 BufferedReader br = new BufferedReader(new InputStreamReader(is, "UTF-8")); String str; while((str = br.readLine()) != null) { total += str; } FileWriter fw = new FileWriter("C:\\Users\\Playdata\\Documents\\test.html"); fw.write(total); fw.close(); //미션) 읽어드린 웹소스를 파일(test.html)로 저장하고 // 탐색기에서 'test.html'을 더블클릭해서 해당 사이트를 접속하시오 //파일 생성 => File //폴더(디렉토리) 생성=> } catch (MalformedURLException e) { System.out.println("잘못된 주소입니다. 다시 한번 확인 해주세요"); e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }

이렇게 하면 깨지니

아래 처럼 해야 한다.

package com.encore.j0508; import java.io.BufferedReader; import java.io.FileOutputStream; import java.io.FileWriter; import java.io.IOException; import java.io.InputStream; import java.io.InputStreamReader; import java.io.OutputStreamWriter; import java.net.MalformedURLException; import java.net.URL; public class URLTest { public static void main(String[] args) { try { URL url = new URL("https://www.naver.com/index.html"); System.out.println("프로토콜: "+ url.getProtocol()); System.out.println("호스트: "+ url.getHost()); System.out.println("서비스파일명: "+ url.getFile()); InputStream is = url.openStream(); //웹소스 읽기 ----------> 화면 콘솔 출력 BufferedReader br = new BufferedReader(new InputStreamReader(is,"UTF-8") ); String str; // while( (str=br.readLine()) != null ) { // System.out.println(str); // } //미션) 읽어들인 웹소스를 파일(test.html)로 저장하고 // 탐색기에서 'test.html'을 더블클릭해서 해당 사이트를 접속하시오. //파일생성 ==> FileOutputStream, FileWriter //폴더(디렉토리)생성==> File //FileWriter fw = new FileWriter("test.html"); ---> 문자집합 설정X //new OutputStreamWriter(OuputStream out, String charsetName) FileOutputStream fos = new FileOutputStream("test.html"); OutputStreamWriter osw = new OutputStreamWriter(fos , "UTF-8"); while( (str=br.readLine()) != null ) { //fw.write(str); osw.write(str); } //fw.close(); osw.close(); System.out.println("파일(test.html)생성 성공!!"); } catch (MalformedURLException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } }//main }


190507 복습, 스레드


<데이터 읽고 쓰는 Target과 자료형의 종류!>

  1. (화면) 콘솔

    • 읽기

      • int asciiNum = System.in.read();

      • String str = br.readLine();

      • pulbic class System
        {
            pulbic static InputStream in;
            pulbic static PrintStream out;
            pulbic static PrintSream err;
        }
      • BufferedReader br;

      • BufferdReader생성자

        • BufferedReader ( Reader객체 ){}
      • br = new BufferdReader( new InputStreamReader(System.in) );

        • System.in 이 키보드 입력을 받고
        • InputStreamReader 에서 바이트스트림 => 문자 단위로 변환
        • BufferdReader 에서 변환된 문자들을 버퍼에 저장!
    • 쓰기

      • System.out.println(데이터);
      • System.out.print(데이터);
      • System.out.printf(데이터);
  2. JTextArea, JTextField

    • 읽기
      • JTextArea ta; JTextField tf;
      • ta.getText();
      • tf.getText();
    • 쓰기
      • ta.setText("문자열데이터");
      • ta.append("문자열데이터");
      • tf.setText("문자열데이터");
  3. File (==> (바이트단위) FileInputStream fis, (문자단위)FileReader fr, (바이트단위)FileOutputStream fos, (문자단위)FileWriter fw)

    • 읽기
      • int b = fis.read(바이트데이터);
      • int c = fr.read(문자데이터);
    • 쓰기
      • fos.write(바이트데이터);
      • fw.write(문자데이터);
      • fw.write(문자열데이터);

미션) Swing을 통해 SimpleNotePad를 만드시오

  • ta(JTextArea) 읽기 ===> 파일 쓰기 : 파일저장
  • 필요한 입출력 객체 FileOutputStream, FileWriter

<객체 직렬화> Serialization

  • 객체를 연속적인 데이터롤 변환하는 것(반대과정은 역직렬화라고 함)

  • 객체의 인스턴스변수들의 값을 일렬로 나열하는 것

    • 객체를 파일이나 네트워크에 전송하기 위해 바이트 형태의 데이터로 변환하는것
  • 객체를 스트림으로 파일에 저장하는 방법

  • transient키워드 : 객체 멤버변수중 직렬화 대상에 제외

    class Person
    {
        String name;
        int age;
        String job;
    }
    
    //=>> class Person [String name, int age, String job]
    • 관련 클래스) - 객체단위로 쓰고 읽자!
    • ObjectOutputStream ObjectInputStream
    • Serializable(마커 인터페이스)
package j0507;

import java.io.Serializable;

public class Person implements Serializable//객체 직렬화 하겠음! 이라는 체크를 해줘야 함. implements Serializable
{
    String name = "바보";
    int age = 13;
    transient String job = "학생"; // 직렬화 대상에서 제외 => 데이터값을 전달하지 않겠음.
}

//Person 객체를 파일에 쓸 수 있습니까? => ObjectOutputStream 사용!
package j0507;

import java.io.FileOutputStream;
import java.io.ObjectOutputStream;

public class ObjectWriteTest //객체 쓰기 테스트
{


    public static void main(String[] args) throws Exception
    {
        FileOutputStream fos = new FileOutputStream("person.ser");
        ObjectOutputStream oos = new ObjectOutputStream(fos);
        Person p = new Person();

        Person p2 = new Person();
            p2.name = "이진주";
            p2.age = 1;
            p2.job = "강아지";

            oos.writeObject(p);
            oos.writeObject(p2);

            oos.writeObject("직렬화 하이~!");
            oos.writeInt(300);    
            oos.writeBoolean(true);

            oos.close();
            fos.close();

        System.out.println("객체 쓰기 성공~!");

    }
}
package j0507;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;

public class ObjectReadTest
{

    public static void main(String[] args) throws Exception
    {
        FileInputStream fis = new FileInputStream("person.ser");
        ObjectInputStream ois = new ObjectInputStream(fis);

        Person p = (Person) ois.readObject();
        System.out.println("이름 : " + p.name);
        System.out.println("나이 : " + p.age);
        System.out.println("직업 : " + p.job);
        System.out.println("========================");

        Person p2 = (Person) ois.readObject();
        System.out.println("이름 : " + p2.name);
        System.out.println("나이 : " + p2.age);
        System.out.println("직업 : " + p2.job);
        System.out.println("========================");
        System.out.println("메세지 :" + ois.readObject());
        System.out.println("정수 :" + ois.readInt());
        System.out.println("논리 :" + ois.readBoolean());

    }

}

<스레드> Thread

  • 프로세스내에서 순차적으로 동작하는 문장들의 단일 집합.
  • 경량(light weight)의 프로세스
  • 하나의 프로세스내에 다수개의 스레드를 정의할 수 있으며 다수개의 스레드를 동시에 수행 될 수 있다.(다중스레드)
  • 자바에서는 클래스(Thread)와 인터페이스(Runnable)지원

<스레드 개념>

void a()
{
    1;
    2;
    3;
}

void b()
{
    4;
    5;
    6;
}

void c()
{
    7;
    8;
    9;
}

//===main
a();
b();
c();
//일반메소드의 경우 a()메소드의 문장을 전체 실행해야 b()메소드 실행
//일반메소드의 경우 기다림, 순차적인 실행!
//[실행결과] 1;2;3;4;5;6;7;8;9;

//만약 a,b,c()메소드가 스레드라고 한다면 기다림없이, 동시에 실행!



//[실행결과] 1;4;7;5;2;8;9;3;6;

※스레드 객체 생성

class My extends Thread
{
    //스레드 특성 메소드(오버라이딩)
    public void run()
    {
          //동시(독립) 실행코드  
    }
}




//Thread t = new Tread();
//t.start():

class My2 extends JFrame implements Runnable
{
    public void run()
    {
        //동시실행코드
    }
}

//my2 my = new My2();
//m2는 스레드 객체? X
//m2는 Runnable객체? O
//별도의 Thread객체 생성이 필요.
    //Thread t2 = new Thread(run()메소드의 위치);
    //Thread t2 = new 
  • 위에서 t를 스레드 객체라고 한다!

문제) MainView 클래스 상단(North)에 현재시간 정보를 작성하시오

Thread.sleep( );

  • package j0507;
    
    public class MyThread extends Thread
    {
    
        //스레드 특성을 갖는 메소드 (동시실행)
        @Override
        public void run()
        {
            //동시 실행할(기다리지 않는) 문장들
            try
            {
                for(int i = 1; i< 11; i++)
                {
                    //Thread.sleep(1000);
                    System.out.println("자바스레드 : " + i);
                }
            } catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    
    }//MyThread
    
  • package j0507;
    
    public class ThreadTest
    {
        public static void main(String[] args)
        {
            MyThread t = new MyThread();
    //        t.run(); //run()메소드를 직접 호출하는 일반메소드와 같은 실행을 해버림.
            t.start(); // start()메소드는 '스레드'작접 스케줄러라고 보면 된다.
        }
    }
    
궁금상자
- 왜 Thread는 Exception이 안될까? @Override때문!

190503_Day19 복습, MVC다른방법, IO


MVC Model2

전체 프로그램 제어
시각담당 분석
요청 응답 데이터 분석
View Controller

<============inputForm.setVisible(true);

=========================================

​ ==>>selectAll();

​ <=====Vector

[입력폼]입력요청 ==>> Store 저장 필요!
Person p = new Person(
tf_name.getText()
tf_age.getText()
tf_job.getText()
getText());==>> insert(Person p);
==>>selectAll()
<<==Vector
<<== JTable 갱신
DisplayTable(벡터)
<<==입력된 결과를 보여주기
메인의 JTable
mainView.setVisuable(true);
[메인뷰]수정요청 ==>> (데이터 출력된) 수정폼 필요
int row = table.getSelectedRow()
//첫행선택 : 0, 두번째 선택 1
int no = table.getValueAt(row, 0); =>> select(int no)
<== Person p
upForm.tf_name.setText(p.getName())
upForm.tf_age.setText(p.getAge())
upForm.tf_job.setText(p.getJob())
<==이전데이터를 한개 보여주기!!
upForm.setVisible(true);
[메인뷰]삭제요청==>> Store 삭제 필요!
int no = showInputDialog("삭제정보 : ")
int state = showConfirmdialog("정말삭제?")
==>>delete(int no);

IO

  • 어렵다

    • 왜? 생전보는 클래스들의 이름, 거기다가 길어..
  • 스트림!(시냇가, 파이프)이 기본!

    • 8bit(1byte)로 구성된 데이터의 흐름
  • 입출력 4대 클래스( 추상클래스 : 입출력의 특성이 되는 부모 클래스 )

    • | | byte단위 | 문자단위 | 대표메소드 |
      | ---- | ------------ | -------- | ---------- |
      | 입력 | InputStream | Reader | read() |
      | 출력 | OutputStream | Writer | write() |
      | | | | |
  • ASCIIGetBytesTest
package j0503;

public class ASCIIGetBytesTest
{

    public static void main(String[] args)
    {
        String str = "hi java Stream!!!!";
        byte []b = str.getBytes();
        for (int i = 0; i < b.length; i++)
        {
            System.out.write(b[i]);
            if(i%3==2)System.out.write('\n');
        }

    }

}
  • 출력객체들은 flush() 메도드를 갖음 ( 참조 : 입력객체들은 flush()메소드 없음)
  • flush()는 버퍼(임시저장소)가 비우는 열할(버퍼의 내용을 push하는 역할)
  • case1
    • JTable table = new JTable;
  • case2
    • DefaultTableModel dtm = new DefaultTableModel();
    • JTable table = new JTable(dtm);
  • case3
    • 나는 파일을 읽고 싶습니다.
    • FileReader fr = new FileReader( "song.txt ");
  • case4
    • 나는 파일을 읽고 싶습니다.
    • File f = new File("song.txt");
    • FileReader fr = new FileReader(f);

<경로표현방법>

  • 전체 경로(드라이브명과 중간 폴더경로 전체, 절대경로)
  • 상대 경로
  • 생략된 경로
  • 자바의 경로는 이 중 '전체경로'가 기본!
    • ImageIcon("경로");
    • ImageIcon("image/left.gif"); //이클립스 프로젝트 중 자바에서만 가능
  • 자바의 경로안의 문자는 대소문자를 구분하지 않음
//mission

package j0503;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class SimpleNotePad  extends JFrame  implements ActionListener 
{
    JTextArea ta;
    JScrollPane scroll_ta;

    JMenuBar bar;
    JMenu menu_file,menu_help;
        JMenuItem item_open;
        JMenuItem item_save;
        JMenuItem item_exit;

    JFileChooser chooser;

    public SimpleNotePad()
    {
        setTitle("자바메모장");

        chooser = new JFileChooser();

        bar = new JMenuBar();
            menu_file = new JMenu( " File " );
                item_open = new JMenuItem("열기");
                item_save = new JMenuItem("저장");
                item_exit = new JMenuItem("종료");

            menu_file = new JMenu( " File " );
            menu_help = new JMenu( " Help " );

            menu_file.add(item_open);
            menu_file.add(item_save);
            menu_file.addSeparator();//구분선 추가
            menu_file.add(item_exit);

            bar.add(menu_file);
            bar.add(menu_help);

            setJMenuBar(bar);

        ta = new JTextArea();
        scroll_ta = new JScrollPane(ta);

        add("Center", scroll_ta);

        setBounds(400, 300, 600, 600);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        item_open.addActionListener(this);
        item_save.addActionListener(this);
        item_exit.addActionListener(this);
    }//생성자


    //FROM : 파일을 읽어서 = > to : TextArea
    //채워 넣기
    public void openFile() 
    {
        chooser.showOpenDialog(this);
        String filePath = chooser.getSelectedFile().getPath();
//        System.out.println(filePath); 주소 출력 잘됨

//        FileReader fr = new FileReader(filePath);
//        FileReader fr = FileReader(address);
//        ta.setText(t);
    }


    //FROM : TextArea = > to : file에 출력
    public void saveFile() throws IOException
    {
        chooser.showSaveDialog(this);
        String copy = ta.getText();
        //FileReader fr = new FileReader("aabbcc");  (X)
        //FileReader fr = new FileReader("abc.txt"); (O)
        FileWriter fw = new FileWriter(chooser.getSelectedFile().getPath());
        //FileWriter fw = new FileWriter("c:/aa/bb/cc.txt");

        //FileWriter fw = new FileWriter(chooser.getSelectedFile());
        //FileWriter fw = new FileWriter(new File("c:/aa/bb/cc.txt"));

            fw.write(copy);

        fw.close();
    }

    @Override
    public void actionPerformed(ActionEvent e)
    {
        Object ob = e.getSource();
        if(ob == item_open)
        {
            openFile();
        }else if(ob == item_save)
        {
            try
            {
                saveFile();
            } catch (IOException e1)
            {
                // TODO Auto-generated catch block
                e1.printStackTrace();
            }
        }else if (ob == item_exit)
        {
            System.exit(0);
        }

    }
    public static void main(String[] args)
    {
        new SimpleNotePad();
    }


}

190502_Day18 MVC Model2,


public class Person {
   //속성정의
    private int no;
    private String name;
    private int age;
    private String job;

    public Person() {

    }

    public Person(int no, String name, int age, String job) {
        this.no = no;
        this.name = name;
        this.age = age;
        this.job = job;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public String getJob() {
        return job;
    }

    public void setJob(String job) {
        this.job = job;
    }

    @Override
    public String toString() {
        return "Person [no=" + no + ", name=" + name + ", age=" + age + ", job=" + job + "]";
    }

//  @Override
//  public String toString() {      
//      return no+": ["+name+","+age+","+job+"]";
//  }



}//class Person

import java.util.Vector;

public class Model {

    public Vector<Person> personv;//데이터 저장소
    private int no;//입력될 Person에 유일한 번호를 부여

    public Model() {
        personv = new Vector<Person>();
    }


    //---------- Vector personv를 기준으로 추가,삭제,수정,조회 작업 ------------------------

    public void insert(Person p){
        no++;
        p.setNo(no);
        personv.add(p);
    } 
    public void update(Person newp){
        //전체 벡터 조회 (일치하는 번호의 Person정보 얻기)
        for(int i=0; i<personv.size(); i++) {
          Person oldp = personv.get(i);
           if(oldp.getNo() ==  newp.getNo()) {//일치하는 번호를 찾았다면
             //수정 작업
               oldp.setAge( newp.getAge());
               oldp.setJob( newp.getJob());
           }

        }   
    } //update

    public void delete(int no){} 
    public Person select(int no){//용도: 수정폼에 출력
      //전체 벡터 조회 (일치하는 번호의 Person정보 얻기)
      for(int i=0; i<personv.size(); i++) {
          Person oldp = personv.get(i);
         if(oldp.getNo() ==  no) {//일치하는 번호를 찾았다면
             return oldp;
         }

      }
      return null;  
    }    
    public Vector<Person> selectAll( ){//용도: JTable출력
      return personv;   
    } 
}
  • View
import java.util.Vector;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

import com.encore.person.model.Person;

public class MainView extends JFrame{

   DefaultTableModel dtm;
   public JTable table;
   //public 명시이유? 다른 패키지에 있는 클래스(컨트롤러)에서 사용하기 때문.
   JScrollPane scroll_table;

   public JButton bt_insert, bt_del, bt_update, bt_exit;

   JPanel southp;

   public MainView() {
      setTitle("MainView");

      Object [][]rowData = new Object[0][4];
      //행 크기 0인 이유?  시작을(앞으로 JTable에 추가될 행을) 0인덱스(첫행)부터 하기 위해서

      String []columTitle = {"번호","이름","나이","직업"};

      dtm = new DefaultTableModel(rowData,columTitle);
      //dtm생성이유? dtm내의 addRow() , removeRow() 사용하기 위해서!!

      table = new JTable(dtm);
      scroll_table = new JScrollPane(table);
      //scroll_table생성이유?  1. 테이블(사이즈)을 벗어나는 데이터를 보기 위해서 (스크롤바가 필요)!!
      //                     2. 테이블의 컬럼명을 보여줄 수 있음.

      bt_insert = new JButton("입력");
      bt_update = new JButton("수정");
      bt_del = new JButton("삭제");
      bt_exit = new JButton("종료");

      southp = new JPanel();
        southp.add(bt_insert);
        southp.add(bt_update);
        southp.add(bt_del);
        southp.add(bt_exit);

      add("Center", scroll_table);
      add("South", southp);

      setBounds(300,200,350,300);
      setVisible(true);
      setDefaultCloseOperation(EXIT_ON_CLOSE);


   }//생성자


   //MainView - JTable이 원하는 타입1 : Object []rowData1= {1, "나길동", 13, "학생"};
            //- JTable이 원하는 타입2 : Vector<String> rowData2 = new Vector<>();
                                            //   rowData2.add("2");        //  0
                                            //   rowData2.add("너주원");   // 1
                                            //   rowData2.add("15");       //  2
                                            //   rowData2.add("학생");    //  3

   // rowData2.get(0)  --->  "2"
   // rowData2.get(1)  --->  "너주원"
   // rowData2.get(2)  --->  "15"
   // rowData2.get(3)  --->  "학생"
   //===========================================================================

   //Controller를 통해 전달받은 데이터 타입
   //  - Vector<Person> personv = new Vector<>();
   // personv.get(0)  ---> Person p1 = new Person(1,"홍길동",13,"학생");                   
   // personv.get(1)  ---> Person p2 = new Person(2,"너주원",15,"학생");                   
   // personv.get(2)  ---> Person p3 = new Person(3,"길라임",16,"학생");                   
   // personv.get(3)  ---> Person p4 = new Person(4,"김유신",17,"학생");                   


   //벡터안에 저장된 Person정보를 JTable에 출력하는 기능.
   public void displayTable(Vector<Person> personv) {
        dtm.setRowCount(0);//새로 addRow되는 행 데이터를 0인덱스 부터 출력하겠음!!
                           //이전에 JTable에 출력된 내용을 clear하는 역할!!

        for(int i=0; i<personv.size(); i++) {//벡터의 인덱스 수 == 사람의 수
            Person p = personv.get(i);
            Object []rowData= {p.getNo(), p.getName(), p.getAge(), p.getJob()};
            dtm.addRow(rowData);
        }
   }//displayTable


//   public void displayTable() {
//     Object []rowData1= {1, "나길동", 13, "학생"};
//     //인덱스                        0     1     2    3
//     
//     Vector<Object> rowData2 = new Vector<>();
//     //인덱스
//     rowData2.add(2);        //  0
//     rowData2.add("너주원");   // 1
//     rowData2.add(15);       //  2
//     rowData2.add("학생");    //  3
//     
//     //dtm.addRow(1차원배열);
//     dtm.addRow(rowData1);
//     //dtm.addRow(벡터);
//     dtm.addRow(rowData2);
//   }

}//MainView

package com.encore.person.view;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class UpForm extends JFrame{
   JLabel la_name, la_age, la_job;
   public JTextField tf_name, tf_age, tf_job;

   public JButton bt_submit, bt_cancel; 

   public int upNo;

   public UpForm() {
      setTitle("수정폼");//텍스트 변경

      la_name = new JLabel("이름");
      la_age = new JLabel("나이");
      la_job = new JLabel("직업");

      tf_name = new JTextField();
       tf_name.setEnabled(false);
       //수정폼에 tf_name을 비활성화한 이유?  벡터에 저장되어있는 Person내의 이름은 변경하지 않겠다!!
      tf_age  = new JTextField();
      tf_job  = new JTextField();

      bt_submit = new JButton("수정");//텍스트 변경
      bt_cancel = new JButton("취소");

      //la_name.setBounds(x, y, width, height);
      la_name.setBounds(30,30, 30,30);
      la_age.setBounds(30,80, 30,30);
      la_job.setBounds(30,130, 30,30);

      tf_name.setBounds(70,30, 120,30);
      tf_age.setBounds(70,80, 120,30);
      tf_job.setBounds(70,130, 120,30);

      bt_submit.setBounds(40,180, 70,30);
      bt_cancel.setBounds(120,180, 70,30);

      setLayout(null);
       add(la_name);
       add(la_age);
       add(la_job);
       add(tf_name);
       add(tf_age);
       add(tf_job);
       add(bt_submit);
       add(bt_cancel);

      setBounds(500,200,240,280);
      //setVisible(true);
      //setDefaultCloseOperation(EXIT_ON_CLOSE);
   }//생성자


}//UpForm
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JTextField;

public class InputForm extends JFrame{
   JLabel la_name, la_age, la_job;
   public JTextField tf_name, tf_age, tf_job;

   public JButton bt_submit, bt_cancel; 

   public InputForm() {
      setTitle("입력폼");

      la_name = new JLabel("이름");
      la_age = new JLabel("나이");
      la_job = new JLabel("직업");

      tf_name = new JTextField();
      tf_age  = new JTextField();
      tf_job  = new JTextField();

      bt_submit = new JButton("입력");
      bt_cancel = new JButton("취소");

      //la_name.setBounds(x, y, width, height);
      //프레임에 붙는 컴포넌트에 시작좌표(location)와 사이즈를 설정하는 이유? NullLayout인 컨테이너에 부착시킬 때 필요.
      la_name.setBounds(30,30, 30,30);
      la_age.setBounds(30,80, 30,30);
      la_job.setBounds(30,130, 30,30);

      tf_name.setBounds(70,30, 120,30);
      tf_age.setBounds(70,80, 120,30);
      tf_job.setBounds(70,130, 120,30);

      bt_submit.setBounds(40,180, 70,30);
      bt_cancel.setBounds(120,180, 70,30);

      setLayout(null);
       add(la_name);
       add(la_age);
       add(la_job);
       add(tf_name);
       add(tf_age);
       add(tf_job);
       add(bt_submit);
       add(bt_cancel);

      setBounds(500,200,240,280);
      //setVisible(true);
      //setDefaultCloseOperation(EXIT_ON_CLOSE); //전체 '자바응용프로그램 종료' 의미
   }//생성자


}//InputForm
  • Control
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.Vector;

import com.encore.person.model.Model;
import com.encore.person.model.Person;
import com.encore.person.view.InputForm;
import com.encore.person.view.MainView;
import com.encore.person.view.UpForm;

public class Controller implements ActionListener{
    //ActionListener상속한 이유? 뷰내의 버튼의 눌림(액션)을 체크하기 위해서!!

    //전체뷰등록
    MainView mainView;
    InputForm form;
    UpForm  upForm;

    //모델 등록 (Vector<Person>등록)
    Model m;

    public Controller() {
        mainView = new MainView();
        form = new InputForm();
        upForm = new UpForm();

        m = new Model();

        eventUp();
    }//생성자

    private void eventUp() {//이벤트 소스 등록
       /////////// MainView이벤트 소스  ////////////////
       mainView.bt_insert.addActionListener(this);
       mainView.bt_update.addActionListener(this);
       mainView.bt_del.addActionListener(this);
       mainView.bt_exit.addActionListener(this);

       /////////// InputForm이벤트 소스  ////////////////
       form.bt_submit.addActionListener(this);
       form.bt_cancel.addActionListener(this);   
       form.addWindowListener(new WindowAdapter() {
           @Override
        public void windowClosing(WindowEvent e) {
             //입력폼  ----> 메인뷰  이동
               form.setVisible(false);
               mainView.setVisible(true);
        }
       });

       /////////// UpForm이벤트 소스  ////////////////   
       upForm.bt_submit.addActionListener(this);
       upForm.bt_cancel.addActionListener(this);
       upForm.addWindowListener(new WindowAdapter() {
           @Override
         public void windowClosing(WindowEvent e) {
             //수정폼  ----> 메인뷰  이동
               upForm.setVisible(false);
               mainView.setVisible(true);
         }
       });
    }//eventUp


    @Override
    public void actionPerformed(ActionEvent e) {//기능정의 메소드: 이벤트 핸들러
       Object ob = e.getSource();
       if(ob==mainView.bt_insert) {//[1]메인뷰: 입력요청 (데이터 입력을 위한 폼이동)
           mainView.setVisible(false);
           form.setVisible(true);
       }
       else if(ob==mainView.bt_update) {//[1]메인뷰: 수정요청  (데이터 수정을 위한 폼이동)
           int row = mainView.table.getSelectedRow();
           int no = Integer.parseInt(mainView.table.getValueAt(row, 0).toString());
           //JTable에서 선택된 행의 번호 얻기

           Person oldp = m.select(no);//no를 조건으로 벡터에 일치하는 Person 얻어오기

           //oldp : 벡터에 이미 저장되어있는 Person
           // ----> 수정폼(TextField)에 출력
           upForm.tf_name.setText(oldp.getName());
           upForm.tf_age.setText(oldp.getAge()+"");
           upForm.tf_job.setText(oldp.getJob());

           //나중에 수정을 위해 UpForm 멤버 upNo에 번호 저장
           upForm.upNo = oldp.getNo();


           mainView.setVisible(false);
           upForm.setVisible(true);
       }
       else if(ob==mainView.bt_del) {//[1]메인뷰: 삭제요청 

       }
       else if(ob==mainView.bt_exit) {//[1]메인뷰: 프로그램 종료요청

       }
       else if(ob==form.bt_submit) {
           //[1]입력폼뷰: 입력요청 (폼에 입력된 데이터를 Vector에 저장)

           String name = form.tf_name.getText();
           int age = Integer.parseInt(form.tf_age.getText());
           String job = form.tf_job.getText();

           Person p = new Person(0, name, age, job);

           m.insert(p);

           //추가된 내용을 JTable에 반영
           Vector<Person> personv = m.selectAll();
           mainView.displayTable(personv);

           //메인뷰로 이동
           form.setVisible(false);
           mainView.setVisible(true);
       }
       else if(ob==upForm.bt_submit) {
           //[1]수정폼뷰: 수정요청 (폼에 입력된 데이터를 정보로 Vector에 값을 변경)


           int age = Integer.parseInt(upForm.tf_age.getText());
           String job = upForm.tf_job.getText();

           //Person p = new Person(0, null, age, job);
           Person p = new Person();
                p.setAge(age);
                p.setJob(job);
                p.setNo(upForm.upNo);


           m.update(p);

           //수정된 내용을 JTable에 반영
           Vector<Person> personv = m.selectAll();
           mainView.displayTable(personv);

           //메인뷰로 이동
           upForm.setVisible(false);
           mainView.setVisible(true);
       }


    }//actionPerformed



    public static void main(String[] args) {
        new Controller();
    }

}

190430_Day17 숫자야구게임,

<이벤트처리>

  • 사건(버튼눌림, 마우스 움직임, 체크하기, 텍스트쓰기 등) 살생시 기능( 실행문장들 기술) 추가
    1. 이벤트 소스 : bt_new, bt_clear, bt_dap, bt_exit;tf
      • 자료형
      • 사건 : 버튼눌림과 텍스트필드에 엔터가 입력
      • Action이벤트~!
    2. implements ActionListener
      • actionPerformed 구현
    3. 연결자 등록
      • 버튼명.addActionListener(this);
      • 텍스트명.addActionListener(this);
package j0430;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class BaseBallGame extends JFrame implements ActionListener
{
    JTextArea ta;
    JButton bt_new, bt_clear, bt_dap, bt_exit;
    JLabel la;
    JTextField tf;
    // JScrollPane: 범위를 벗어나는 데이터를 표현(JTextArea, JList, JTable)
    JScrollPane scroll_ta;

    JPanel panel;

    int []com, user; // 이러면 user도 배열이래... 대신 com[]은 문제발생 []가 앞에 있을때만
    Random r;

    public BaseBallGame()
    {
        setTitle("숫자야구게임");

        r = new Random();
        com = new int[3]; // 배열객체생성식! 개속 바귈거라서 고정된 값이면 그냥 {}; 이렇게 했음
        user = new int[3]; // 사용자가 입력한 데이터 초기화
        // [0][1][2]에 {0,0,0}으로 들어감

        createNum();

        ta = new JTextArea();
        // scroll_ta = new JScrollPane(스크롤바를 필요로 하는 컴포넌트);
        scroll_ta = new JScrollPane(ta);

        bt_new = new JButton("새게임");
        bt_clear = new JButton("지우기");
        bt_dap = new JButton("정답");
        bt_exit = new JButton("종료");

        la = new JLabel("입력:");
        tf = new JTextField();

        // ta.setBounds(10, 10, 350, 300);
        scroll_ta.setBounds(10, 10, 350, 300);
        bt_new.setBounds(380, 60, 90, 40);
        bt_clear.setBounds(380, 120, 90, 40);
        bt_dap.setBounds(380, 180, 90, 40);
        bt_exit.setBounds(380, 240, 90, 40);

        la.setBounds(10, 320, 30, 30);
        tf.setBounds(50, 320, 310, 30);

        panel = new JPanel();
        panel.setLayout(null);
        panel.setBackground(Color.blue);
        panel.add(scroll_ta);// (ta);
        panel.add(bt_new);
        panel.add(bt_clear);
        panel.add(bt_dap);
        panel.add(bt_exit);
        panel.add(la);
        panel.add(tf);

        add(panel);
        setBounds(300, 300, 500, 410);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        eventUp();// 이벤트소스 등록(이벤트소스와 이벤트처리부 연결)!!
    }// 생성자

    private void eventUp()
    {
        // 버튼
        bt_new.addActionListener(this); // 201호
        bt_clear.addActionListener(this); // 202호
        bt_dap.addActionListener(this); // 203호
        bt_exit.addActionListener(this);

        // 텍스트필드
        tf.addActionListener(this); // 205호
    }

    @Override
   public void actionPerformed(ActionEvent e) // EventHandler(이벤트처리부) - 기능정의
   {
       //가장 빈번한 이벤트 발생 컴포넌트를 가장 상단에 위치 하는것이 좋다.
       Object ob = e.getSource(); // 이벤트소스의 주소 얻기

       if( ob == tf) // 텍스트 필드에 enter 입력시 사용자가 입력한 String과 com배열의 값을 비교해서 화면(TextArea)에 결과 출력
       {
           String str = tf.getText(); //"369" => { 3, 6, 9 } 변환한다면 비교용이!!
           int su = Integer.parseInt(str);
//         su/100; (su%100)/10; ((su%100)%10)
//         user[0] = su/100; 이렇게 해도 되는데 문제는 숫자 아닌 문자열들이 왔을때 문제가 발생할수도!

           //Stirng str = "369"라면 인덱스를 가지고 있다 012로!
//         user[0] = str.charAt(0) - 48; //캐릭터와 인트는 호환이 되지만 아스키 코드값으로 들어가서 -48
//         user[1] = str.charAt(1) - 48;
//         user[2] = str.charAt(2) - 48;
           for (int i = 0; i < com.length; i++)
        {
            user[i] = str.charAt(i)-48;
        }
           // com배열과 비교할 수 있는 대등한 int[]user 배열 값이 생성!

           int strike = 0,ball = 0;
           // 비교 
           for(int i = 0; i < com.length; i++) // com배열 인덱스
           {
               for(int j = 0; j < com.length; j++) // user배열 인덱스
               {
                   //같은 수(값)가 존재한다면 =>> 스트라이크 또는 볼 후보!
                   if( com[i] == user[j] ) // 같은 수 발견
                   {
                    if( i == j ) // 같은 자리수 인지
                    {
                        strike++; // 같은 수 같은 자리
                    }
                    else
                    {
                        ball++; //같은 수 다른 자리
                    }
                   }
               }
           }
           if(strike == 3)
           {
               ta.append("축하합니다  정답을 맞추셨습니다.");
           }else 
           {
               ta.append(str + "은 " + strike + "스트라이크, " + ball + "볼\n");
           }

           tf.setText("");

       }
       else if( ob == bt_new)
       {
           createNum();
           ta.setText("");
       }
       else if( ob == bt_dap ) //정답버튼 클릭시 com이라는 배열값 ta에 출력
       {
//         ta.setText(t); //는 기존거 지우고 덮어쓰기
           ta.append("정답은~♥ " + com[0] + " " +  com[1] + " " +  com[2] + " 이었습니다.\n" );//기존거 유지한 상태에서 추가, append는 String받아옴
       }
       else if( ob == bt_clear) //지우기버튼 클릭시 텍스트 지우기
       {
           ta.setText("");
           tf.setText("");
       }
       else if( ob == bt_exit) //종료버튼 클릭시
       {
           System.exit(0);
       }
   }//actionPerformed


    public void createNum()
    {
        for(int i = 0; i <com.length; i++ ) // com배열 인덱스 표현
        {
            com[i] = r.nextInt(10); // 0~9
            for (int j = i - 1; j >= 0; j--)
            {
                if( com[i] == com[j] )//중복된 데이터가 발견 된다면
                {
                    i--;
                    break;
                }
            }
        }
    }

    public static void main(String[] args)
    {
        new BaseBallGame();
    }



}

마우스모션

package j0430;

import java.awt.Color;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;

import javax.swing.JFrame;
import javax.swing.JLabel;

public class MouseMotionTest extends JFrame implements MouseMotionListener
{
    JLabel green, red;

    public MouseMotionTest()
    {
        setTitle("마우스모션테스트");

        green = new JLabel("MOVE");
            green.setBackground(Color.GREEN); //라벨은 바탕색 투명이 default
            green.setOpaque(true); //불투명
        red = new JLabel("DRAG");
            red.setBackground(Color.RED);
            red.setOpaque(true);

            //green.setLocation(30,30);
            //green.setSize(80,30);

        green.setBounds(30, 30, 80, 30); // x, y좌표 가로,세로 길이
        red.setBounds(30, 80, 80, 30); // x, y좌표 가로,세로 길이

        setLayout(null);
        add(green);
        add(red);

        setBounds(300,200,600,600);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        addMouseMotionListener(this); // 프레임 위에서 마우스 움직임 관찰!
    }//생성자

    @Override
    public void mouseDragged(MouseEvent e) //마우스의 왼쪽 클릭한 상태에서 이동
    {
        System.out.println("mouseDragged");
        int x = e.getX();
        int y = e.getY();

        red.setLocation(x,y);

    }

    @Override
    public void mouseMoved(MouseEvent e) //마우스 단순 이동
    {
        System.out.println("mouseMoved");
        int x = e.getX() + -30;
        int y = e.getY() + -30;

        green.setLocation( x, y );
    }

    public static void main(String[] args)
    {
        new MouseMotionTest();
    }

}

숫자야구 개선!

package j0430;

import java.awt.Color;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

public class BaseBallGame3 extends JFrame implements ActionListener
{
    JTextArea ta;
    JButton bt_new, bt_clear, bt_dap, bt_exit;
    JLabel la;
    JTextField tf;
    // JScrollPane: 범위를 벗어나는 데이터를 표현(JTextArea, JList, JTable)
    JScrollPane scroll_ta;

    JPanel panel;

    int []com, user; // 이러면 user도 배열이래... 대신 com[]은 문제발생 []가 앞에 있을때만
    Random r;

    public BaseBallGame3()
    {
        setTitle("숫자야구게임");

        r = new Random();
        com = new int[3]; // 배열객체생성식! 개속 바귈거라서 고정된 값이면 그냥 {}; 이렇게 했음
        user = new int[3]; // 사용자가 입력한 데이터 초기화
        // [0][1][2]에 {0,0,0}으로 들어감

        createNum();

        ta = new JTextArea();
        // scroll_ta = new JScrollPane(스크롤바를 필요로 하는 컴포넌트);
        scroll_ta = new JScrollPane(ta);

        bt_new = new JButton("새게임");
        bt_clear = new JButton("지우기");
        bt_dap = new JButton("정답");
        bt_exit = new JButton("종료");

        la = new JLabel("입력:");
        tf = new JTextField();

        // ta.setBounds(10, 10, 350, 300);
        scroll_ta.setBounds(10, 10, 350, 300);
        bt_new.setBounds(380, 60, 90, 40);
        bt_clear.setBounds(380, 120, 90, 40);
        bt_dap.setBounds(380, 180, 90, 40);
        bt_exit.setBounds(380, 240, 90, 40);

        la.setBounds(10, 320, 30, 30);
        tf.setBounds(50, 320, 310, 30);

        panel = new JPanel();
        panel.setLayout(null);
        panel.setBackground(Color.blue);
        panel.add(scroll_ta);// (ta);
        panel.add(bt_new);
        panel.add(bt_clear);
        panel.add(bt_dap);
        panel.add(bt_exit);
        panel.add(la);
        panel.add(tf);

        add(panel);
        setBounds(300, 300, 500, 410);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        eventUp();// 이벤트소스 등록(이벤트소스와 이벤트처리부 연결)!!
    }// 생성자

    private void eventUp()
    {
        // 버튼
        bt_new.addActionListener(this); // 201호
        bt_clear.addActionListener(this); // 202호
        bt_dap.addActionListener(this); // 203호
        bt_exit.addActionListener(this);

        // 텍스트필드
        tf.addActionListener(this); // 205호
    }

    @Override
   public void actionPerformed(ActionEvent e) // EventHandler(이벤트처리부) - 기능정의
   {
       //가장 빈번한 이벤트 발생 컴포넌트를 가장 상단에 위치 하는것이 좋다.
       Object ob = e.getSource(); // 이벤트소스의 주소 얻기

       if( ob == tf) // 텍스트 필드에 enter 입력시 사용자가 입력한 String과 com배열의 값을 비교해서 화면(TextArea)에 결과 출력
       {
           String str = tf.getText(); //"369" => { 3, 6, 9 } 변환한다면 비교용이!!
           int su = Integer.parseInt(str);
//         su/100; (su%100)/10; ((su%100)%10)
//         user[0] = su/100; 이렇게 해도 되는데 문제는 숫자 아닌 문자열들이 왔을때 문제가 발생할수도!

           //Stirng str = "369"라면 인덱스를 가지고 있다 012로!
//         user[0] = str.charAt(0) - 48; //캐릭터와 인트는 호환이 되지만 아스키 코드값으로 들어가서 -48
//         user[1] = str.charAt(1) - 48;
//         user[2] = str.charAt(2) - 48;
           for (int i = 0; i < com.length; i++)
        {
            user[i] = str.charAt(i)-48;
        }
           // com배열과 비교할 수 있는 대등한 int[]user 배열 값이 생성!

           int strike = 0,ball = 0;
           // 비교 
           for(int i = 0; i < com.length; i++) // com배열 인덱스
           {
               for(int j = 0; j < com.length; j++) // user배열 인덱스
               {
                   //같은 수(값)가 존재한다면 =>> 스트라이크 또는 볼 후보!
                   if( com[i] == user[j] ) // 같은 수 발견
                   {
                    if( i == j ) // 같은 자리수 인지
                    {
                        strike++; // 같은 수 같은 자리
                    }
                    else
                    {
                        ball++; //같은 수 다른 자리
                    }
                   }
               }
           }
           if(strike == 3)
           {
               ta.append("축하합니다  정답을 맞추셨습니다.");
           }else 
           {
               ta.append(str + "은 " + strike + "스트라이크, " + ball + "볼\n");
           }

           tf.setText("");

       }
       else if( ob == bt_new)
       {
           createNum();
           ta.setText("");
       }
       else if( ob == bt_dap ) //정답버튼 클릭시 com이라는 배열값 ta에 출력
       {
//         ta.setText(t); //는 기존거 지우고 덮어쓰기
           ta.append("정답은~♥ " + com[0] + " " +  com[1] + " " +  com[2] + " 이었습니다.\n" );//기존거 유지한 상태에서 추가, append는 String받아옴
       }
       else if( ob == bt_clear) //지우기버튼 클릭시 텍스트 지우기
       {
           ta.setText("");
           tf.setText("");
       }
       else if( ob == bt_exit) //종료버튼 클릭시
       {
           System.exit(0);
       }
   }//actionPerformed


    public void createNum()
    {
        for(int i = 0; i <com.length; i++ ) // com배열 인덱스 표현
        {
            com[i] = r.nextInt(10); // 0~9
            for (int j = i - 1; j >= 0; j--)
            {
                if( com[i] == com[j] )//중복된 데이터가 발견 된다면
                {
                    i--;
                    break;
                }
            }
        }
    }

    public static void main(String[] args)
    {
        new BaseBallGame3();
    }



}
package com.encore.j0430;

import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;


/*
<이벤트 처리> - 사건(버튼눌림,마우스움직임,체크하기,텍스트쓰기등) 발생시 기능(실행문장들 기술)추가
1. 이벤트 소스:  bt_new, bt_clear, bt_dap, bt_exit, tf
              ---------------------------------- ---
                    JButton                      JTextField
                   사건:      버튼눌림                                     텍스트필드에 엔터가 입력   -----> Action이벤트!!

2. implements ActionListener
    ---> actionPerformed구현

3. 연결자 등록
    버튼명.addActionListener(this);
    텍스트명.addActionListener(this);
 */

public class BaseBallGame2 extends JFrame implements ActionListener{
   JTextArea ta;
   JButton bt_new, bt_clear, bt_dap, bt_exit, bt_hint;
   JLabel la;
   JTextField tf;
   //JScrollPane: 범위를 벗어나는 데이터를 표현(JTextArea, JList, JTable)
   JScrollPane scroll_ta;

   JPanel panel;  

   int []com;
   int []user;
   Random r;
   int count;

   JFrame f;
   boolean start;//게임 시작 상태 표현

   public BaseBallGame2() {
     setTitle("숫자야구게임");

     f = this;

     com= new int[3]; //배열객체생성식!!
     user= new int[3]; //사용자가 입력한 데이터로 초기화
              //{0,0,0}

     r = new Random();

     createNum();

     ta = new JTextArea();
       ta.setFont(new Font("굴림체", Font.BOLD , 17));
       ta.setLineWrap(true);
       //TextArea에 자동 줄바꿈(가로사이즈를 벗어나는 텍스트 발견시)
       ta.setEditable(false);
       //ta.setEnabled(false);

     //scroll_ta = new JScrollPane(스크롤바를 필요로 하는 컴포넌트);
     scroll_ta = new JScrollPane(ta);

     bt_new = new JButton("새게임");
     bt_clear = new JButton("지우기");
     bt_dap = new JButton("정답");
     bt_exit = new JButton("종료");
     bt_hint = new JButton("힌트");

     la = new JLabel("입력:");
     tf = new JTextField();

     //ta.setBounds(10, 10, 350, 300);
     scroll_ta.setBounds(10, 10, 350, 300);

     bt_new.setBounds(380,40,90,40);
     bt_clear.setBounds(380,100,90,40);
     bt_dap.setBounds(380,160,90,40);    
     bt_hint.setBounds(380,220,90,40);
     bt_exit.setBounds(380,280,90,40);

     la.setBounds(10, 320, 30,30);
     tf.setBounds(50, 320, 310,30);

     panel = new JPanel();
      panel.setLayout(null);
      panel.setBackground(Color.ORANGE);
      panel.add(scroll_ta);//(ta);
      panel.add(bt_new);
      panel.add(bt_clear);
      panel.add(bt_dap);
      panel.add(bt_hint);
      panel.add(bt_exit);
      panel.add(la);
      panel.add(tf);

     add(panel);
     setBounds(300,300, 500,410);
     setVisible(true);
     setDefaultCloseOperation(EXIT_ON_CLOSE);

     setResizable(false);//프레임에 대한 사이즈 변경 불가!!

     //특정 컴포넌트에 포커스 이동
     tf.requestFocus();

     endGame();//텍스트필드, 정답버튼, 힌트버튼 비활성화

     ruleDescription();

     eventUp();//이벤트소스 등록(이벤트소스와 이벤트처리부 연결)!!
   }//생성자

   private void eventUp() {
     //버튼
     bt_new.addActionListener(this);  //201호
     bt_clear.addActionListener(this); //202호 
     bt_dap.addActionListener(this);   //203호
     bt_exit.addActionListener(this);  //204호
     bt_hint.addActionListener(this);  //206호

     //텍스트필드
     tf.addActionListener(this);  //205호


     tf.addMouseListener(new MouseAdapter() {
         @Override
        public void mousePressed(MouseEvent e) {
            //JOptionPane.showMessageDialog(f, "게임시작을 위해 [새게임]버튼을 클릭!!");
           if(!start)//start==false)
             showMsg("게임시작을 위해 [새게임]버튼을 클릭!!");  
        }
      });
     /*
      class BaseBallGame2 extends JFrame{//외부클래스 
         new MouseAdapter()
         {//익명의 내부클래스 시작      

           this  --->  JFrame X 
           this  --->  MouseAdapter O 

         }//익명의 내부클래스 끝
      }
       ===========================================================
       class My  extends MouseAdapter{
                 ---------------------
                      위의 new 다음 오는 자료형이 클래스면 extends, 인터페이스면 implements
       }

       ==> 위의 코드는 My라는 이름의 클래스명이 없으므로 익명(Anonymous)이라함.

     */




   }//eventUp

   @Override
   public void actionPerformed(ActionEvent e) {//EventHandler(이벤트처리부) - 기능정의
      //가장 빈번한 이벤트발생 컴포넌트를 가장 위에 위치.

      Object ob =  e.getSource();//이벤트소스의 주소 얻기.
      if(ob == tf) {//텍스트 필드에 enter 입력시
         //사용자가 입력한 String과 com배열의 값을 비교하여 화면(TextArea)에 결과 출력.

        String str = tf.getText();//"369" ---> {3,6,9} 변환한다면 비교용이!!

        //str의 유효성 검사!!(세자리 숫자)
        if(!str.matches("[\\d]{3}")) {//세자리 숫자가 아니라면
            showMsg("세자리숫자만 입력!!");
            tf.setText("");
            return;
        }


        /*
        int su = Integer.parseInt(str);//"369" ---> 369
        user[0]=su/100;  // 369/100 ---> 3
        user[1]=(su%100)/10;  // (369%100)/10 ---> 69/10 ---> 6
        user[2]=(su%100)%10;  // (369%100)%10 ---> 69%10 ---> 9
        */

        //String str="369";
        //     인덱스    012
        /*
        user[0]=str.charAt(0)-48; //user[0] = '3'-48  = 51-48 ?
        user[1]=str.charAt(1)-48;
        user[2]=str.charAt(2)-48;
        */
       for(int i=0; i<com.length; i++) {
         user[i]=str.charAt(i)-48;
       }

       if(duplicateNum()) {
            showMsg("중복된 숫자사용금지!!");
            tf.setText("");
            return;
        }


        count++; 


       //==> com배열과 비교할 수 있는 대등한 int[]user 배열 값이 생성


       int strike=0,ball=0;
       //비교
       for(int i=0; i<com.length; i++) {//com배열 인덱스          [0]   [1]   [2]
         for(int j=0; j<user.length; j++) {//user배열 인덱스  [0]   [1]   [2] 
            //같은 수(값)가 존재한다면 ==> 스트라이크 또는 볼 후보!!
             if(com[i] == user[j]) {//같은 수 발견!!
                 if(i==j) {//같은 자릿수(백,십,일) 라면 
                    strike++;//같은 수, 같은 자리 
                 }else {
                    ball++; //같은 수, 다른 자리
                 }
             }
         }//안쪽for
       }//바깥for

        //9번의 비교가 끝난후 결과 출력!!

       if(strike==3) {
        ta.append("♥축하합니다♥ 정답[" + str +"]을 맞추셨습니다^^*\n");
        endGame();
       }else {
        ta.append(count+": "+str+" ▶ " + strike +"Strike "+ ball+"Ball\n");
       }

        tf.setText("");

      }else if(ob == bt_new) {//'새게임'버튼 클릭시
          startGame();
      }else if(ob == bt_dap) {//'정답'버튼 클릭시
         //com배열의 값을 ta에 출력
         ta.append("▣ 정답은 ["+com[0]+com[1]+com[2]+"]입니다.\n" ); 
         endGame();
      }else if(ob == bt_clear) {//'지우기'버튼 클릭시
         //텍스트 지우기
          ta.setText("");
          tf.setText("");
      }else if(ob == bt_hint) {

          JOptionPane.showMessageDialog(this, "힌트["+ com[r.nextInt(3)]  +"]");
          bt_hint.setEnabled(false);
      }else if(ob == bt_exit) {//'종료'버튼 클릭시
         //전체프로그램종료
          System.exit(0);
      } 

   }//actionPerformed

   public void createNum() {
     for(int i=0; i<com.length; i++) {//com배열 인덱스 표현
         com[i]= r.nextInt(10);//0~9
         for(int j=i-1;  j>=0; j--) {//중복검사: i=1 --> 0번지비교
                                     //        i=2 --> 1번지, 0번지 비교
          if(com[i] == com[j]) {//중복된 데이터가 발견된다면
               i--;
               break;
          }
 }//안쪽for 
      }//바깥쪽for   
   }//번호생성

   public boolean duplicateNum() {//중복숫자 발견시 true리턴
      if(user[0]== user[1] ||
         user[0]== user[2] ||
         user[1]== user[2]) {
          return true;
      }
      return false; 
   }//duplicateNum


   public void ruleDescription() {//게임 룰 설명
     ta.append("\n\n\t<숫자야구게임>");  
     ta.append("\n1. 게임시작을 위해서 새게임버튼을 클릭");  
     ta.append("\n2. 입력에 중복되지않는 세자리수를 입력   후 엔터");  
     ta.append("\n3. 숫자와 자릿수를 맞추면 Strike, 숫자  만 맞추면 Ball이 추가됩니다.");  
     ta.append("\n4. 정답을 보고 싶으면 정답버튼을 클릭");  
     ta.append("\n5. 기타 문의사항이 있으면 관리자에게     연락바람(02-754-7302)");  
   }//ruleDescription

   public void showMsg(String message) {
       JOptionPane.showMessageDialog(this, message);
   }//showMsg

   //게임 시작
   public void startGame() {
      start=true; 

      createNum();
      tf.setEnabled(true); 
      ta.setText("");
      count=0;
      bt_dap.setEnabled(true);
      bt_hint.setEnabled(true);

      tf.requestFocus();
   }//startGame

   //게임 끝   
   public void endGame() {
      start=false;  

      tf.setEnabled(false); 
      bt_dap.setEnabled(false);
      bt_hint.setEnabled(false);
   }

   public static void main(String[] args) {
     new BaseBallGame2();
   }

}







JTable

package j0430;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;

public class JTableTest extends JFrame{
   /*
 문제1)

      JFrame 'Center'에 javax.swing.JTable을 add시키시오.
           그리고 아래의 데이터를 JTable에 입력(표시)하시오. (API문서 참조)

      <데이터>
            이름        나이       직업
    ------------------------
          홍길동        13    학생                         
          길라임        15    학생                         
          김주원        17    학생            
   */

   JTable table;    
   JScrollPane scroll_table;

   public JTableTest() {
       setTitle("JTable테스트");

       Object[][] rowData = {
               // 0열            1열      2열
               { "홍길동",        13,    "학생" },
               { "길라임",        15,    "학생" },
               { "김주원",        17,    "학생" }

       };
       String[] columnTitle = {"이름","나이","직업"};

       table = new JTable(rowData, columnTitle)
               {
                    @Override
                    public boolean isCellEditable( int row, int column )
                    {
                        return false;
                    }
               };
       scroll_table = new JScrollPane(table);

       add(scroll_table);

//       add(table);

       setBounds(400,300, 300,300);
       setVisible(true);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
   }//생성자   

   public static void main(String[] args) {
       new JTableTest(); //JFrame객체 생성!!
   }

}







package j0430;

import java.awt.FlowLayout;

import javax.swing.JButton;
import javax.swing.JFrame;

class You extends JButton
{
    public You(String text)
    {
        super(text);
    }
}

class A
{
    void hello()
    {
        System.out.println("하이");
    }
}

public class My extends JFrame
{
    JButton bt;
    You you;

    public My()
    {
        bt = new JButton("버튼1");
        you = new You("버튼2");

        setLayout(new FlowLayout());
        add(bt);
        add(you);

        setSize(300,300);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }

    public static void main(String[] args)
    {
        new My();

        A a = new A() 
        {
            @Override
            public void hello()
            {
                System.out.println("신짜오~!"); //오버라이딩
            }
        };
        a.hello();
    }
}
package j0430;

import java.util.Vector;

import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;

public class JTableTest extends JFrame{
   /*
 문제1)

      JFrame 'Center'에 javax.swing.JTable을 add시키시오.
           그리고 아래의 데이터를 JTable에 입력(표시)하시오. (API문서 참조)

      <데이터>
            이름        나이       직업
    ------------------------
          홍길동        13    학생                         
          길라임        15    학생                         
          김주원        17    학생            


     JTable, JTextArea, JList  ===> 사이즈를 벗어나는 데이터를 표현하기 위해 JScrollPane 함께 사용.     
   */

   JTable table;    
   JScrollPane scroll_table;

   public JTableTest() {
       setTitle("JTable테스트");

       //JTable(Object[][] rowData, Object[] columnNames)
       Object [][] rowData = {
                                 //  0열       1열     2열
                                  {"홍길동", 13, "학생"}, //첫째행   0행
                                  {"길라임", 15, "학생"}, //둘째행   1행
                                  {"김주원", 17, "학생"}  //셋째행   2행
                             };
       String [] columnTitle = {"이름","나이","직업"};

       //DefaultTableModel(Object[][] data, Object[] columnNames)
       DefaultTableModel dtm = new DefaultTableModel(rowData,columnTitle);
       //DefaultTableModel 클래스 사용 이유?
       // 프로그램 실행 중  '행 단위 데이터'를  추가 또는 삭제 하기 위해


      // table = new JTable(rowData,columnTitle) {
       table = new JTable(dtm) {
           @Override
         public boolean isCellEditable(int row, int column) {
            return false;
         }
       };
       scroll_table = new JScrollPane(table);

       add(scroll_table);//(table);

       setBounds(400,300, 300,300);
       setVisible(true);
       setDefaultCloseOperation(EXIT_ON_CLOSE);
 /*
        <데이터>
            이름        나이       직업
    ------------------------
0행       홍길동        13    학생                         
1행       길라임        15    학생                         
2행       김주원        17    학생

        0열        1열        2열       

  */
 //문제2) JTable내의 '길라임'을 얻어서 (콘솔)화면에 출력하시오.
        //table.get메소드() 찾기      :  힌트 ===> 행열 인덱스를 사용!!
       Object nameValue= table.getValueAt(1, 0);
       System.out.println("nameValue="+ nameValue);

 //문제3) JTable내의 '길라임' ---> '차라임'으로 변경
        //table.set메소드() 찾기      :  힌트 ===> 행열 인덱스를 사용!!
       //table.setValueAt(Object aValue, int row, int column);//aValue: 변경할 데이터
       table.setValueAt("차라임", 1, 0);

 //문제4) JTable내의 모든 사람의 이름을 (콘솔)화면에 출력하시오.
        //힌트: 이름 ---> 0열
       System.out.println(table.getValueAt(0, 0)); 
       System.out.println(table.getValueAt(1, 0)); 
       System.out.println(table.getValueAt(2, 0)); 
       //System.out.println(table.getValueAt(3, 0)); //IndexOutOfBounds에러 발생
       System.out.println("======================");
       for(int i=0; i<table.getRowCount(); i++) {//행인덱스 표현
           System.out.println(table.getValueAt(i, 0));
       }

 //문제5) 행 추가!!  ---> ["김유신",13,"화랑"]
       //table.setValueAt("김유신", 3, 0);   (X):에러 ==> 존재하지 않는 행인덱스를 참조

       Object [] newRow = {"김유신",13,"화랑"};
       dtm.addRow(newRow);

       Vector<Object> v = new Vector<>();
          v.add("강감찬");
          v.add(28);
          v.add("장군");
       dtm.addRow(v);          


 //문제6) 김주원 행을 삭제 (힌트: 세번째행 ---> 2인덱스행)   
       dtm.removeRow(2);


   }//생성자   

   public static void main(String[] args) {
       new JTableTest(); //JFrame객체 생성!!
   }

}








190429_Day16 복습, Swing

이벤트 처리 복습


그리고 오늘은 스윙을 배워본다!

스윙도 자바 GUI, 더 기능이 많고 자바 언어로만 쓰여있어서 다른 기기에서도 바뀌지 않는다!

스윙(Swing)

  • AWT : 내부적으로 C언어로 구성

    • 운영체제에서 지원하는 컴포넌트를 얻어 옴.
    • (동일한 class가 운영체제 OS에 따라 다른 모양으로 보일 수 있음)
    • java.awt.*;
  • Swing : 순수자바언어로 구성.( 운영체제에 상관없이 동일한 컴포넌트 지원 )

    • javax.swing.*;

    • 특징 : awt와 비교하여 첫글자가 ‘J’로 시작!

    • AWT Swing
      Button JButton
      Frame JFrame
      Checkbox JCheckBox(o)JCheckbox(x)
  • package j0429;
    
    import java.awt.FlowLayout;
    import java.awt.event.WindowAdapter;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    
    public class SwingTest extends JFrame
    {
    JButton bt,bt1;
    
    public SwingTest()
    {
        setTitle("Swing테스트");
    
        bt = new JButton("<html><font size = 20 color = red face = 궁서체>나버튼</font></html>"); //html 태그 적용 가능
        bt1 = new JButton("나버튼"); 
    
        setLayout(new FlowLayout());
        add(bt);
        add(bt1);
    
        setSize(300,500);
        setVisible(true);
        //만약 프레임 우측 상단의 X버튼 클릭시 프로그램 종료만 할 것이라면 아래의 코드 사용!
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        //X버튼에 기능 부여할 것이면 addWindowListener() 사용!
    }
    
    
    public static void main(String[] args)
    {
        new SwingTest();
    }
    }
    
  • 1556503089180

  • package j0429;
    
    import java.awt.GridLayout;
    
    import javax.swing.ImageIcon;
    import javax.swing.JCheckBox;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.border.BevelBorder;
    import javax.swing.border.TitledBorder;
    
    public class JCheckBoxTest extends JFrame
    {
    JCheckBox cb1, cb2, cb3;
    JPanel panel;
    
    public JCheckBoxTest()
    {
        ImageIcon icon1 = new ImageIcon("src/image/left.gif"); // 경로는 대소문자 구분 안함
        ImageIcon icon2 = new ImageIcon("src/image/leftrollover.gif");
        ImageIcon icon3 = new ImageIcon("src/image/leftdown.gif"); 
        ImageIcon icon4 = new ImageIcon("src/image/right.gif");
        ImageIcon icon5 = new ImageIcon("src/image/rightrollover.gif");
        ImageIcon icon6 = new ImageIcon("src/image/rightdown.gif"); 
        cb1 = new JCheckBox("첫번째 체크박스",icon1);
        cb1.setRolloverIcon(icon2);
        cb1.setSelectedIcon(icon3);
    
        cb2 = new JCheckBox("두번째 체크박스",icon4);
        cb2.setRolloverIcon(icon5);
        cb2.setSelectedIcon(icon6);
    
        cb3 = new JCheckBox("세번째 체크박스");
    
        panel = new JPanel();
            panel.setLayout(new GridLayout( 3, 1 ));
            panel.add(cb1);
            panel.add(cb2);
            panel.add(cb3);
    
    //            panel.setBorder(new TitledBorder("패널타이틀"));
    //            panel.setBorder(new BevelBorder(BevelBorder.RAISED)); //양각
    //            panel.setBorder(new BevelBorder(BevelBorder.LOWERED)); //음각
            panel.setBorder(new TitledBorder(new BevelBorder(BevelBorder.LOWERED), "패널타이틀"));
    
        setTitle("체크박스테스트");
        add(panel);
        //JFrame - BorderLayout기본레이아웃 "Center"기본위치
    
            setSize(300,200);
            setVisible(true);
            setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    public static void main(String[] args)
    {
        new JCheckBoxTest();
    }
    }
    
  • 1556505751843

  • package j0429;
    
    import java.awt.GridLayout;
    
    import javax.swing.ButtonGroup;
    import javax.swing.ImageIcon;
    import javax.swing.JFrame;
    import javax.swing.JPanel;
    import javax.swing.JRadioButton;
    import javax.swing.border.BevelBorder;
    import javax.swing.border.TitledBorder;
    
    public class JRadioButtonTest extends JFrame
    {
    JRadioButton radio1, radio2, radio3;
    JPanel panel;
    
    public JRadioButtonTest()
    {
        ImageIcon icon1 = new ImageIcon("src/image/left.gif");
        ImageIcon icon2 = new ImageIcon("src/image/leftRollover.gif");
        ImageIcon icon3 = new ImageIcon("src/image/leftdown.gif");
    
        radio1 = new JRadioButton("라디오1", icon1);
        radio2 = new JRadioButton("라디오2", icon2);
        radio3 = new JRadioButton("라디오3", icon3);
    
        ButtonGroup group = new ButtonGroup();
        group.add(radio1);
        group.add(radio2);
        group.add(radio3);
    
        panel = new JPanel();
        panel.setLayout(new GridLayout( 3, 1 ) );
            panel.add(radio1);
            panel.add(radio2);
            panel.add(radio3);  
        panel.setBorder(new TitledBorder(new BevelBorder(BevelBorder.RAISED), "라디오그룹" ) );
    
        setTitle("라디오 버튼 테스트");
        add(panel);
    
        setSize(200,300);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    }
    
    
    public static void main(String[] args)
    {
        new JRadioButtonTest();
    }
    }
    
    
  • 1556506893675

  • //JList 안쓴것 
    
    package j0429;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.GridLayout;
    import java.awt.List;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class ItemMoveTest extends JFrame
    {
    
       JButton bt_right,bt_right_all, bt_left, bt_left_all;
    
    JPanel leftp, centerp, rightp;
    
    //    JList<String> left_list = new JList<String>();
    //    JList<String> right_list = new JList<String>();
    List left_list, right_list;
    
    JTextField left_tf, right_tf;
    
    public ItemMoveTest()
    {
    
    //        ImageIcon icon1 = new ImageIcon();
    //        ImageIcon icon2 = new ImageIcon();
    //        ImageIcon icon3 = new ImageIcon();
    //        ImageIcon icon4 = new ImageIcon();
    
          left_list = new List();
          right_list = new List();
    
          left_tf = new JTextField();      
          right_tf = new JTextField();
    
          bt_right = new JButton("▷");
          bt_right_all = new JButton("▶");
          bt_left = new JButton("◁");
          bt_left_all = new JButton("◀");
    
          leftp = new JPanel();
            leftp.setLayout(new BorderLayout());
            leftp.add("Center",left_list);
            leftp.add("South",left_tf);
    
          rightp = new JPanel();
            rightp.setLayout(new BorderLayout());
            rightp.add("Center",right_list);
            rightp.add("South",right_tf);
    
          centerp = new JPanel();
            centerp.setBackground(Color.YELLOW);
            centerp.setLayout(new GridLayout(6,3));
            centerp.add(new JLabel());
            centerp.add(bt_left);
            centerp.add(bt_left_all);
            centerp.add(bt_right);
            centerp.add(bt_right_all);
    
            setTitle("Item움직이기");
            setLayout(new GridLayout(1,3));
            add(leftp);
            add(centerp);
            add(rightp);
    
        setSize(300,400);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    
    }
    
    public static void main(String[] args)
    {
        new ItemMoveTest();
    }
    
    }
    
  • //=== 그냥 리스트
    package j0429;
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.GridLayout;
    import java.awt.List;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JTextField;
    
    public class ItemMoveTest extends JFrame implements ActionListener
    {
    // JList<String> left_list, right_list;
    List left_list, right_list;
    
    JTextField left_tf, right_tf;
    JButton bt_right, bt_right_all, bt_left, bt_left_all;
    
    JPanel leftp, centerp, rightp;
    
    public ItemMoveTest()
    {
    //      left_list = new JList<String>();
    //      right_list = new JList<String>();
        left_list = new List();
        right_list = new List();
    
        left_tf = new JTextField();
        right_tf = new JTextField();
    
        // 'ㅁ'한글입력 - 한자키 누름
        // 확장된 부호찾기 - ▷ ▶ ◁ ◀
        bt_right = new JButton("▷");
        bt_right_all = new JButton("▶");
        bt_left = new JButton("◁");
        bt_left_all = new JButton("◀");
    
        leftp = new JPanel();
        leftp.setLayout(new BorderLayout());
        leftp.add("Center", left_list);
        leftp.add("South", left_tf);
    
        rightp = new JPanel();
        rightp.setLayout(new BorderLayout());
        rightp.add("Center", right_list);
        rightp.add("South", right_tf);
    
        centerp = new JPanel();
        centerp.setBackground(Color.YELLOW);
        centerp.setLayout(new GridLayout(6, 3, 10, 10));
        centerp.add(new JLabel());
        centerp.add(new JLabel());
        centerp.add(new JLabel());
        centerp.add(new JLabel());
        centerp.add(bt_left);
        centerp.add(new JLabel());
        centerp.add(new JLabel());
        centerp.add(bt_left_all);
        centerp.add(new JLabel());
        centerp.add(new JLabel());
        centerp.add(bt_right);
        centerp.add(new JLabel());
        centerp.add(new JLabel());
        centerp.add(bt_right_all);
        centerp.add(new JLabel());
        // centerp.add(new JLabel());centerp.add(new JLabel());centerp.add(new
        // JLabel());
    
        setTitle("Item움직이기");
        setLayout(new GridLayout(1, 3));
        add(leftp);
        add(centerp);
        add(rightp);
    
        setSize(600, 300);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    
        eventUp();
    }// 생성자
    private void eventUp() //이벤트 소스 등록
    {
        //버튼
        bt_left.addActionListener(this); // bt_left에 액션을 감지하다가 핸들러 호출.
        bt_left_all.addActionListener(this); // bt_left에 액션을 감지하다가 핸들러 호출.
        bt_right.addActionListener(this); // bt_left에 액션을 감지하다가 핸들러 호출.
        bt_right_all.addActionListener(this); // bt_left에 액션을 감지하다가 핸들러 호출.
    
        //텍스트필드
        left_tf.addActionListener(this);
        right_tf.addActionListener(this);
    
    }
    @Override
    public void actionPerformed(ActionEvent e) // 핸들러(기능추가)
    {
        //액션 : 버튼누르기 , 텍스트필드에 enter입력
    //        System.out.println("테스트");
        Object ob = e.getSource();  //이벤트 발생시킨 이벤트소스의 주소 얻기
    
        if(ob == left_tf) //주소 비교
        {
            //1. 데이터 얻기
            String str = left_tf.getText();
            if(str.trim().length()<1) //str이 공백과 같다면
            {
    
                return;
            }
            //2. 데이터 복사
            left_list.add(str);
            //3. 원본데이터 삭제
            left_tf.setText("");
        }
        else if(ob == right_tf) //주소 비교
        {
            //1. 데이터 얻기
            String str = right_tf.getText();
            if(str.trim().length()<1)
            {
                return;
            }
            //2. 데이터 복사
            right_list.add(str);
            //3. 원본데이터 삭제
            right_tf.setText("");
        }
        else if(ob == bt_left) //주소 비교 , 첫번째 버튼(bt_left) 클릭시
        {
            String str = right_list.getSelectedItem();
    
            if(str == null)
            {
    //                JOptionPane.showMessageDialog(Component parentComponent, Objectmessage);
    //                parentComponent : 대화상자가 올려지는 바탕(기준) 콤포넌트
                //messate : 전달메세지
                JOptionPane.showMessageDialog(right_list, "이동할 아이템 선택!");
                return; // 현재 메소드 종료
            }
            left_list.add(str);
            right_list.remove(str);
        }
    
        else if(ob == bt_left_all) //주소 비교
        {
            for(int i = 0; i<right_list.getItemCount(); i++)
            {
                System.out.println(" getItem ( " + i + " )  = "  +right_list.getItem(i));
                left_list.add(right_list.getItem(i));
            }
            right_list.removeAll(); // 복사가 전체 끝난 후 원본 리스트 전체 데이터 지우기
        }
        else if(ob == bt_right) //주소 비교
        {
            String str = left_list.getSelectedItem();
            if(str == null)
            {
    //                JOptionPane.showMessageDialog(Component parentComponent, Objectmessage);
    //                parentComponent : 대화상자가 올려지는 바탕(기준) 콤포넌트
                //messate : 전달메세지
                JOptionPane.showMessageDialog(right_list, "이동할 아이템 선택!");
                return; // 현재 메소드 종료
            }
            right_list.add(str);
            left_list.remove(str);
        }
        else //주소 비교
        {
            for(int i = 0; i<left_list.getItemCount(); i++)
            {
                System.out.println(" getItem ( " + i + " )  = "  +left_list.getItem(i));
                right_list.add(left_list.getItem(i));
            }
            left_list.removeAll(); // 복사가 전체 끝난 후 원본 리스트 전체 데이터 지우기
        }
    
    }//actionPerformed
    
    public static void main(String[] args)
    {
        new ItemMoveTest();
    }
    
    }
    
  • //JList 사용
    
    import java.awt.BorderLayout;
    import java.awt.Color;
    import java.awt.GridLayout;
    import java.awt.List;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.util.Vector;
    
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JList;
    import javax.swing.JOptionPane;
    import javax.swing.JPanel;
    import javax.swing.JScrollPane;
    import javax.swing.JTextField;
    
    public class ItemMoveTest2 extends JFrame implements ActionListener{
     JList<String> left_list, right_list;
    
     JTextField left_tf, right_tf;
     JButton bt_right,bt_right_all, bt_left, bt_left_all;
    
     JPanel leftp, centerp, rightp;
    
     JScrollPane left_scrol, right_scrol;
     //스크롤바가 지원되는 패널 --->  보통 JList, JTextArea, JTable과 함께 사용
    
     //JList는 데이터를 String[] 또는 Vector로 따로 분리해서 저장!!
     Vector<String> leftV;//좌측 JList가 담을 데이터를 표현   
     Vector<String> rightV;//우측 JList가 담을 데이터를 표현   
    
     public ItemMoveTest2() {
      leftV = new Vector<String>();
      rightV = new Vector<String>();
    
        left_list = new JList<String>();
        //left_scrol = new JScrollPane(스크롤바를 필요로 하는 컴포넌트);
        left_scrol = new JScrollPane(left_list);
        /*
    
        <JList에 데이터 추가방법>
        left_list.setListData(String[] listData);
        left_list.setListData(Vector listData);
    
        */
    
    //      String[] listData = {"홍길동","길라임","김주원",
    //              "홍길동","길라임","김주원",
    //              "홍길동","길라임","김주원",
    //              "홍길동","길라임","김주원",
    //              "홍길동","길라임","김주원",
    //              "홍길동","길라임","김주원",
    //              "홍길동","길라임","김주원",
    //              "홍길동","길라임","김주원"              
    //                           };
    //      left_list.setListData(listData);
    
    
    
    
        right_list = new JList<String>();
        right_scrol = new JScrollPane(right_list);
    
    //      Vector<String> v = new Vector<>();
    //       v.add("김유신");
    //       v.add("이순신");
    //       v.add("강감찬");
    //      right_list.setListData(v);  
    
    
        left_tf = new JTextField();     
        right_tf = new JTextField();
    
        //'ㅁ'한글입력 - 한자키 누름
        //확장된 부호찾기 - ▷ ▶ ◁ ◀
        bt_right = new JButton("▷");
        bt_right_all = new JButton("▶");
        bt_left = new JButton("◁");
        bt_left_all = new JButton("◀");
    
        leftp = new JPanel();
          leftp.setLayout(new BorderLayout());
          //leftp.add("Center",left_list);//JList붙이기
          leftp.add("Center",left_scrol);//스크롤바가 있는 JList붙이기
          leftp.add("South",left_tf);
    
        rightp = new JPanel();
          rightp.setLayout(new BorderLayout());
          //rightp.add("Center",right_list);
          rightp.add("Center",right_scrol);
          rightp.add("South",right_tf);
    
        centerp = new JPanel();
          centerp.setBackground(Color.YELLOW);
          centerp.setLayout(new GridLayout(6,3,10,10));
          centerp.add(new JLabel());centerp.add(new JLabel());centerp.add(new JLabel());
          centerp.add(new JLabel());centerp.add(bt_right);     centerp.add(new JLabel());
          centerp.add(new JLabel());centerp.add(bt_right_all); centerp.add(new JLabel());
          centerp.add(new JLabel());centerp.add(bt_left);    centerp.add(new JLabel());
          centerp.add(new JLabel());centerp.add(bt_left_all);centerp.add(new JLabel());
          //centerp.add(new JLabel());centerp.add(new JLabel());centerp.add(new JLabel());
    
    
        setTitle("Item움직이기");
        setLayout(new GridLayout(1,3));
        add(leftp);
        add(centerp);
        add(rightp);
    
        setSize(600, 300);
        setVisible(true);
        setDefaultCloseOperation(EXIT_ON_CLOSE);
    
        eventUp();
     }//생성자
    
     private void eventUp() {//이벤트 소스 등록
      //버튼
      bt_left.addActionListener(this);//bt_left에 액션을 감지하다가 핸들러 호출.
      bt_left_all.addActionListener(this);
      bt_right.addActionListener(this);
      bt_right_all.addActionListener(this);
    
      //텍스트필드
      left_tf.addActionListener(this);
      right_tf.addActionListener(this);
     }
    
    @Override
     public void actionPerformed(ActionEvent e) {//핸들러(기능추가)
        //액션: 버튼누르기, 텍스트필드에 enter입력
      //System.out.println("action");   
      Object ob = e.getSource();//이벤트 발생시킨 이벤트소스의 주소 얻기.
        if(ob==left_tf) {//좌측 텍스트필드에 엔터입력시
         //1.데이터 얻기
          String str = left_tf.getText();
    
          if(str.trim().equals("")) {//str이 공백과 같다면!!
              left_tf.setText("");
              return;
          }       
    
         //2.데이터 복사
          leftV.add(str);//벡터에 담고
          left_list.setListData(leftV);//벡터 데이터를 JList에 반영
    
         //3.원본데이터 삭제
          left_tf.setText("");
      }else if(ob==right_tf) {//우측 텍스트필드에 엔터입력시
         //1.데이터 얻기
          String str = right_tf.getText();
    
          if(str.trim().length()<1) {//str이 공백과 같다면!!
              right_tf.setText("");
              return;
          }
    
         //2.데이터 복사   
    
         //3.원본데이터 삭제
          right_tf.setText("");
      }else if(ob==bt_right) {//첫번째버튼(bt_left) 클릭시
         //1.(선택된아이템) 데이터 얻기
          String str = left_list.getSelectedValue();
                      //선택된 아이템이 없을시 null 리턴!!
    
          if(str==null) {
            //JOptionPane.showMessageDialog(Component parentComponent,Object message);
            //parentComponent: 대화상자가 올려지는 바탕(기준) 컴포넌트
            //message: 전달 메시지
              //JOptionPane.showMessageDialog(left_list,"이동할 아이템 선택!!");  
              JOptionPane.showMessageDialog(this,"이동할 아이템 선택!!");  
             return;//현재 메소드 종료!!
          }
    
         //2.데이터 복사 (우측 Vector에 전달)
            rightV.add(str);//오른쪽 벡터에 데이터 추가
            right_list.setListData(rightV);//벡터값을 오른쪽리스트에 전달(반영)
    
         //3.원본데이터 삭제
            leftV.remove(str);//왼쪽 벡터에 데이터 삭제
            left_list.setListData(leftV);//벡터값을 왼쪽리스트에 전달(반영)
    
    
      }else if(ob==bt_right_all) {//두번째버튼(bt_left_all) 클릭시
          //벡터 사이에서 데이터 전달
            //왼쪽벡터 데이터   ---------->  오른쪽벡터 데이터
          for(int i=0; i<leftV.size(); i++) {
             rightV.add(leftV.get(i));
          }
    
          //왼쪽벡터 데이터 전체 삭제
          leftV.clear();
          //--------------------------------------------
    
    
          //각 리스트는 변경된 벡터내용을 refresh!!
          left_list.setListData(leftV);
          right_list.setListData(rightV);
    
    
    
      }else if(ob==bt_left) {//세번째버튼(bt_right) 클릭시
        //1.(선택된아이템) 데이터 얻기
          String str = "";
    
          if(str==null) {//선택된 아이템이 없다면
              JOptionPane.showMessageDialog(this,"이동할 아이템 선택!!");  
              return;//현재 메소드 종료!!
          }
    
         //2.데이터 복사   
    
         //3.원본데이터 삭제
    
    
      }else {//if(ob==bt_left_all) {//네번째버튼(bt_right_all) 클릭시
    //          for(int i=0; i<right_list.getItemCount(); i++) {
    //              left_list.add(right_list.getItem(i));//1,2
    //          }       
          right_list.removeAll();//3.복사가 전체 끝난 후  원본 리스트 전체 데이터를 지우기.
    
      }
    
     }//actionPerformed
    
     public static void main(String[] args) {
      new ItemMoveTest2();
     }
    }
  • awt는 자동 스크롤바 지원, 스윙에서는 JScrollPane 사용해 주어야 한다.

궁금상자
    - 스윙 어디서 쓰이는걸까?
    - setBounds
    - GridLayout, BorderLayout

+ Recent posts