Super Kawaii Cute Cat Kaoani
본문 바로가기
💻 Programming/Java

[JAVA] 개념 정리 (1)

by wonee1 2023. 10. 15.
728x90
입출력 스트림 

 
스트림 개념
 
연속된 데이터와 단방향 흐름을 추상화 
데이터 소스와 상관없이 적용할 수 있어 매우 효과적
 
스트림 예

  • 키보드 및 모니터의 입출력
  • 프로그램과 외부장치 파일의 입출력에서 데이터 흐름도 스트림
  • 네트워크와 통신하는 데이터의 흐름
  • 데이터 집합체의 각 원소를 순회하면서 람다식으로 반복 처리되는 데이터 흐름 

 
입출력 스트림의 특징

  • 선입선출 구조  순차적으로 흘러가고 순차적으로 접근
  • 임의 접근 파일 스트림을 제외한 모든 스트림은 단방향
  • 입출력 스트림은 객체
  • 출력 스트림과 입력 스트림을 연결해서 파이프라인 구성 가능

 
입출력 스트림의 유형
데이터를 전달하는 방식에 따라 바이트 스트림과 문자 스트림으로 구분 
 
바이트 스트림: InputStream, OutputStream / 영상 음성 영문자 등의 바이너리 데이터 처리. 1바이트 단위 입출력 처리
문자 스트림: Reader, Writer / 2바이트 단위의 문자 입출력 처리 
 
바이트 스트림
 
InputStream과 OutputStream
FileInputStream및 FileOutputStream

  • 시스템에 있는 모든 파일을 읽거나 쓸 수 있는 기능을 제공
  • 생성자로 스트림 객체를 생성할 때는 FileNotFoundException 예외 가능성이 있기 때문에 반드시 예외 처리 필요

BufferedInputStream및 BufferedOutputStream

  • 버퍼는 스트림과 프로그램 간에 데이터를 효율적으로 전송하려고 사용하는 메모리
  • 입출력 장치와 프로그램 간 동작 속도가 크게 차이가 날 때 버퍼를 사용하면 매우 효율적

DataInputStream및 DataOutputStream

  • 각각 기초 타입 데이터를 읽는 메서드와 기초 타입 데이터를 기록하는 메서드를 사용할 수 있는 스트림

문자 스트림 
 
 
Reader와 Writer

  • 객체를 생성할 수 없는 추상 클래스이기 때문에 Reader와 Writer의 자식인 구현 클래스를 사용

 FileReader와 FileWriter

  • 파일 입출력 클래스로, 파일에서 문자 데이터를 읽거나 파일에 문자 데이터 를 저장할 때 사용

InputStreamReader및 OutputStreamWriter

  • 바이트 스트림과 문자 스트림을 연결하는 브리지 스트림으로 사용

 BufferedReader와 BufferedWriter

  • 데이터를 효율적으로 전송하려고 버퍼로 처리할 때 사용

 
파일관리 
 
File 클래스

  •  파일이나 폴더의 경로를 추상화한 클래스로 java.io 패키지에 포함
  • 파일 유무, 삭제, 접근 권한 조사 등을 수행
  •  File 클래스 생성자

 
Path 인터페이스

  • 운영체제에 따라 일관성 없이 동작하는 File 클래스를 대체하는 것
  • 기존 File 객체도 File 클래스의 toPath( ) 메서드를 이용해 Path 타입으로 변환 가능
  • Path 인터페이스의 구현 객체는 파일 시스템에서 경로를 나타낸다.
  •  java.nio.file 패키지에 포함
  • java.io.File 클래스와 마찬가지로 파일의 유무, 삭제, 접근 권한 조사 등이 주요 기능

 
 
Files 클래스

  •  파일 연산을 수행하는 정적 메서드로 구성된 클래스
  • java.nio.file 패키지에 포함

 
Paths 클래스

  •  정적 메서드 Path get(String first, String... more)

 
 
 

프로세스와 스레드 

프로세스 

  • 프로세스는 실행중인 프로그램, 프로그램은 파일의 형태로 디스크에 존재함
  • 프로그램이 실행되면 메모리에 파일이 프로세스 형태로 로드된다.
  • 프로세스끼리는 서로 독립적이다 

