23.04.06

이준영·2023년 4월 6일
0

🍡 UI

CUI - 명령 프롬포트에서 실행되는 프로그램
GUI - 그래픽이 있는 프로그램 (2D 그래픽 : 선 / 면, 색상, 폰트 등)



AWT / Swing

컨테이너
Window > (J)Frame : J가 없으면 AWT > JDialog > JPanel +Layout Manager

컴포넌트(위젯)
JLabel ,,, 등


🍡 WindowBuilder 작업 순서 (이클립스 plug - in)

  1. 컨테이너(JFrame / JDialog)

  2. Layout Manager (디폴트 null) - 좌표중심 배치

  3. 컴포넌트

  4. 이벤트

  5. 이벤트별 코딩



🍡 빠른 검사

저 부분을 클릭하면 빠르게 실행된다. (그냥 디자인 검사만!, 코드 추가하고 실행해도 적용 안됨)



🍡 응용 : 주민등록번호 검사기 GUI로 만들어 보기

TIP! : gettext, settext를 잘 사용하기

JButton btn1 = new JButton("주민번호 검사");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				String jumin1 = text1.getText();
				String jumin2 = text2.getText();
				
				if(jumin1.length() != 6 && jumin2.length() != 7) {
					lbl1.setText("결과 : 올바른 주민등록번호가 아닙니다!");
					//에러 띄우고 안에 내용 지우기
					text1.setText("");
					text2.setText("");
				}
				else {
					String strJumin = jumin1 + jumin2;
					
					int[] bits = {2, 3, 4, 5, 6, 7, 8, 9, 2, 3, 4, 5};
					int sum = 0;
					for(int i = 0; i < bits.length; i++) {
						sum += Integer.parseInt(strJumin.substring(i, i+1)) * bits[i];
					}
					
					int resultNum = (11 - (sum % 11)) % 10;
					int lastNum = Integer.parseInt(strJumin.substring(12, 13));
					
					if(lastNum == resultNum) {
						lbl1.setText("정상 입력");
					}
					else {
						lbl1.setText("비정상 입력");
					}
				}
			}
		});

  1. 누르면 밑에 라벨에 결과가 뜨는 구조라 이벤트 클릭 코드쪽에서 작업해줘야 한다.
  2. gettext/ settext를 잘 사용하여 코드 짜기!



🍡 JTextArea

  1. 여러줄 입력시 사용

  2. JLabel 한계점(여러 줄 입력하려면 html 사용하는 단점)
    -> JLabel 여러줄 출력할때 사용 (대충 입력하고, editable을 꺼주면 여러줄 라벨 효과를 낼 수 있다) - 더 많이 사용



🍡 text 메서드


default값

🔽


◽ setText() = 안의 내용 지운 다음에 () 내용 쓰기

JButton btn = new JButton("버튼");
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				textArea.setText("setText 사용");
			}
		});


◽ append() = 뒤에 () 내용 추가, lineseparator은 \n 기능

JButton btn = new JButton("버튼");
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				textArea.append("setText 사용");
			}
		});




🍡 surround with : JScrollPane



scrollPane = new JScrollPane();
		scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
		scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_ALWAYS);
		scrollPane.setBounds(12, 10, 209, 69);
		contentPane.add(scrollPane)

  1. 사용할 디자인에 우클릭 -> surround with -> scroll 부분 클릭하면 scrollPane 안에 디자인(textArea)가 들어가는 모습

  2. horizontal~~ / vertical~~ 부분에서 설정가능
    ( 필요시(need) , x(never), 항상 기능(always) )



3. scroll이 적용된 모습




🍡 surround with : JPanel (border)



이런식으로 틀을 잡아줌


panel안에 디자인들이 들어가 있는 것을 확인할 수 있음.

틀의 이름은 panel 클릭 -> border ...부분에서 바꿀 수 있다.




🍡 응용2 - 구구단 출력기 만들기


