지구정복

[JAVA] 12/08 | JavaFx(Swing, 프레임, 위치와 크기설정, JFrame, 레이아웃과 위젯, 스레드 실행), Window Builder(jlabel, jbutton, jtextfield, jpassword, jtextarea), 구구단만들기, 우편번호 검색기 만들기 본문

데이터 엔지니어링 정복/JAVA & JSP

[JAVA] 12/08 | JavaFx(Swing, 프레임, 위치와 크기설정, JFrame, 레이아웃과 위젯, 스레드 실행), Window Builder(jlabel, jbutton, jtextfield, jpassword, jtextarea), 구구단만들기, 우편번호 검색기 만들기

eeaarrtthh 2020. 12. 8. 17:24
728x90
반응형

앞으로 배울 내용

화면구성 -> UI(User Interface)
	CUI	- Charater User Interface
		- 명령프롬프트(Terminal)
			dir, ipconfig ...
			입력 : argument, System.in, Scanner
			출력 : System.out
			명령프롬프트는 순차 처리 기반이다.
	GUI	- Graphic User Interface		- VR / AR / XR
			그래픽 도구 - 2D - Graphic 클래스를 이용해서 그린다.
			-> 그래픽클래스를 통해서 모양을 그린다.
			-> 이벤트를 통해서 사용자의 입력을 처리한다.
			GUI는 이벤트 처리 기반이다.

자바에서 GUI를 처리하는 방법(1, 2, 3은 Oracle에서 만들었다.)
1. AWT(Abstract Window Tookit) - 맨 초기
2. Swing - AWT에서 발전된 것
	JFC(Java Foundation Class)
3. Java FX
4. SWT		- IBM에서 만들었다.


SWING 배울내용
	1. layout - widget을 포함할 수 있는 widget
		=> Container
			AWT의 container안에는 Frame, Dialog, Panel 
			Swing은 JFrame, JDialog, JPanel
				-JFrame은 내리기, 최소화, 닫기 버튼이 있는 것, 가장 기본이되는 화면, 애플리케이션당 1개
				-JDialog는 예를들면 메모장의 글꼴처럼 JFrame에 종속되는(자식) 화면을 의미한다.
				-JPanel은 위젯의 그룹(정렬에서 위로, 아래로 같이 정렬안에 위젯 2개가 하나의 묶음으로 있는 것을 의미)
	2. widget - component (특정 그림을 그릴 수 있음)
	3. 순수하게 입력과 출력을 위한 widget 설정
	4. event - 이벤트의 종류

 

 

 

17.1 JavaFx 개요

p850

JavaFX 애플리케이션의 구성요소는 다음과 같다.

레이아웃 : 자바 코드 파일 또는 FXML파일

외관 및 스타일 : CSS 파일

비즈니스 로직 : 자바 코드 파일

리소스 : 그림파일, 동영상 파일

 

SWING을 먼저 배울 것

SWING

- AWT를 확장한 GUI프로그래밍 도구

- AWT보다 더 많은 종류의 컴포넌트를 제공

- OS의 컴포넌트를 사용하지 않고, 순수한 Java로 구현하였다.

 

AWT의 구성은 다음과 같다.

 

SWING의 프로그램은 아래와 같다.

 

 

ㅇ프레임 만들기

package Pack1;

import javax.swing.JFrame;

public class SwingEx1 {

	public static void main(String[] args) {
		//프렘임 생성 (제목넣기)
		JFrame frame = new JFrame( "프레임 타이틀" );
		frame.setTitle( "새로운 타이틀" );
		System.out.println( frame.getTitle() );
		
		//프레임 크기와 위치 설정
		frame.setSize(1024, 768);
		frame.setLocation(100, 100);
		
		//프레임 보이기
		frame.setVisible(true);
	}

}
ㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡㅡ
새로운 타이틀

 

상속을 통해서 프레임 만들기

package Pack1;

import javax.swing.JFrame;

public class JFrameEx1 extends JFrame {
	public JFrameEx1() {
		this.setSize(1024, 768);
		this.setLocation(100, 100);
		this.setTitle("new Frame");
	}

	public static void main(String[] args) {
		JFrameEx1 frame = new JFrameEx1();
		frame.setVisible(true);
	}
}

외부클래스에서 상속받아서 만들기

-UserFrame 외부클래스

package Pack1;

import javax.swing.JFrame;

public class UserFrame extends JFrame {
	public UserFrame() {
		this.setSize(1024, 768);
		this.setLocation(100, 100);
		this.setTitle("new Frame");
	}
}