멀티태스킹

  • 멀티코어 CPU라면 실제로 다수의 애플리케이션을 동시에 병렬처리한다.
  • 싱글코어CPU라면 운영체제가 다수의 애플리케이션을 병행처리한다.
  • 하나의 애플리케이션에서도 동시에 수행할 수 있는 다수의 코드 블록이 있을 수 있기 때문에 멀티태스킹이 가능하다.
  • 멀티코어 CPU는 멀티스레드를 지원한다. 

스레드의 의미 

  • 하나의 실행 흐름으로 프로세스 내부에 존재한다.
  • 하나의 프로세스는 하나 이상의 실행 흐름을 포함하며 프로세스는 적어도 하나의 스레드를 가지고 있다.
  • 메모리와 파일 등 모든 자원을 프로세스 자원과 공유한다.
  • 자바 애플리케이션의 실행 환경인 JVM은 하나의 프로세스로 실행한다. 

 
 
 

스레드 생성과 실행 

 
스레드 생성 방법 
자바 애플리케이션은 적어도 메인 스레드라는 하나의 스레드를 가짐 
 

  • Runnable 구현 클래스 정의
class MyRunnable implements Runnable{
// 스레드가 실행할 코드 
}

Thread t = new Thread(new MyRunnable());

t.strat() // 스레드 실행

 

  • Thread 자식 클래스 정의 
class WorkerThread extends Thread {
//스레드가 실행할 코드
}

Thread t = new WorkerThread();
t.start();//스레드 실행

 
Runnable 구현 클래스에 스레드 실행 코드 추가 
 

public class Main {
	public static void main(String[] args) {
		Thread t = new Thread(new MyRunnable());//스레드 정의
		t.start();//백그라운드 스레드 생성(시작) 

		for (int i = 0; i < 5; i++) {
			System.out.print("안녕. ");
			try {
				Thread.sleep(500);// 이 스레드를 ms 만큼 유휴상태로...500ms
			} catch (InterruptedException e) {
			}
		}//메인스레드 
	}
}

class MyRunnable implements Runnable { // Runnnable 구현 클래스 MyRunable 
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.print("잘가. "); 
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
	}
}

실행을 할때마다 안녕. 잘가. 순서가 달라짐
그 이유는 컴퓨터 시스템 안에 main 스레드와 t 스레드가 동시에 진행되고 있기 때문에.
싱글 스레드였으면 코드 순서대로 출력된다.
 
 
 
Thread 자식 클래스에 스레드 실행 코드 추가 
 

public class Main {
	public static void main(String[] args) {
		Thread t = new WorkerThread();//클래스 객체만 생성 
		t.start();

		for (int i = 0; i < 5; i++) {
			System.out.print("안녕. ");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
	}
}

class WorkerThread extends Thread {
	public void run() {
		for (int i = 0; i < 5; i++) {
			System.out.print("잘가. ");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
	}
}

 
스레드 풀을 이용한 스레드 실행 
 

  • 스레드의 개수가 많아지면 그에 따른 스레드 객체 생성과 스케줄링 등으로 CPU와 메모리에 많은 부하가 발생-> 동시에 실행하는 스레드 개수를 제한할 필요 
  • 스레드 풀은 제한된 개수의 스레드를 JVM에 관리하도록 맡기는 방식 

 

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Main {
	public static void main(String[] args) {
		Runnable task = () -> {
			for (int i = 0; i < 5; i++) {
				System.out.print("잘가. ");
				try {
					Thread.sleep(500);
				} catch (InterruptedException e) {
				}
			}
		};스레드가 수행할 코드 


		// ExecutorService exec = Executors.newCachedThreadPool(); // 스레드 동적 생성
		ExecutorService exec = Executors.newFixedThreadPool(2); // 고정된 스레드 수 생성
		// exec.execute(task); // Runnable task만 단순하게 수행함. 예외처리 x return값x		
        exec.submit(task); // Runnable, Callable 모두 OK, 예외처리 있음, return값 있음

		for (int i = 0; i < 5; i++) {
			System.out.print("안녕. ");
			try {
				Thread.sleep(500);
			} catch (InterruptedException e) {
			}
		}
		exec.shutdown();
	}
}

 
 

스레드 상태와 제어

 
스레드 종료
 
run() 메서드 실행 종료를 위한 stop() 메서드 -> 잘 사용하지 않는다
 
스레드를 안전하게 종료하는 방법