JButton btn1 = new JButton("구구단 출력");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				String dan1 = text1.getText();
				String dan2 = text2.getText();
				
				if(dan1.length() < 1 | dan2.length() < 1) {
					textArea.setText("하나 이상의 숫자를 입력하세요!!");
				}
				else {
					int Idan1 = Integer.parseInt(dan1);
					int Idan2 = Integer.parseInt(dan2);
					
                    //초기화 -> 새로 입력할 때마다 append 되는 것 방지하기 위함!
                    textArea.setText("");
                    
					for(int cols = Idan1; cols <= Idan2; cols++) {
						for(int rows = 1; rows <= 9; rows++ ) {
							System.out.println(cols +  " X " + rows + " = " + (cols * rows));
							textArea.append(cols +  " X " + rows + " = " + (cols * rows) + "\n");
						}
						textArea.append("\n");
					}
				}
			}
		});
		btn1.setBounds(260, 17, 108, 47);
		panel.add(btn1);

주의!!! setText가 아니라 append로 반복문 붙여줘야함! setText는 새로 만들기 때문에 마지막 결과만 보여줌!



🍡 응용3 - 우편번호 검색기(DB연동) : GUI로 만들어보기


JButton btn = new JButton("우편번호 검색");
		btn.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				String url = "jdbc:mariadb://localhost:3306/project";
				String user = "project";
				String password = "1234";

				Connection conn = null;
				PreparedStatement pstmt = null;
				ResultSet rs = null;

				try {
					Class.forName("org.mariadb.jdbc.Driver");

					conn = DriverManager.getConnection(url, user, password);

					String sql = "select zipcode, sido, gugun, dong, ri, bunji from zipcode where dong like ?";

					pstmt = conn.prepareStatement(sql);

					pstmt.setString(1, text1.getText() + "%");

					rs = pstmt.executeQuery();

					if (text1.getText().length() < 2) {
						textArea.setText("두 글자 이상 입력하세요!");
					} else {
						
						textArea.setText("");
						
						while (rs.next()) {
							String zipcode = rs.getString("zipcode");
							String sido = rs.getString("sido");
							String gugun = rs.getString("gugun");
							String dong = rs.getString("dong");
							String ri = rs.getString("ri");
							String bunji = rs.getString("bunji");
							
							String address = String.format("[%s] %s %s %s %s %s",zipcode,
									sido, gugun, dong, ri, bunji);
							
							textArea.append(address + System.lineSeparator());
                        
						}
					}
				} catch (ClassNotFoundException e1) {  --> 이벤트에서 e를 사용하고 있어서 
                변수 중복 자동으로 계산해서 e1으로 바뀐 것
					System.out.println("[에러]" + e1.getMessage());
				} catch (SQLException e1) {
					System.out.println("[에러]" + e1.getMessage());
				} finally { 
                if(rs != null) try { rs.close(); } catch (SQLException e1) {}
                if(pstmt != null) try { pstmt.close(); } catch (SQLException e1) {}
                if(conn != null) try { conn.close(); } catch (SQLException e1) {}
				}
			}

		});
		btn.setBounds(337, 17, 97, 23);
		panel.add(btn);



🍡 클래스의 역할 분리

  1. 한개 클래스
  2. 분리(pattern) : DAO, TO => MVC(Model View Controller)
    Model - 데이터(DAO - 연결 / DTO - 데이터 전송)
    View - 디자인(UI)
    Controller - 흐름제어

🍡 DAO(Data Access Object)

생성자에서 데이터베이스 연결
sql문 한 개당 메서드 하나(기능별로 나눠씀 : pattern)
데이터베이스의 data에 접근하기 위한 객체


🍡 DTO(Data Transfer Object)

Select문(테이블)과 1 : 1 (join 쓸 경우 달라질 수 있음)
계층간 데이터 교환 위해 사용하는 객체
로직을 가지지 않는 순수한 데이터 객체(Getter & Setter만 가진 클래스)이다.


🍡 VO(Value Object)

값 오브젝트로 값을 위해 쓰임
read-Only 특징(사용하는 도중에 변경 불가능하며 오직 읽기만 가능)을 가진다.
DTO와 유사하지만 DTO는 setter를 가지고 있어 값이 변할 수 있음

Client = view로 보기



🍡 응용3번 문제 클래스 분리하여 쓰기

  1. ZipcodeTO 클래스 만들어서 필드, getter / setter 만들기 (DTO)