-실행클래스

package Pack1;

public class JFrameEx2 {

	public static void main(String[] args) {
		UserFrame frame = new UserFrame();
		frame.setVisible( true );

	}
}

 

보통 메인클래스에서 상속받아서 사용하는 것을 주로 사용한다.

이번에는 종료를 구현해보자. 이제 엑스를 누르면 창이 닫히면서 이클립스 실행도 종료된다.

package Pack1;

import javax.swing.JFrame;

public class JFrameEx1 extends JFrame {
	public JFrameEx1() {
		this.setSize(1024, 768);
		this.setLocation(100, 100);
		this.setTitle("new Frame");
		
		//종료
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		JFrameEx1 frame = new JFrameEx1();
		frame.setVisible(true);

	}
}

 

이번에는 위치와 크기를 한 번에 작성하자

package Pack1;

import javax.swing.JFrame;

public class JFrameEx1 extends JFrame {
	public JFrameEx1() {
		this.setBounds(100, 100, 1024, 768);
		//this.setSize(1024, 768);
		//this.setLocation(100, 100);
		this.setTitle("new Frame");
		
		//종료
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
	}

	public static void main(String[] args) {
		JFrameEx1 frame = new JFrameEx1();
		frame.setVisible(true);

	}
}

 

contentPane 사용하기 (JFrame과 같다)

package Pack1;

import java.awt.Color;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class JFrameEx3 extends JFrame {
	private JPanel contentPane;
	
	public JFrameEx3() {
		this.setTitle("New Frame");
		this.setBounds(100, 100, 1024, 768);
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
		
		//JFrame을 contentPane으로 만들기
		contentPane = new JPanel();
		contentPane.setBorder( new EmptyBorder(5, 5, 5, 5));
		this.setContentPane(contentPane);
		
		//배경색 초록색
		contentPane.setBackground( Color.GREEN );
	}

	public static void main(String[] args) {
		JFrameEx3 frame = new JFrameEx3();
		frame.setVisible(true);

	}
}

 

레이아웃과 위젯 추가하기

package Pack1;

import java.awt.Color;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class JFrameEx3 extends JFrame {
	private JPanel contentPane;
	
	public JFrameEx3() {
		this.setTitle("New Frame");
		this.setBounds(100, 100, 1024, 768);
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
		
		//JFrame을 contentPane으로 만들기
		contentPane = new JPanel();
		contentPane.setBorder( new EmptyBorder(5, 5, 5, 5));
		this.setContentPane(contentPane);
		
		//배경색 초록색
		contentPane.setBackground( Color.GREEN );
		
		//contentPane에 레이아웃 정하기 (LayoutManager 클래스 사용)
		//null Layout 사용 (좌표 레이아웃)
		contentPane.setLayout( null );
		
		//위젯 배치 (버튼 추가)
		JButton btn1 = new JButton( "New Button" );
		btn1.setBounds(12, 10, 97, 23);
		contentPane.add( btn1 );
	}

	public static void main(String[] args) {
		JFrameEx3 frame = new JFrameEx3();
		frame.setVisible(true);

	}
}

 

좌표 레이아웃을 사용하면 좌표잡기가 힘들다.

이를 위해서 쉬운 툴을 사용하게 된다.

 

또한 보통 직접적으로 실행하지 않고 쓰레드화 시켜서 실행한다.

package Pack1;

import java.awt.Color;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

public class JFrameEx4 extends JFrame {
	private JPanel contentPane;
	
	public JFrameEx4() {
		this.setTitle("New Frame");
		this.setBounds(100, 100, 1024, 768);
		this.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
		
		//JFrame을 contentPane으로 만들기
		contentPane = new JPanel();
		contentPane.setBorder( new EmptyBorder(5, 5, 5, 5));
		this.setContentPane(contentPane);
		
		//배경색 초록색
		contentPane.setBackground( Color.GREEN );
		
		//contentPane에 레이아웃 정하기 (LayoutManager 클래스 사용)
		//null Layout 사용 (좌표 레이아웃)
		contentPane.setLayout( null );
		
		//위젯 배치 (버튼 추가)
		JButton btn1 = new JButton( "New Button" );
		btn1.setBounds(12, 10, 97, 23);
		contentPane.add( btn1 );
	}