  • 반복문의 조건
  • interrupt() 메서드

 
반복문의 조건
 

class StopThread extends Thread {
	public boolean stop;

	public void run() {
		while (!stop) {//종료가 아니라면 실행 띄우기 fasle일때 루프돌림 
			System.out.println("실행 중...");
			try {
				Thread.sleep(1);//1ms 
			} catch (InterruptedException e) {
			}
		}
		System.out.println("정상 종료");
	}
}

public class Main {
	public static void main(String[] args) {
		StopThread t = new StopThread();
		t.start();//스레드가 생성되고 실행이 됨

		try {
			Thread.sleep(3);/3ms 를 대기하고 
		} catch (InterruptedException e) {
		}

		t.stop = true;//boolean변수인 stop을 true로 선언함->반복문 탈출 
	}
}

 
인터럽트 메서드 

public class Main {
	public static void main(String[] args) {
		Runnable task = () -> {
			try {
				while (true) {//무한루프 
					System.out.println("실행 중...");
					Thread.sleep(1);
				}
			} catch (InterruptedException e) {
				// 인터럽트 처리 코드, 실행되면 바로 끝남 
			}
			System.out.println("정상 종료");
		};//스레드가 수행할 코드 

		Thread t = new Thread(task);
		t.start();

		try {
			Thread.sleep(2);//2ms
		} catch (InterruptedException e) {
		}
		t.interrupt();//인터럽트를 걸면 catch구문안에 있는 인터럽트 처리코드가실행됨 
	}
}

인터럽트 신호가 올 때까지 실행중 메서지를 출력하다가 인터럽트를 걸면 cathch 구문안에 있는 인터럽트 처리 코드가 실행된다. 처리코드가 실행되면 무한루프가 종료된 뒤 정상 종료라는 메세지가 출력된다.
 
 
 
다른 스레드를 종료할 때까지 대기
join 메서드 사용 예제 (중요함)
 

class JoinThread extends Thread {
	int total;

	public void run() {
		try{
		//Thread.sleepn(1000);
		for (int i = 1; i <= 100; i++)
			total += i;
			System.out.println("자식 스레드 관점, 총합:"+total);
		}catch(InterruptedException e){
}
	}
}

public class Main {
	public static void main(String[] args) {
		JoinThread t = new JoinThread();
		//t.setDaemon(true);
		t.start();//위에 JoinThread t 라고 정의해놓은 스레드를 실제로 생성하고 실행

		//스레드 1: main 스레드, 이미 main 자체가 스레드 -> 부모스레드
		//스레드2: t 스레드 -> 자식 스레드 
		//스레드 1은.. 스레드 2 .. 각자 할일을함 -> main스레드가 종료되면 t 스레드가 
        //다 실행되지 않았음에도 종료되는 문제 발생, t.strat를 하면 바로 밑으로 내려가서 종료됨 
		
		/* 
		 try {
		 t.join();//main 스레드는 대기 
		 System.out.println("스레드 t가 끝날 때까지 대기...");
		 } catch (InterruptedException e) {
		 }
		*/

	
		
		System.out.println("부모 스레드 관점 총합 : " + t.total);//0이 나오는 이유: 부모 스레드가
        //자식스레드를 안기다리고 먼저 종료되었기 때문에
	}
}

 
부모 스레드가 자식 스레드가 종료될 때까지 기다려줘야한다. 
 
 
 
 
스레드 우선순위 
 
멀티 태스킹에서 스레드 개수가 cpu코어 개수 보다 만다면 스레드 스케줄링 필요
자바는 우선순위 방식과 순환 할당 방식 사용
 

class Counter extends Thread {
	private int count = 0;

	public Counter(String name) {
		setName(name);
	}