public class ZipcodeTO {
	private String zipcode;
	private String sido;
	private String gugun;
	private String dong;
	private String ri;
	private String bunji;
	private String seq;
	
	너무 길어서 안만들었음. 필드변수들 getter / setter 만들어 주기
}

  1. ZipcodeDAO 클래스 만들어서 DB에서 데이터 가져오는 프로그램 만들기 (DAO)
    이 과정으로 ArrayList 타입의 addresses 변수에 db에서 가져온 select요소들이 전부 들어가있는 것이고, like 조건을 통하여 원하는 정보를 뽑을 수 있게끔 만들어 짐 -> 후에 gui 메인 클래스에서 String strDong의 매개변수를 통해 호출하여 실행하고, addresses를 반환해줘서 사용하게끔 함
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;

public class ZipcodeDAO {
	// Data Access Object;
	private Connection conn;
	
	public ZipcodeDAO() {   --> 생성자에서 DB 연결
		// TODO Auto-generated constructor stub
		
		String url = "jdbc:mariadb://localhost:3306/project";
		String user = "project";
		String password = "1234";
		
		try {
			Class.forName( "org.mariadb.jdbc.Driver" );
			this.conn = DriverManager.getConnection( url, user, password );
		} catch (ClassNotFoundException e) {
			// TODO Auto-generated catch block
			System.out.println( "[에러] " + e.getMessage() );
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println( "[에러] " + e.getMessage() );
		}
		
	}
	
	public ArrayList<ZipcodeTO> searchZipcode( String strDong ) { --> DB Select문 사용하는 메서드 만들기
		
		PreparedStatement pstmt = null;
		ResultSet rs = null;
		
		ArrayList<ZipcodeTO> addresses = new ArrayList<>();
		
		try {
			String sql = "select zipcode, sido, gugun, dong, ri, bunji from zipcode where dong like ?";
			pstmt = this.conn.prepareStatement( sql );
			pstmt.setString( 1, strDong + "%" );
			
			rs = pstmt.executeQuery();
			while(rs.next()) {
				ZipcodeTO to = new ZipcodeTO();
				to.setZipcode( rs.getString( "zipcode" ) );
				to.setSido( rs.getString( "sido" ) );
				to.setGugun( rs.getString( "gugun" ) );
				to.setDong( rs.getString( "dong" ) );
				to.setRi( rs.getString( "ri" ) );
				to.setBunji( rs.getString( "bunji" ) );
				
				addresses.add( to );
			}
		} catch (SQLException e) {
			// TODO Auto-generated catch block
			System.out.println( "[에러] " + e.getMessage() );
		} finally {
			if( rs != null ) try { rs.close(); } catch( SQLException e ) {}
			if( pstmt != null ) try { pstmt.close(); } catch( SQLException e ) {}
			if( conn != null ) try { conn.close(); } catch( SQLException e ) {}			
		}
		
		return addresses;
		
	}
}

  1. 메인 GUI에서 버튼 클릭시 작용하게 하기 (디자인 소스 생략하고 버튼 클릭 부분만 가져옴)
    이 과정에서 strDong 변수를 만들고 ZipcodeDAO 타입으로 dao 객체 생성하여 addresses가 dao.searchZipcode( strDong ) 값을 받게한다( = searchZipcode의 리턴값 addresses가 리턴되어 들어감), 받은 값으로 for문을 통하여 검색 시에 원하는 정보(select 정보들의 where dong like ? 값)를 얻을 수 있음

JButton btn = new JButton( "우편번호 검색" );
		btn.addMouseListener( new MouseAdapter() {
			@Override
			public void mouseClicked( MouseEvent e ) {
				
				if( textField.getText().trim().length() < 2 ) {
					textArea.setText( "동이름을 두자 이상 입력하셔야 합니다" );
				} else {
					textArea.setText("");
					
					String strDong = textField.getText().trim();
					
					ZipcodeDAO dao = new ZipcodeDAO();
					ArrayList<ZipcodeTO> addresses = dao.searchZipcode( strDong );
					
					for( ZipcodeTO to : addresses ) {
						String address = String.format( "[%s] %s %s %s %s %s",
							to.getZipcode(), to.getSido(), to.getGugun(),
							to.getDong(), to.getRi(), to.getBunji() );
						
						textArea.append( address + System.lineSeparator() );
					}
					
				}
				
			}
		});
		btn.setBounds( 443, 33, 117, 23 );
		panel.add( btn );