	public static void main(String[] args) {
		//쓰레드화 해서 실행하기
		java.awt.EventQueue.invokeLater( new Runnable() {
			
			@Override
			public void run() {
				try {
					JFrameEx4 frame = new JFrameEx4();
					frame.setVisible(true);
				} catch (Exception e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
			}
		});
	}
}

 

ㅇWindow Builder 사용하기

Swing은 UI구성을 편리하게 하게씀 툴을 제공한다.
- eclipse용 툴(plugin)
- window builder

 

window builder를 설치해보자

eclipse메뉴 help - eclipse market place - 'window builder'검색 

- WindowBuilder 1.9.4 설치 - confirm - "i accept ~" - finish - eclipse 재시작

 

이제 클래스를 만들 때 아래와 같이 만든다.

이름은 아무거나 지정한다.

그리고 아래처럼 Design을 누르면 실제 보면서 코드를 작성할 수 있다.

또한 디자인탭에서 크기를 늘리거나 위젯을 추가하면 소스코드도 자동으로 추가된다.

 

만약 자신이 작성한 코드를 윈도우빌더에서 불러오려면 윈도우빌더의 형식에 맞게 코드를 작성해야한다.

 

라벨을 만들어보자.

이때 라벨2 텍스트에 html구문을 작성할 수 있다.

JLabel lbl2 = new JLabel("<html><body><font color='red'> hello label </font><br><font color='red'> hello label </font></body></html>");

라벨 텍스트에서 엔터키를 치려면 html구문으로 <br>을 써줘야한다.

 

라벨사용목적은 출력이나 안내이다.

라벨의 속성중에서

Variable은 변수명

background는 배경색

font는 글자모양

foreground는 글자색

horizontal은 글자정렬

text는 라벨안에 쓸 내용

icon은 이미지를 넣을 수 있다.

 

 

이번에는 버튼을 사용해보자.

버튼은 사용자의 입력을 만들 수 있다.

버튼을 만든 다음 v자로 체크된 부분을 누르면 버튼객체의 변수를 전역변수로 쓸 것인지 로컬변수로 쓸 것인지 정할 수 있다.

 

버튼을 눌렀을 때 어떤 동작을 하길 원한다면 이벤트를 설정해야 한다.

아래와 같이 버튼에서 오른쪽 클릭을 한다음 이벤트를 생성하자

그리고 소스코드에서 이벤트생성 클래스에 동작을 작성한다.

 

이번에는 btn2 변수명을 가진 JButton을 만들고 클릭하면 "난 클릭됨" 이 출력되도록 버튼을 만들어보자.

 

이번에는 btn1을 누르면 라벨의 내용을 출력해보자.

먼저 라벨의 변수를 전역변수로 만든다.

 

이번에는 라벨을 두 개 만들고 한 개의 라벨은 텍스트값을 설정하고 다른 한 개의 라벨은 텍스트값을 비워놓는다.

그리고 btn2를 누르면 내용이 써져있는 라벨의 텍스트값이 비어져있는 라벨로 들어갈 수 있도록 만들어보자.

이번에는 버튼안에 이미지를 넣어보자.

자바프로젝트안에 아무 이미지를 드래그해서 저장하고 아래와 같이 버튼 icon에서 불러온다.

 

이번에는 버튼 3개를 만든다.( 숨기기 / 보이기 / 타겟 ) 그리고 숨기기버튼을 누르면 타겟버튼은 사라지고

보이기 버튼을 누르면 타겟 버튼이 다시 나타나게 해보자.

이때 타겟의 변수는 전역변수여야한다.

 

이번에는 숨기기버튼을 누르면 타겟버튼을 비활성화되게 만들어보자.

 

이번에는 사용자 입력 텍스트를 만들어보자.

입력을 받기위해서는 3가지가 필요하다.

 

JTextField : 한 줄 입력

JPasswordField : 비밀번호 입력

JTextArea : 여러 줄 입력

텍스트필드에 editable은 쓰기 가능 / 불가능 기능이고 불가능하면 라벨과 비슷해진다.

enable은 사용 / 사용불가와 같다.

 

이번에는 hong gil dong을 대문자 HONG GIL DONG으로 바꿔서 출력하도록 만들어보자.

디자인은 아래와 같다. JPanel은 현재 위젯들을 ctrl로 전체 묶은다음 오른쪽클릭 - surround with - Jpanel(border)를 누르면된다.

이제 구현해보자.

코드는 아래와 같다.

		JButton btn1 = new JButton("\uB300\uBB38\uC790\uB85C \uBCC0\uD658");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				String name = textField1.getText().toUpperCase();
				textField1.setText( "" );
				textField2.setText( name );
			}
		});

 

 

이번에는 PasswordField를 사용해보자.

 