	public void run() {
		while (count++ < 5) {
			System.out.print(getName() + " -> ");
			try {
				sleep(500);
			} catch (InterruptedException e) {
			}
		}
	}
}

public class Main {
	public static void main(String[] args) {
		Counter c1 = new Counter("느긋한");
		c1.setPriority(Thread.MIN_PRIORITY);
		Counter c2 = new Counter("급한");
		c2.setPriority(Thread.MAX_PRIORITY);
		c1.start();
		c2.start();
	}
}

 
 
데몬 스레드 
 
일반적으로 스레드는 독립적으로 수행하기 때문에 메인 스레드를 종료해도 작업 스레드는 계속 실행
데몬 스레드:다른 스레드를 모두 종료하면 자동으로 종료되는 스레드 

public class Main {
	public static void main(String[] args) {//메인스레드이자 부모스레드
		Runnable task = () -> {
			for (int i = 0; i < 3; i++) {
				try {
					Thread.sleep(1000);
				} catch (InterruptedException e) {
				}
				System.out.println(Thread.currentThread().getName());
			}
		};

		Thread t1 = new Thread(task, "작업 스레드");
		// t1.setDaemon(true); //이게 없으면 t1은 유저 스레드, 있으면 데몬 스레드.
		t1.start();//자식스레드

		try {
			Thread.sleep(1000);
		} catch (InterruptedException e) {
		}
		System.out.println("메인 스레드가 끝났습니다.");
	}
}

 

동기화와 협업 

 
스레드 동기화 

  • 다중 스레드 프로그래밍 환경에서 임계영역이 있다면 동기화 문제 발생
  • 자바는 임계 영역을 동기화 하려고 synchronized 키워드 제공
  • 스레드가 synchronzied로 지정된 동기화 블록에 진입하면 락을 걸고, 그 블록을 벗어날 때 락을 푼다.
  • 동기화 블록에 진입한 스레드가 코드를 실행할 동안 다른 스레드는 동기화 블록 앞에서 락이 풀릴 때까지 대기해야한다

 
 
 
 
어떤 공유되는 값이 있다고 한다
int a=0;

스레드1
 a=a+1;//write쓰기,  write(a)
int b=a;//a를 읽어서 b에 쓰기, read(a)

스레드2

a=a-1;//write(a)
int c=a;//read(a)
 
이렇게 프로그램을 실행하면 a=a+1이 먼지 실행 될 수도 있고 a=a-1이 먼저 실행 될 수 있어서 결과가 항상 달라진다. 
 
이때  락을 걸어야 값이 일관성 있게 나온다.
 
a=1
a=a+1;//2                                               a=a-1; 동시에 진행되고 있음  //2->1
int b=a;// 2가아닌 1을 읽어올 수 있다   int c=a;
b=? //2                                                   c=?

결과가 항상 달라짐 동시성 문제 ->synchronized를 사용해서 락을 건다. 
 
 
두 가지 방법
 

  • 동기화 메서드 
 public synchronaized void 메서드(){
  // 임계영역 코드
 }

 

  • 동기화 블록 
synchronzied (공유객체){
//임계영역 코드

}

 
 
동기화 예제 

import java.util.Random;

class SharedCar {
	public synchronized void drive(String name, String where) {
		System.out.println(name + "님이 자동차에 탔습니다.");
		Random r = new Random();
		for (int i = 0; i < r.nextInt(3) + 1; i++)
			System.out.println(name + "님이 자동차를 운전합니다.");
		System.out.println(name + "님이 " + where + "에 도착했습니다.");
	}
}

class CarThread extends Thread {
	private String who;
	private SharedCar car;
	private String where;

	public CarThread(String who, SharedCar car, String where) {
		this.who = who;
		this.car = car;
		this.where = where;
	}

