해당 클래스를 출, 퇴근 프로그램으로 변경하시오.
출근처리를 눌렀을 떄, 출근시간이 입력되고, 퇴근처리를 눌렀을 때 퇴근 시간이 입력되어야 한다.
출근 처리를 눌렀을 떄 -> 퇴근시간이 동시에 작성되면 안 된다.
출근 시간 -> 눌렀을 때, 현재 출근시간
퇴근 시간 -> 눌렀을 때, 현재 퇴근시간 입력
package com.step5;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.JToolBar;
/*
* 이벤트 처리 3단계
* 1.JTextField가 지원하는 이벤트 처리 담당 클래스를 implements한다.
* 2.1번에서 추가된 이벤트 처리 담당 클래스가 선언하고 있는 actionPerformed메소드를 재정의 해야함.
* 3.이벤트 소스(이벤트 처리 대상 클래스의 주소번지)와 이벤트 처리를 담당하는 클래스를 연결하기
*/
public class BaseBallGameView extends JFrame implements ActionListener{
JFrame jf = new JFrame();
//이미지를 담은 물리적인 위치 선언하기.
String imgPath = "D:\\workspace_java\\dev_java\\src\\com\\week2\\";
// ImageIcon titleIcon = new ImageIcon(imgPath+"yagu.png");
//ImageIcon bg = new ImageIcon(imgPath+"dreamballpark.jpg");
Image img = null;
JMenuBar jmb = new JMenuBar();
JMenu jm_game = new JMenu("게임");
JMenuItem jmi_new = new JMenuItem("새게임");
JMenuItem jmi_dap = new JMenuItem("정답");
JMenuItem jmi_clear = new JMenuItem("지우기");
JMenuItem jmi_exit = new JMenuItem("나가기");
JMenu jm_info = new JMenu("도움말");
JMenuItem jmi_detail = new JMenuItem("야구숫자게임이란?");
JMenuItem jmi_create = new JMenuItem("만든사람들");
//중앙에 들어갈 속지 선언
JPanel jp_center = new JPanel();
//세자리 숫자를 입력 후 엔터를 쳤을때 사용자가 입력한 숫자와 숫자를 맞추기 위한 힌트문
//을 출력해줄 화면.
JTextArea jta_display = null;
JScrollPane jsp_display = new JScrollPane(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JTextField jtf_user = new JTextField();
//글꼴과 글꼴에 대한 스타일과 글자 크기를 정해줌.-인스턴스화를 통해서, 그 값들은 생성자의 파라미터로 결정됨
Font f = new Font("Thoma",Font.BOLD,14);
//동쪽에 들어갈 속지 생성하기
JPanel jp_east = new JPanel();
//새게임, 정답, 지우기, 나가기 버튼 추가하기
JButton jbtn_new = new JButton("새게임");
JButton jbtn_dap = new JButton("정답");
JButton jbtn_clear = new JButton("지우기");
JButton jbtn_exit = new JButton("나가기");
int my[] = new int[3];
int com[] = new int[3];
int cnt = 0;//++cnt 힌트 문장에서 순번을 출력하는 변수
//생성자 선언하기
BaseBallGameView(){
ranCom();//이 메소드 딱 한번만 호출된다.
}
//세자리 임의의 숫자를 채번하는 메소드 구현하기
public void ranCom() {
Random r = new Random();
//첫번째 자리는 중복검사가 필요없다
com[0] = r.nextInt(10);
//while문과는 다르게 무조건 한번은 실행됨
do {
com[1] = r.nextInt(10);
}while(com[0]==com[1]);//중복된 숫자이면 계속 돌아라
do {
com[2] = r.nextInt(10);
}while((com[0]==com[2]) || (com[2]==com[1]));//중복된 숫자이면 계속 돌아라
}
//사용자가 입력한 값을 판정하는 메소드를 구현해 봅시다.
public String account(String user) {
if(user.length()!=3) {//length명사형은 배열의 원소의 수반환. length()동사형은 문자열의 길이를 반환함
return "세자리 숫자를 입력하세요.";
}
//사용자가 jtf_user에 입력한 숫자는 보기에는 숫자 처럼 보여도 알맹이는 문자열로
//인식을 합니다. 그래서 형전환을 한 후 my[]배열에 담아야 함니다.
//문자열 "256"을 숫자로 담을 변수 선언
int temp = 0;
int strike = 0;//힌트로 사용될 스트라이크를 담을 변수 선언
int ball = 0;//볼을 담을 변수 선언
//strike와ball을 지역변수로 해야 하는건 매 회차 마다 값이 변해야 하기 때문이다.
try {
temp = Integer.parseInt(user);//안녕 - NumberFormatException발생
} catch (NumberFormatException e) {
return "숫자만 입력하세요.";
}
my[0] = temp/100;//256/100=> 2.56 -> 2만 담김
my[1] = (temp%100)/10;//십의자리 - 몫 2 나머지 56-> 5.6 -> 5만 담김
my[2] = temp%10;//몫: 25 - 6만담김
//이 중 for 문 사용해서 자리는 다르더라도 그 숫자가 존재하니? 네-> ball확보됨
//네 일때 다시 한번 i ==j가 같은지 비교해서 index값 마저도 동일하면 자리까지도 일치함 - strike++
for(int i=0;i<3;i++) {//9가지 경우의 수가 발생
for(int j=0;j<3;j++) {
if(com[i] == my[j]) {//그 숫자가 존재하니? 네 -ball확보
if(i==j) {//자리값도 일치하는 거야? 네 -strike결정됨
strike++;
}else {//숫자는 있지만 자리는 달라요
ball++;
}
}//end of if
}/// end of inner for
}//////end of outter for
return strike+"스 "+ball+"볼";
}
//나가기 버튼이나 나가기 메뉴 아이템을 선택(클릭)했을때 호출되는 메소드 구현
public void exit() {
System.exit(0);
}
//화면을 그려주는 메소드 선언
public void initDisplay() {
jta_display = new JTextArea();
jsp_display = new JScrollPane(jta_display);
jta_display.setOpaque(false);
jf.setResizable(false);
//jf.setContentPane(new BgPanel());
//////////////// 툴바에 들어갈 이미지 버튼 추가하기 ///////////////
//////////////// 메뉴 바 추가 시작 /////////////////
jm_game.add(jmi_new);
jm_game.add(jmi_dap);
jm_game.add(jmi_clear);
jm_game.add(jmi_exit);
jm_info.add(jmi_detail);
jm_info.add(jmi_create);
jmb.add(jm_game);
jmb.add(jm_info);
//////////////// 메뉴 바 추가 끝 /////////////////
System.out.println("initDisplay 호출 성공");
//이벤트 소스와 이벤트 처리 클래스를 매핑하는 코드 추가
//EventHandler ehandler = new EventHandler();
//jtf_user.addActionListener(ehandler);//여기서 this는 자기자신 클래스를 가리킴.-BaseBallGame:내안에 actionPerformed
jtf_user.addActionListener(this);//여기서 this는 자기자신 클래스를 가리킴.-BaseBallGame:내안에 actionPerformed
jbtn_new.addActionListener(this);
jbtn_dap.addActionListener(this);
jbtn_clear.addActionListener(this);
jbtn_exit.addActionListener(this);
jmi_exit.addActionListener(this);
jbtn_new.setBackground(new Color(158,9,9));
jbtn_new.setForeground(new Color(212,212,212));
jbtn_dap.setBackground(new Color(7,84,170));
jbtn_dap.setForeground(new Color(212,212,212));
jbtn_clear.setBackground(new Color(19,99,57));
jbtn_clear.setForeground(new Color(212,212,212));
jbtn_exit.setBackground(new Color(54,54,54));
jbtn_exit.setForeground(new Color(212,212,212));
jp_east.setLayout(new GridLayout(4,1));
jp_east.add(jbtn_new);
jp_east.add(jbtn_dap);
jp_east.add(jbtn_clear);
jp_east.add(jbtn_exit);
jta_display.setFont(f);
jta_display.setBackground(new Color(255,255,200));
jta_display.setForeground(new Color(57,109,165));
jf.setJMenuBar(jmb);
jtf_user.setBackground(new Color(255,255,200));
jp_center.setBackground(Color.green);
jp_east.setBackground(Color.black);
jp_center.setLayout(new BorderLayout(0,10));
jp_center.add("Center",jsp_display);
jp_center.add("South",jtf_user);
jta_display.setLineWrap(true);
jf.setLayout(new BorderLayout(10,20));
jf.add("Center",jp_center);
jf.add("East",jp_east);
jf.setTitle("야구 숫자 게임 Ver1.0");
jf.setSize(400, 300);
jf.setVisible(true);
}
public static void main(String[] args) {
BaseBallGameView bbGame = new BaseBallGameView();
bbGame.initDisplay();
}
////////jtf_user에 엔터를 쳤을 때 , jbtn_exit버튼을 클릭했을때 이벤트 지원하는 인터페이스가 ActionListener이다.
//ActionListener는 반드시 actionPerformed를 재정의 해야 한다.
//annotation- 부모가 가진 메소드를 재정의 하였다 는 의미임.
//콜백메소드는 개발자가 호출할 수 없는 메소드로 시스템 레벨에서 필요할 때 자동으로 호출됨.
//자바에 main메소드도 일종의 콜백 메소드 임.
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("actionPerformed 호출 성공");
String label = e.getActionCommand();//감지된 클래스의 라벨담기
System.out.println("너가 누른 버튼의 문자열은 "+label+ " 입니다.");
Object obj = e.getSource();//이벤트소스의 주소번지를담아줌.
System.out.println(obj);
if("지우기".equals(label)) {
jta_display.setText("");
}
//너 나가기 버튼이니?
//|만 있을 땐 앞에 조건이 true이면 실행문이 결정되었지만 뒤에 조건을 따짐
//||가 있을 땐 앞에 조건이 true이면 뒤에 조건이 false이어도 어차피 실행됨 - 뒤에 조건을 안따짐- 일량이 줄어듦
else if("나가기".equals(label) || obj == jmi_exit) {//or이니까 둘중 하나만 true이어도 호출된다.
exit();//사용자 정의 메소드 호출이다.
}
//새게임을 누른거야?
else if(obj == jbtn_new) {
jtf_user.requestFocus();
}
//이벤트가 발생한 이벤트 소스의 문자열을 비교하기
else if(e.getSource()==jtf_user) {
jta_display.append(++cnt+"회 : "+jtf_user.getText()+" : "+account(jtf_user.getText())+"\n");
jtf_user.setText("");
}///////////입력하고 엔터 쳤을 때
else if(obj==jmi_dap || "정답".equals(label)) {
//1-먼저 채번(동사-기능-메소드 호출)하고 그 다음에 com배열에 있는 값을 출력해 준다.
//ranCom();
jta_display.append("정답은 "+com[0]+com[1]+com[2]+" 입니다.\n");
//jta_display.append(com[0]+com[1]+com[2]);//0
}
}///////////////end of actionPerformed
}
package com.ExTable;
import java.awt.Component;
import java.sql.Date;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
import java.awt.Component;
import java.util.Vector;
import javax.swing.AbstractCellEditor;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
import javax.swing.table.TableCellRenderer;
@SuppressWarnings("serial")
public class ExTableAddBtn extends JFrame {
private Object[] objColNms = new Object[] { "이름", "출근","퇴근", "출근버튼","퇴근버튼" };
private Object[][] datas = null;
public static void main(String[] args) {
new ExTableAddBtn();
}
private JFrame jf;
private DefaultTableModel dtm;
private JTable jtable;
private JScrollPane jsp;
public ExTableAddBtn() {
jf = new JFrame("JTable Add Delete Button");
jf.setLocationRelativeTo(null);
jf.setSize(300, 300);
datas = new Object[][]{
{ "나신입", "08:59:00", "17:00:00",null,null }
, { "나일등", "08:57:00", "17:00:00",null,null }
, { "나초보", "08:55:00", "17:00:00",null,null}
};
dtm = new DefaultTableModel(datas,objColNms);
jtable = new JTable(dtm);
jsp = new JScrollPane(jtable);
jtable.getColumnModel().getColumn(3).setCellRenderer(new TableCell());
TableCell editor = new TableCell();
editor.setTableModel(dtm);
jtable.getColumnModel().getColumn(3).setCellEditor(editor);
jtable.getColumnModel().getColumn(4).setCellRenderer(new TableCell());
editor = new TableCell();
editor.setTableModel(dtm); // 객체를 재정의하여 새로운 객체를 넘겨준다.
jtable.getColumnModel().getColumn(4).setCellEditor(editor);
jf.add(jsp);
jf.setVisible(true);
}
class TableCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
JButton jb;
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
String currentTime;
private DefaultTableModel dtm;
JButton jb2;
public TableCell() {
jb = new JButton("출근버튼");
jb2 = new JButton("퇴근버튼");
/* 버튼을 2개로 설정되어 있고 if 문으로 --> 조건 분기를 진행한다.
* 현재의 시간 Date객체를 기준으로 해서 currentTime 변수에 값을 넣는다.
*/
jb.addActionListener(e -> { // 람다식
int row = jtable.getSelectedRow();
if (row != -1) {
currentTime = dateFormat.format(new Date(System.currentTimeMillis()));
dtm.setValueAt(currentTime, row, 1);
} // 중괄호 누락 수정
});
jb2.addActionListener(e -> { // 퇴근버튼의 액션 리스너
int row = jtable.getSelectedRow();
if (row != -1) {
currentTime = dateFormat.format(new Date(System.currentTimeMillis()));
dtm.setValueAt(currentTime, row, 2); // 퇴근시간 열(인덱스 2)에 시간 설정
}
});
}
@Override
public Object getCellEditorValue() {
return null;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if(column == 3)
{
return jb;
}
else if(column == 4)
{
return jb2;
}
return null;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
int column) {
if (column == 3) {
return jb;
} else if (column == 4) {
return jb2;
}
return null;
}
public void setTableModel(DefaultTableModel dtm) {
this.dtm = dtm;
} // end class TableCell extends AbstractCellEditor implements TableCellEditor,
// TableCellRenderer
}
}
@SuppressWarnings("serial")
public class ExTableAddBtn extends JFrame {
private Object[] objColNms = new Object[] { "이름", "출근","퇴근", "출근버튼","퇴근버튼" };
private Object[][] datas = null;
public static void main(String[] args) {
new ExTableAddBtn();
}
private JFrame jf;
private DefaultTableModel dtm;
private JTable jtable;
private JScrollPane jsp;
public ExTableAddBtn() {
jf = new JFrame("JTable Add Delete Button");
jf.setLocationRelativeTo(null);
jf.setSize(300, 300);
datas = new Object[][]{
{ "나신입", "08:59:00", "17:00:00",null,null }
, { "나일등", "08:57:00", "17:00:00",null,null }
, { "나초보", "08:55:00", "17:00:00",null,null}
};
dtm = new DefaultTableModel(datas,objColNms);
jtable = new JTable(dtm);
jsp = new JScrollPane(jtable);
jtable.getColumnModel().getColumn(3).setCellRenderer(new TableCell());
TableCell editor = new TableCell();
editor.setTableModel(dtm);
jtable.getColumnModel().getColumn(3).setCellEditor(editor);
jtable.getColumnModel().getColumn(4).setCellRenderer(new TableCell());
editor = new TableCell();
editor.setTableModel(dtm); // 객체를 재정의하여 새로운 객체를 넘겨준다.
jtable.getColumnModel().getColumn(4).setCellEditor(editor);
jf.add(jsp);
jf.setVisible(true);
}
- public ExTableAddBtn()
class TableCell extends AbstractCellEditor implements TableCellEditor, TableCellRenderer {
JButton jb;
SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
String currentTime;
private DefaultTableModel dtm;
JButton jb2;
public TableCell() {
jb = new JButton("출근버튼");
jb2 = new JButton("퇴근버튼");
/* 버튼을 2개로 설정되어 있고 if 문으로 --> 조건 분기를 진행한다.
* 현재의 시간 Date객체를 기준으로 해서 currentTime 변수에 값을 넣는다.
*/
jb.addActionListener(e -> { // 람다식
int row = jtable.getSelectedRow();
if (row != -1) {
currentTime = dateFormat.format(new Date(System.currentTimeMillis()));
dtm.setValueAt(currentTime, row, 1);
} // 중괄호 누락 수정
});
jb2.addActionListener(e -> { // 퇴근버튼의 액션 리스너
int row = jtable.getSelectedRow();
if (row != -1) {
currentTime = dateFormat.format(new Date(System.currentTimeMillis()));
dtm.setValueAt(currentTime, row, 2); // 퇴근시간 열(인덱스 2)에 시간 설정
}
});
}
@Override
public Object getCellEditorValue() {
return null;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if(column == 3)
{
return jb;
}
else if(column == 4)
{
return jb2;
}
return null;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
int column) {
if (column == 3) {
return jb;
} else if (column == 4) {
return jb2;
}
return null;
}
public void setTableModel(DefaultTableModel dtm) {
this.dtm = dtm;
} // end class TableCell extends AbstractCellEditor implements TableCellEditor,
// TableCellRenderer
}
}
- public Object getCellEditorValue()
- public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column)
- public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row, int column)
- public void setTableModel(DefaultTableModel dtm)
jb.addActionListener(e -> { // 람다식
int row = jtable.getSelectedRow();
if (row != -1) {
currentTime = dateFormat.format(new Date(System.currentTimeMillis()));
dtm.setValueAt(currentTime, row, 1);
} // 중괄호 누락 수정
});
System.currentTimeMillis(): 이 메서드는 1970년 1월 1일 00:00:00 GMT(그리니치 표준시)부터 현재 시간까지의 경과 시간을 밀리초(1/1000 초)로 반환한다.
new Date(...): java.util.Date 클래스는 날짜와 시간 정보를 저장하는 클래스다.
Date 클래스의 생성자에 System.currentTimeMillis()로 얻은 현재 시간을 전달하면 해당 시간 정보를 가지는 Date 객체가 생성된다.
dateFormat.format(...): SimpleDateFormat 클래스의 format 메서드는 Date 객체나 시간 정보를 특정 포맷으로 문자열로 변환한다.
dateFormat는 SimpleDateFormat 클래스의 인스턴스로 미리 지정한 날짜 및 시간 포맷을 사용하여 Date 객체의 시간 정보를 문자열로 변환한다.
@Override
public Object getCellEditorValue() {
return null;
}
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus,
int row, int column) {
if(column == 3)
{
return jb;
}
else if(column == 4)
{
return jb2;
}
return null;
}
@Override
public Component getTableCellEditorComponent(JTable table, Object value, boolean isSelected, int row,
int column) {
if (column == 3) {
return jb;
} else if (column == 4) {
return jb2;
}
return null;
}
public void setTableModel(DefaultTableModel dtm) {
this.dtm = dtm;
getTableCellRendererComponent
메서드는 셀의 컴포넌트를 반환하고, 이 컴포넌트가 테이블 셀 내용의 표시 역할이다
여기서는 column 값에 따라 jb 또는 jb2 버튼을 반환하여 해당 열(컬럼)에 버튼을 표시하고 있다. 즉, 이 메서드는 테이블 셀 내용의 렌더링을 담당하고, column 값에 따라 다른 버튼을 반환하여 표시한다.