일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |
- 노션 데이터베이스
- Notion
- VS Code
- 인라인 데이터베이스
- 노션 텍스트 블록
- visual studio code
- D2Coding
- 노션 하위 페이지
- 노션 데이터베이스 활용
- 전체 페이지 데이터베이스
- 노션 데이터베이스 전환
- D2coding 폰트 다운로드
- 노션
- D2coding 폰트
Crescendo Code
4월 6일 (목) - [JTextArea, JPasswordField, JCheckBox, JRadioButton, DB연동 클래스 분할] 본문
4월 6일 (목) - [JTextArea, JPasswordField, JCheckBox, JRadioButton, DB연동 클래스 분할]
Crecok 2023. 4. 6. 17:39◆ 이전 개념 정리
▶ UI 구축 (목적에 맞게 구성)
- CUI : 명령 프롬프트에서 실행
- GUI : 그래픽이 있는 프로그램
- 2D Graphic의 개념 ( 선/면, 색상, 폰트 ... ) → UI 제작 → GUI
▶ Java로 GUI를 사용할 수 있는 라이브러리
- AWT / Swing
- Java FX
- Swt
▶ AWT / Swing
- 컨테이너 : 뭔가를 담을 수 있는 상자 개념
- Window → JFrame (Frame은 AWT) → JDialog → JPanel
- Layout Manager ( 컨테이너 위에 컴포넌트를 설치 )
- 컴포넌트(위젯)
▶ 디자인 작성 순서
- Window Builder - 이클립스 Plug-in
- Window Builder에서 처리 ( Window Builder답게 코딩. 커스텀 코딩은 해석하지 못할 수도 있음 )
1. 컨테이너 ( JFrame / JDialog )
2. Layout Manager ( null - 좌표중심 배치 )
3. 컴포넌트
4. 이벤트
- 기타
5. 이벤트별 코딩
- 내일 (금) 11시 10분 SQL 퀴즈 + 캡쳐 화면 (SQL) 있을 예정
◆ WindowBuilder 사용 시 주의점
▶ Bounds 속성
- Properties의 Bounds 속성을 누르면 구체적인 좌표와 크기를 조절할 수 있다.
▶ Variable 속성
- 변수 지정시 지역변수 여부를 확인한다.
예제 1. Windowbuilder를 이용하여 아래 그림과 같은 주민등록번호 검사기 프로그램 제작
JButton btn = new JButton( "주민번호검사" );
btn.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
String juminBefore = textField1.getText();
String juminAfter = textField2.getText();
// 입력길이 검사 (O)
// 입력 값 검사 (필요한 작업)
if ( juminBefore.length() != 6 || juminAfter.length() != 7 ) {
lbl.setText( "주민등록번호 양식에 맞춰 입력해주세요" );
textField1.setText( "" );
textField2.setText( "" );
} else {
String strJumin = juminBefore + juminAfter;
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 ) {
lbl.setText( "결과 : 정상" );
} else {
lbl.setText( "결과 : 비정상" );
}
}
}
}
- 코드는 마우스클릭 이벤트 부분만 기재했다.
◆ JTextArea
- 단순 여러 줄 입력
- JLabel을 대신해서 여러 줄 출력이 가능 (많이 사용)
→ TextArea 안에 여러 줄의 데이터 입력 후 Properties의 editable을 false로 지정한다.
- setText() : 기존 내용을 지우면서 작성된 텍스트를 출력한다.
- append() : 기존 내용에 추가하여 작성된 텍스트를 출력한다.
- textArea.append( "new text" + System.lineSeparator() ) 와 같이 줄바꿈을 적용 할 수도 있다.
▶ scollPane (스크롤바) 추가
- 스크롤바를 추가하면 scrollPane 항목이 생긴다.
- horizontalScrollBarPolicy와 verticalScrollBarPolicy의 옵션값을 ALWAYS로 바꾸면 스크롤바를 항시 표시할 수 있다.
▶ JPanel (border) 추가
- 영역을 지정할 컴포넌트들을 그룹으로 선택한 뒤 JPanel을 적용하면 선택 영역을 그룹으로 묶을 수 있다.
예제 2. WindowBuilder와 소스코드를 이용하여 시작단과 끝단 입력 시 조건에 따라 구구단이 출력되는 프로그램 제작
JButton btnNewButton = new JButton("구구단 출력");
btnNewButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
int startDan = Integer.parseInt(textField1.getText());
int endDan = Integer.parseInt(textField2.getText());
// 버튼 반복 사용을 위한 내용 초기화
textArea.setText("");
for (int i=startDan; i<=endDan; i++) {
for (int j=1; j<=9; j++) {
textArea.append( i + "x" + j + "=" + i*j + "\t" );
}
textArea.append( "" + System.lineSeparator() );
}
}
});
- 코드는 마우스클릭 이벤트 부분만 기재했다.
▶ 외부 파일을 불러올 때 WindowBuilder 화면을 여는 방법
- FileZilia - Java - Java - 강의 - JTextAreaEx03.java 자료 활용
예제 3. WindowBuilder와 DB 안의 주소록 데이터를 이용해 우편번호 검색기 프로그램 제작
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();
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, strDong+"%");
rs = pstmt.executeQuery();
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) {
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) {}
}
}
}
});
- 코드는 마우스클릭 이벤트 부분만 기재했다.
◆ 클래스의 역할 분리
1. 한 개의 클래스로 잘게 쪼개서 사용
2. 분리 (pattern)
- DAO, TO → MVC ( Model / View / Controller )
- Model : 데이터 ( DAO - 데이터 연결 / DTO - 데이터 전송 )
- View : 디자인 (UI)
- Controller : 흐름제어
- DTO : Select 문과 1:1
- DAO : 생성자에서 DB와 연결 / SQL 1개당 메서드 1개
Q. 위 우편번호 검색기 프로그램을 3개의 클래스로 나눠서 작업
1. ZipcodeTO 클래스
public class ZipcodeTO {
private String zipcode;
private String sido;
private String gugun;
private String dong;
private String ri;
private String bunji;
private String seq;
public String getZipcode() {
return zipcode;
}
public void setZipcode(String zipcode) {
this.zipcode = zipcode;
}
public String getSido() {
return sido;
}
public void setSido(String sido) {
this.sido = sido;
}
public String getGugun() {
return gugun;
}
public void setGugun(String gugun) {
this.gugun = gugun;
}
public String getDong() {
return dong;
}
public void setDong(String dong) {
this.dong = dong;
}
public String getRi() {
return ri;
}
public void setRi(String ri) {
this.ri = ri;
}
public String getBunji() {
return bunji;
}
public void setBunji(String bunji) {
this.bunji = bunji;
}
public String getSeq() {
return seq;
}
public void setSeq(String seq) {
this.seq = seq;
}
}
2. ZipcodeDAO 클래스
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 {
private Connection conn;
public ZipcodeDAO() {
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) {
System.out.println( "[에러] " + e.getMessage() );
} catch (SQLException e) {
System.out.println( "[에러] " + e.getMessage() );
}
}
public ArrayList<ZipcodeTO> searchZipcode( String strDong ){
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) {
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;
}
}
3. AddressEx02 클래스
import java.awt.EventQueue;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Scanner;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import java.awt.Color;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class AddressEx02 extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JTextArea textArea;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
AddressEx02 frame = new AddressEx02();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public AddressEx02() {
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 800, 600);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, new Color(255, 255, 255), new Color(160, 160, 160)), "\uC6B0\uD3B8\uBC88\uD638 \uD0D0\uC0C9\uAE30", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
panel.setBounds(16, 20, 745, 69);
contentPane.add(panel);
panel.setLayout(null);
textField = new JTextField();
textField.setBounds(25, 25, 516, 21);
panel.add(textField);
textField.setColumns(10);
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(553, 24, 176, 23);
panel.add(btn);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(22, 105, 738, 446);
contentPane.add(scrollPane);
textArea = new JTextArea();
scrollPane.setViewportView(textArea);
}
}
◆ JPasswordField
- echoChar 옵션으로 비밀번호를 가릴 문자를 지정할 수 있다.
Q. JPasswordField 데이터 확인하기
System.out.println( new String( passwordField.getPassword() ) );
- JPasswordField는 보이지 않을 뿐 암호화된 것은 아니다.
◆ JCheckBox
Q. 아래와 같이 체크박스를 설정한다.
Q. 체크된 목록 ( True / False 여부 ), 체크박스의 이름을 출력
public void mouseClicked(MouseEvent e) {
System.out.println( chckbx1.isSelected() );
System.out.println( chckbx2.isSelected() );
System.out.println( chckbx3.isSelected() );
System.out.println( chckbx1.getText() );
System.out.println( chckbx2.getText() );
System.out.println( chckbx3.getText() );
}
Q. 체크된 목록만 이름을 출력하는 소스를 작성
public void mouseClicked(MouseEvent e) {
String result = "";
if( chckbx1.isSelected() ) result += chckbx1.getText() + " ";
if( chckbx2.isSelected() ) result += chckbx2.getText() + " ";
if( chckbx3.isSelected() ) result += chckbx3.getText() + " ";
System.out.println( "결과 : " + result );
}
Q. 전체 선택, 전체 해제 버튼을 만들고 그 기능을 구현
public void mouseClicked(MouseEvent e) {
chckbx1.setSelected(true);
chckbx2.setSelected(true);
chckbx3.setSelected(true);
}
public void mouseClicked(MouseEvent e) {
chckbx1.setSelected(false);
chckbx2.setSelected(false);
chckbx3.setSelected(false);
}
Q. 버튼을 추가하고 클릭마다 '전체 선택', '전체 해제' 문구가 바뀌는 버튼을 구현
public void mouseClicked(MouseEvent e) {
if( btn3.getText().equals( "전체 선택" ) ) {
btn3.setText( "전체 해제" );
} else {
btn3.setText( "전체 선택" );
}
}
◆ JRadioButton
Q. RadioButton 3개를 그룹화하여 단일 선택 버튼으로 만들기
Q. 새 버튼을 클릭하면 체크된 RadioButton에 해당하는 이름을 출력
public void mouseClicked(MouseEvent e) {
String result = "";
if( rdbtn1.isSelected() ) System.out.println(rdbtn1.getText());
if( rdbtn2.isSelected() ) System.out.println(rdbtn2.getText());
if( rdbtn3.isSelected() ) System.out.println(rdbtn3.getText());
}
예제 4. 부서이름 검색기 ( 출력 : 부서번호, 부서위치, 사원번호, 사원이름, 직책, 급여 )
- DAO / TO / 실행클래스 총 3개를 만들어서 제작
1. DepfSearchTO 클래스
public class DeptSearchTO {
private String deptno;
private String loc;
private String empno;
private String ename;
private String job;
private String sal;
public String getDeptno() {
return deptno;
}
public void setDeptno(String deptno) {
this.deptno = deptno;
}
public String getLoc() {
return loc;
}
public void setLoc(String loc) {
this.loc = loc;
}
public String getEmpno() {
return empno;
}
public void setEmpno(String empno) {
this.empno = empno;
}
public String getEname() {
return ename;
}
public void setEname(String ename) {
this.ename = ename;
}
public String getJob() {
return job;
}
public void setJob(String job) {
this.job = job;
}
public String getSal() {
return sal;
}
public void setSal(String sal) {
this.sal = sal;
}
}
2. DeptSearchDAO 클래스
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 DeptSearchDAO {
private Connection conn;
public DeptSearchDAO() {
String url = "jdbc:mariadb://localhost:3306/sample";
String user = "root";
String password = "123456";
try {
Class.forName( "org.mariadb.jdbc.Driver" );
this.conn = DriverManager.getConnection( url, user, password );
} catch (ClassNotFoundException e) {
System.out.println( "[에러] " + e.getMessage() );
} catch (SQLException e) {
System.out.println( "[에러] " + e.getMessage() );
}
}
public ArrayList<DeptSearchTO> searchZipcode( String strDept ){
PreparedStatement pstmt = null;
ResultSet rs = null;
ArrayList<DeptSearchTO> depts = new ArrayList<>();
try {
String sql = "select e.empno, e.ename, e.job, e.sal, e.deptno, d.loc from ( select * from dept where dname like ? ) d inner join emp e on (d.deptno = e.deptno);";
pstmt = this.conn.prepareStatement( sql );
pstmt.setString( 1, "%" + strDept + "%" );
rs = pstmt.executeQuery();
while( rs.next() ) {
DeptSearchTO to = new DeptSearchTO();
to.setEmpno( rs.getString( "empno") );
to.setEname( rs.getString( "ename") );
to.setJob( rs.getString( "job") );
to.setSal( rs.getString( "sal") );
to.setDeptno( rs.getString( "deptno") );
to.setLoc( rs.getString( "loc") );
depts.add( to );
}
} catch (SQLException e) {
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 depts;
}
}
3. DeptSearchEx01 클래스
import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JTextField;
import javax.swing.JButton;
import javax.swing.border.TitledBorder;
import javax.swing.border.EtchedBorder;
import java.awt.Color;
import javax.swing.JTextArea;
import javax.swing.JScrollPane;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
public class DeptSearchEx01 extends JFrame {
private JPanel contentPane;
private JTextField textField;
private JTextArea textArea;
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
DeptSearchEx01 frame = new DeptSearchEx01();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
/**
* Create the frame.
*/
public DeptSearchEx01() {
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 800, 600);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JPanel panel = new JPanel();
panel.setBorder(new TitledBorder(new EtchedBorder(EtchedBorder.LOWERED, new Color(255, 255, 255), new Color(160, 160, 160)), "\uBD80\uC11C\uC774\uB984 \uAC80\uC0C9", TitledBorder.LEADING, TitledBorder.TOP, null, new Color(0, 0, 0)));
panel.setBounds(16, 24, 741, 53);
contentPane.add(panel);
panel.setLayout(null);
textField = new JTextField();
textField.setBounds(25, 18, 552, 21);
panel.add(textField);
textField.setColumns(10);
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 strDept = textField.getText().trim();
DeptSearchDAO dao = new DeptSearchDAO();
ArrayList<DeptSearchTO> depts = dao.searchZipcode( strDept );
for( DeptSearchTO to : depts ) {
String dept = String.format( "%s %s %s %s %s %s",
to.getEmpno(), to.getEname(), to.getJob(),
to.getSal(), to.getDeptno(), to.getLoc() );
textArea.append( dept + System.lineSeparator() );
}
}
}
});
btn.setBounds(589, 17, 134, 23);
panel.add(btn);
JScrollPane scrollPane = new JScrollPane();
scrollPane.setBounds(26, 91, 727, 460);
contentPane.add(scrollPane);
textArea = new JTextArea();
scrollPane.setViewportView(textArea);
}
}
'KIC 백엔드 수업' 카테고리의 다른 글
4월 10일 (월) - [JTable, DAO, TO] (0) | 2023.04.10 |
---|---|
4월 7일 (금) - [] (0) | 2023.04.07 |
4월 5일 (수) - [UI] (0) | 2023.04.05 |
4월 4일 (화) - [] (0) | 2023.04.04 |
4월 3일 (월) - [] (0) | 2023.04.03 |