	public void run() {
		car.drive(who, where);
	}
}

public class Main {
	public static void main(String[] args) {
		SharedCar car = new SharedCar();
		new CarThread("뺀지리", car, "서울").start();
		new CarThread("문둥이", car, "부산").start();
		new CarThread("깽깽이", car, "광주").start();
	}
}

 
 

GUI 프로그래밍

 
스윙 
운영체제의 도움을 받지 않고 순수하게 자바로 작성되어 있기 때문에 스윙 컴포넌트를 경량 컴포넌트라고 한다.
모든 스윙 컴포넌트는 AWT 컴포넌트와 완전히 호환된다.
 

컨테이너 생성과 컴포넌트 추가 

 
 
컴포넌트 
버튼, 레이블,텍스트, 필드 등 GUI를 작성하는 기본적인 빌딩 블록
사용자 인터페이스를 생성하는 객체로 윈도우 시스템에선 컨트롤에 해당
 
컨테이너
 
컴포넌트를 부착하는 특수한 컴포넌트를 의미
컴포넌트를 부착할 수 있는 프레임이나 패널등이 대표적인 컨테이너 클래스
 
컨테이너는 내부의 배치 관리자를 사용해 컨포넌트의 위치를 결정하고 자신에게 부착
스윙 애플리케이션을 작성하려면 스윙 애플리케이션의 최상위 컨테이너인 프레임 생성 필요
 
 

Frame,Panel도 컨테이너

 
JFrame 
 

public class JFrame extends Frame
 implemets WindowConstants, Accessible, RootPaneContainer

 
복잡한 구조로 구성되어 있지만 개발자가 자주 접하는 부분은 메뉴바와 컨텐트페인
 
생성자

JFrame() // 타이틀이 없는 JFrame 객체를 생성한다
JFrame(String title)// 명시된 타이틀을 가진 JFrame 객체를 생성한다

 
이외에도 Component 클래스가 제공하는 add(), Window 클래스가 제공하는 setVisible(), Frame 클래스가 제공하는 setResizable() 등도 자주 사용한다
 
 

import javax.swing.JFrame;

public class Main extends JFrame {//메인클래스를 프레임으로 확장 
	Main() {
		setTitle("안녕, 스윙!");
		setSize(300, 100);
		setVisible(true);
	}//메인 클래스의 생성자 안에서 구현 

	public static void main(String[] args) {
		new Main();// Main 클래스 생성자 호출 
	}
}
결과창

 
프레임에 컴포넌트 추가 
 
스윙 컴포넌트를 프레임에 부착하려면 Conteainer 클래스가 제공하는 add() 메서드 를 호출 
 

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

public class Main extends JFrame {
	Main() {
		setTitle("안녕, 스윙!");

		JButton b = new JButton("버튼");//버튼 객체를 생성 
		add(b);//버튼 컴포넌트를 컨테이너에 추가 

		//setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 종료할 때 애플리케이션도 강제 종료
		setSize(300, 100);
		setVisible(true);
	}

	public static void main(String[] args) {
		new Main();//프레임 생성 
	}
}
결과창

 
패널로 프레임에 컴포넌트 추가 
 

//플로 레이아웃과 더블 버퍼를 가진 JPanel 객체를 생성한다.
JPanel()

//플로 레이아웃과 명시된 더블 버퍼 전략을 가진 JPanel 객체를 생성한다.
JPanel(boolean isDoubleBuffered)

//명시된 레이아웃과 더블 버퍼를 가진 JPanel 객체를 생성한다.
JPanel(LayoutManager manager)

//명시된 레이아웃과 더블 버퍼 전략을 가진 JPanel 객체를 생성한다.
Jpanel(LayoutManager manager,boolean isDoubleBuffered)

 
패널로 프레임에 컴포넌트 추가 
 

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

public class Main extends JFrame {
	Main() {
		setTitle("안녕, 스윙!");

		JPanel p = new JPanel();//패널을 생성 
		JLabel l = new JLabel("안녕, 스윙!");//레이블 생성
		JButton b = new JButton("버튼");
		
        p.add(l);//패널에 라벨 컴포넌트를 올린다는 뜻 
		p.add(b);//패널에 버튼 컴포넌트를 올린다는 뜻 
        
		add(p);//패널을 프레임에다가 올림 

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 100);
		// pack(); 여백제거 메서드 
		setVisible(true);
	}