🍡 JPasswordField : 비밀번호 텍스트



echoChar : 비밀번호 입력할 때 나오는 도형

에코케어 바뀐 모습 (*로)



값 가져올 때 getText로 가져오는 것이 아닌 아래 메서드를 사용하여 가져옴


값 출력되는 모습( 암호화 아님! 안 보이는 것 뿐)



🍡 JCheckbox


select = true면 선택되어 나옴 / false면 비선택
text = 체크박스 내용



🍡 isSelected

선택 유무를 true/false로 반환해 준다.

		JButton btn1 = new JButton("결과");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				System.out.println(checkbox1.isSelected());
				System.out.println(checkbox2.isSelected());
				System.out.println(checkbox3.isSelected());
			}
		});



🍡 getText

	JButton btn1 = new JButton("결과");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				
				System.out.println(checkbox1.getText());
				System.out.println(checkbox2.getText());
				System.out.println(checkbox3.getText());
			}
		});


getText는 체크 유무와 상관없이 무조건 값 가져옴



🍡 체크된 박스만 가져오기

		JButton btn1 = new JButton("결과");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				String result = "";
				if(checkbox1.isSelected()) result += checkbox1.getText() + " ";
				if(checkbox2.isSelected()) result += checkbox2.getText() + " ";
				if(checkbox3.isSelected()) result += checkbox3.getText() + " ";
				
				System.out.println("결과 : " + result);
			}
		});



🍡 전체선택 / 전체해제

btn2 = new JButton("전체 선택");
		btn2.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				checkbox1.setSelected(true);
				checkbox2.setSelected(true);
				checkbox3.setSelected(true);
			}
		});
		btn2.setBounds(8, 10, 97, 23);
		contentPane.add(btn2);
		
		btn3 = new JButton("전체 해제");
		btn3.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				checkbox1.setSelected(false);
				checkbox2.setSelected(false);
				checkbox3.setSelected(false);
			}
		});
		btn3.setBounds(8, 62, 97, 23);
		contentPane.add(btn3);

전체선택 누르면 모두 선택되고, 해제 누르면 전부 해제됨




🍡 버튼 클릭하면 버튼 이름 바꾸기

		btn4 = new JButton("전체선택");
		btn4.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if(btn4.getText().equals("전체선택")) {
					btn4.setText("전체해제");
				}
				else {
					btn4.setText("전체선택");
				}
			}
		});
		btn4.setBounds(8, 63, 97, 23);
		contentPane.add(btn4);


전체선택 - 전체해제로 누를 때마다 내용(이름)이 바뀐다.




🍡 단일 선택 : JRadioButton

체크박스와 다르게 단일 선택 되는 버튼


체크박스와 똑같이 selected 누름에 따라 선택되어 나옴
isselected 체크 박스와 동일함

radiobox 전부 잡고 오른쪽 클릭 -> Set Buttongroup -> New Standard 해줘야 단일 적용된다.

누르면 이런 소스코드가 추가됨(단일 적용해주는 소스코드)



🍡 선택한 내용 출력

		JButton btn1 = new JButton("버튼");
		btn1.addMouseListener(new MouseAdapter() {
			@Override
			public void mouseClicked(MouseEvent e) {
				if(radio1.isSelected()) {
					System.out.println(radio1.getText());
				}
				else if (radio2.isSelected()) {
					System.out.println(radio2.getText());
				}
				else if (radio3.isSelected()) {
					System.out.println(radio3.getText());
				}
			}
		});
		btn1.setBounds(8, 85, 97, 23);
		contentPane.add(btn1);



🍡 응용 4 - 부서이름 검색기 만들기!


아까 클래스 분리 부분이랑 똑같다 (select 에 join 쓰는 거 빼곤 똑같음)
profile
끄적끄적

0개의 댓글