이번에는 여러줄 입력상자를 사용해보자.

 

이번에는 덮어쓰기말고 누적돼서 텍스트를 출력해보자.

 

이번에는 시작단과 끝단을 입력받으면 시작단부터 끝단까지의 구구단을 출력하는 프로그램을 만들어보자.

먼저 TextArea에 스크롤을 만든다.

		JButton btn1 = new JButton("\uAD6C\uAD6C\uB2E8 \uACC4\uC0B0");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				int a = Integer.parseInt( textField1.getText() );
				int b = Integer.parseInt( textField2.getText() );
				
				System.out.println(a);
				System.out.println(b);

				StringBuffer result = new StringBuffer();
				for( int i=1; i<=9; i++) {
					for( int j=a; j<=b; j++) {
						result.append(j + "X" + i + "=" + (j*i) + "\t"); 
					}
					result.append( "\n" );
				}
				textArea.setText( result.toString() );

			}
		});

 

 

이번에는 마리아디비와 연결해서 동이름을 집어넣으면 해당 동 주소가 모두 출력되도록 만들자.

결과는 아래와 같다.

package Pack1;

import java.awt.BorderLayout;
import java.awt.EventQueue;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class ZipcodeUIEx1 extends JFrame {

	private JPanel contentPane;
	private JTextField textField1;
	private JTextArea textArea;

	/**
	 * Launch the application.
	 */
	public static void main(String[] args) {
		EventQueue.invokeLater(new Runnable() {
			public void run() {
				try {
					ZipcodeUIEx1 frame = new ZipcodeUIEx1();
					frame.setVisible(true);
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		});
	}

	/**
	 * Create the frame.
	 */
	public ZipcodeUIEx1() {
		setTitle("\uC8FC\uC18C\uAC80\uC0C9\uD504\uB85C\uADF8\uB7A8");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 649, 486);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(null);
		
		JLabel lblNewLabel = new JLabel("\uB3D9 \uC774\uB984\uC744 \uC801\uC5B4\uC8FC\uC138\uC694 (\uC608\uC2DC: \uC2E0\uC0AC)");
		lblNewLabel.setBounds(12, 10, 450, 15);
		contentPane.add(lblNewLabel);
		
		textField1 = new JTextField();
		textField1.setBounds(12, 32, 450, 21);
		contentPane.add(textField1);
		textField1.setColumns(10);
		
		JButton btn1 = new JButton("\uAC80\uC0C9\uD558\uAE30");
		btn1.addMouseListener(new MouseAdapter() {
			@SuppressWarnings("null")
			@Override
			public void mouseClicked(MouseEvent e) {
				//DB연동에 필요한 api가져오기
				Connection conn = null;
				PreparedStatement pstmt = null;
				ResultSet rs = null;
				
				try {
					//사용자 입력 데이터 가져오기(동 이름)
					String strDong = textField1.getText();
					
					
					//데이터베이스 접속 정보 설정 및 연결하기
					String url = "jdbc:mysql://localhost:3307/sample";
					String user = "root";
					String password = "!123456";
					
					Class.forName( "org.mariadb.jdbc.Driver" );
					conn = DriverManager.getConnection(url, user, password);
					
					//sql문 설정 및 sql문 실행
					String sql = "select * from zipcode where dong like ?";
					
					pstmt = conn.prepareStatement(sql);
					pstmt.setString(1, strDong + "%");
					rs = pstmt.executeQuery();
					
					//sql문 결과값 TextArea에 넘기기
					textArea.setText( "" );		//값 비우기
					while( rs.next() ) {
						textArea.append("["+rs.getString(1)+"] " + 
								rs.getString(2) +" "+ 
								rs.getString(3) +" "+
								rs.getString(4) +" "+ 
								rs.getString(5) +" "+ 
								rs.getString(6) +" "+
								rs.getString(7) +"\n");
					}

					
				} catch (ClassNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (SQLException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} finally {
					if(conn !=null) try {conn.close();} catch(SQLException e1) {}
					if(pstmt !=null) try {pstmt.close();} catch(SQLException e1) {} 
					if(rs !=null) try {rs.close();} catch(SQLException e1) {} 
				}
				
			}
		});
		btn1.setBounds(474, 31, 147, 23);
		contentPane.add(btn1);
		
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(12, 63, 609, 374);
		contentPane.add(scrollPane);
		
		textArea = new JTextArea();
		scrollPane.setViewportView(textArea);
		textArea.setEditable(false);
	}
}

 

728x90
반응형
Comments