	public static void main(String[] args) {
		new Main();
	}
}
결과창
컴포넌트 배치 

 
배치 관리자의 역할 
부착할 컴포넌트 위치를 결정해서 적절히 배치하며 컨테이너의 크기가 변하면 컴포넌트를 재배치
 
배치 관리자 설정 및 제거 
 

setLayout(new GridLayout());
setLayout(null);

컨테이너와 기본 배치 관리자

 
FlowLayout 배치 관리자

//중앙 정렬, 5픽셸 간격의 FlowLayout 객체를 생성한다.
FlowLayout()

//명시된 정렬, 5픽셸 간격의 FlowLayout 객체를 생성한다.
FlowLayout(int align)

//명시된 정렬 및 간격의 FlowLayout 객체를 생성한다.
FlowLayout(int align, int hgqp, int vgap)

왼쪽 정렬: FlowLayout.LEFT
오른쪽 정렬:FlowLayout.RIGHT
중앙 정렬(기본):FlowLayout.CENTER
 

JPanel p = new JPanel(new FlowLayout()); // 플로우레이아웃

p.setComponentOrientation(ComponentOrientation.RIGHT_TO_LEFT);// 오른쪽에서부터 왼쪽으로 배치

 

BorderLayout 배치 관리자
 

//간격이 없는 BorderLayout 객체를 생성한다.
BorderLayout()

// 명시한 간격을 가진 BorderLayout() 객체를 생성한다.
BorderLayout(int hgap, int vgap)

 
영역에 컴포넌트 추가하기 위한 메서드
 
Component add(Component comp, int index)
Component comp는 컨테이너에 부착시킬 컴포넌트
 
int index-> BorderLayout의 위치
동: BorderLayout.EAST
서: BorderLayout.WEST
남: BorderLayout.SOUTH
북: BorderLayout.NORTH
중앙: BorderLayout.CENTER
 
Component add(String name, Component comp)
String name -> BorderLayout의 위치
동: EAST
서: WEST
남:SOUTH
북:NORTH
중앙: CENTER
 
 
 

import java.awt.BorderLayout;

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

public class Main extends JFrame {
	Main() {
		setTitle("보더 레이아웃!");
		setLayout(new BorderLayout());

		add("East", new JButton("동"));
		add("West", new JButton("서"));
		add("South", new JButton("남"));
		add(new JButton("북"), BorderLayout.NORTH);
		add(new JButton("중앙"), BorderLayout.CENTER);

		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setSize(300, 110);
		setVisible(true);
	}

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

 

 
 
GridLayout 배치 관리자

//하나의 행과 열로 구성 GridLayout 객체를 생성한다.
GridLayout()

//명시된 행과 열로 구성된 GridLayout 객체를 생성한다.
GridLayout(int rows,int cols)

//명시된 행과 열, 명시된 간격의 GridLauout 객체를 생성한다.
GridLayout(int rows,int cols,int hgap, int vgap)

GridLayout 객체를 생성할 때 행과 열의 개수를 0이상의 정수로 명시
행이나 열의 값이 0이면 필요한 만큼의 행이나 열을 생성, 그러나 행과 열의 개수로 동시에 0은 사용금지 
 
 
배치 관리자 없이 컴포넌트 배치

  • 배치 관리자가 없을 때는 절대 좌표로 컴포넌트 배치
  • 컴포넌트 크기 위치를 setSize(), setLocation(), setBounds() 메서드를 이용에 개발자가 지정하는 번거로움 감수

 
 

주요 컴포넌트

 
GUI 컴포넌트의 상속관계 

Swing은 awt와 다르게 운영체제와  무관하게 일관된 화면을 보여준다.
 
Component 클래스 

  • 컴포넌트의 공통 속성과 크기, 모양, 색상, 폰트, 이동 ,삭제 ,이벤트 처리 등을 수행할 수 있는 메서드를 제공

Container 클래스

  • 다른 컨테이너 내부에 포함될 수 없는 최상위 컨테이너인 프레임, 다이얼로그, 애플릿
  • 다른 컨테이너에 포함될 수 있는 패널 또는 스크롤페인 등

JComponent 클래스 

  • 모든 스윙 컴포넌트의 부모 클래스

JLabel

  • 이벤트와 관계없이 단순히 텍스트나 이미지를 표시

JButton

  • 사용자가 직접 작동해서 제어할 수 있는 컴포넌트 중 하나
  • 사용자가 클릭하면 ActionEvent를 발생

 
JTextField

  • 한 행짜리 문자열 입력 창을 만드는 컴포넌트로, JTextArea 및 JEditPane과 함께 JTextComponent의 자식 클래스

 
JTextArea

  • 여러 행에 걸쳐 문자열을 입력하거나 편집할 수 있는 스윙 컴포넌트
  • 사용자가 문자열을 입력한 후 엔터 키를 누르면 ActionEvent가 발생

JComboBox

  • 다수의 항목 중에 하나를 선택하며, 컴포넌트에 텍스트와 이미지를 추가 가능
  • 항목을 선택하면 ActionEvent 발생, 항목을 변경하면 ItemEvent 발생

 
스윙 컴포넌트 응용
다음과 같은 외형을 구성
 

 

728x90

'💻 Programming > Java' 카테고리의 다른 글

[JAVA] 개념 정리 (3)  (0) 2023.10.19
[JAVA] 개념 정리(2)  (0) 2023.10.15