ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 21-11-16 Swing 계산기, 달력, 체크 박스, 라디오 버튼
    학원/Java 2021. 11. 16. 15:49

     

    계산기

     

    어제 계산기 틀 만들기(https://omp14.tistory.com/23)에 이어 기능 구현하기

     

    기능 구현은 오버라이딩한 actionPerformed 메소드에서 이루어 지며 switch문을 사용하면 if문 보다 확장성이 좋다.

     

    1. 생성한 버튼에 모두 ActionListener을 추가한다.

    2. actionPerformed에 사용할 변수를 선언한다 

    3. switch문의 매개변수로 e.getActionCommand() 를 지정하고 case 작성 

    4. +,-,*,/,% 는 변수 operator로 특정 숫자를 지정하고 =를 눌렀을 때 동작하도록 case 작성

    -> 연산자를 누르면 이전에 입력됐던 텍스트를 parseInt로 firstNumber 변수에 넣고 0으로 텍스트필드가 초기화 시킨 후 두번째 피연산자를 입력받는다. 

    5. =을 누르면 operator에 맞는 연산이 일어나도록 작성

    -> 두번째 입력받은 텍스트를 secondNumber에 저장하고 연산 후 result1(정수) / result2(실수) 에 저장되어 setText

    ※ switch이 중첩되어 있으므로 중괄호 밖에 break; 적었는지 확인 할 것

    5. 1/x, sqr은 단항 연산이므로 operator 지정 불필요 (= 안눌러도 바로 결과가 나오도록 작성)

    -> 0일 경우 연산되지 않도록 if문 사용 

    6. C는 전체 삭제 이므로 setText("0"), ◀는 백스페이스므로 뒤에서 첫번째 글자만 지워지도록 한다

    -> getText().length() 로 문자열 길이를 구한다. 만일 1일 경우 0으로 초기화 한다.

    -> 1이 아닐 경우 subString (substring( 시작인덱스, 끝 ), substring( 시작인덱스 ) : 원본 문자열에서 시작인덱스부터 끝인덱스 바로 전 문자까지를 추출한다) 을 이용하여 length()-1 까지만 출력할 수 있도록 한다 (subString(0, jtf.getText.length()-1);  

     

     

    package days21;
    
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    class Calculator extends JFrame implements ActionListener {
    
    	JTextField jtf = new JTextField(20);
    	int firstNumber; 	//첫번째 숫자 저장
    	int secondNumber;	//두번째 숫자 
    	int result1;		//정수 결과
    	double result2;		//실수 결과
    	int operator = 0; 
    
    	Calculator() {
    
    		// 폰트 사용
    		Font f = new Font("굴림", Font.BOLD, 20);
    		jtf.setFont(f);
    
    		Container con = getContentPane();
    		con.setLayout(new GridLayout(6, 1));
    
    		JPanel p1 = new JPanel();
    		JPanel p2 = new JPanel();
    		JPanel p3 = new JPanel();
    		JPanel p4 = new JPanel();
    		JPanel p5 = new JPanel();
    		JPanel p6 = new JPanel();
    
    		p2.setLayout(new GridLayout(1, 4));
    		p3.setLayout(new GridLayout(1, 4));
    		p4.setLayout(new GridLayout(1, 4));
    		p5.setLayout(new GridLayout(1, 4));
    		p6.setLayout(new GridLayout(1, 4));
    
    		//p1
    		p1.setLayout(new FlowLayout(FlowLayout.CENTER));
    		jtf.setText("0");
    		jtf.setHorizontalAlignment(SwingConstants.RIGHT); // 텍스트 필드 오른쪽 정렬
    		jtf.setEditable(false); // 텍스트필드를 통해 직접 수정할 수 없음
    		p1.add(jtf);
    	
    		//p2
    		JButton b7 = new JButton("7");
    		JButton b8 = new JButton("8");
    		JButton b9 = new JButton("9");
    		JButton bp = new JButton("+");
    		b7.setFont(f);
    		b8.setFont(f);
    		b9.setFont(f);
    		bp.setFont(f);
    		p2.add(b7);
    		p2.add(b8);
    		p2.add(b9);
    		p2.add(bp);
    		
    		//p3
    		JButton b4 = new JButton("4");
    		JButton b5 = new JButton("5");
    		JButton b6 = new JButton("6");
    		JButton bm = new JButton("-");
    		b4.setFont(f);
    		b5.setFont(f);
    		b6.setFont(f);
    		bm.setFont(f);
    		p3.add(b4);
    		p3.add(b5);
    		p3.add(b6);
    		p3.add(bm);
    		
    		//p4
    		JButton b1 = new JButton("1");
    		JButton b2 = new JButton("2");
    		JButton b3 = new JButton("3");
    		JButton bt = new JButton("×");
    		b1.setFont(f);
    		b2.setFont(f);
    		b3.setFont(f);
    		bt.setFont(f);
    		p4.add(b1);
    		p4.add(b2);
    		p4.add(b3);
    		p4.add(bt);
    		
    		//p5
    		JButton bc = new JButton("C");
    		JButton b0 = new JButton("0");
    		JButton be = new JButton("=");
    		JButton bd = new JButton("÷");
    		bc.setFont(f);
    		b0.setFont(f);
    		be.setFont(f);
    		bd.setFont(f);
    		p5.add(bc);
    		p5.add(b0);
    		p5.add(be);
    		p5.add(bd);
    		
    		//p6
    		JButton back = new JButton("◀");
    		JButton sqr = new JButton("sqr");
    		JButton divide1 = new JButton("1/x");
    		JButton bn = new JButton("%"); //나머지 연산자
    		back.setFont(f);
    		sqr.setFont(f);
    		divide1.setFont(f);
    		bn.setFont(f);
    		p6.add(back);
    		p6.add(sqr);
    		p6.add(divide1);
    		p6.add(bn);
    
    		//컨테이너 적재
    		
    		con.add(p1);
    		con.add(p6);
    		con.add(p2);
    		con.add(p3);
    		con.add(p4);
    		con.add(p5);
    
    		
    		//ActionListener
    		b0.addActionListener(this);
    		b1.addActionListener(this);
    		b2.addActionListener(this);
    		b3.addActionListener(this);
    		b4.addActionListener(this);
    		b5.addActionListener(this);
    		b6.addActionListener(this);
    		b7.addActionListener(this);
    		b8.addActionListener(this);
    		b9.addActionListener(this);
    		bp.addActionListener(this);
    		bm.addActionListener(this);
    		bt.addActionListener(this);
    		bd.addActionListener(this);
    		bc.addActionListener(this);
    		be.addActionListener(this);
    		back.addActionListener(this);
    		sqr.addActionListener(this);
    		divide1.addActionListener(this);
    		bn.addActionListener(this);
    		
    		//윈도우 생성
    		setTitle("계산기 실습");
    		setSize(400, 500);
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setVisible(true);
    	}
    
    	@Override
    	public void actionPerformed(ActionEvent e) {
    
    		String oldText = jtf.getText();
    		String s = e.getActionCommand();
    		String newText;
    		
    		switch (s) {
    		case "+": 
    			operator = 1;
    			firstNumber = Integer.parseInt(jtf.getText());
    			jtf.setText("0");
    			break;
    		case "-": 
    			operator = 2;
    			firstNumber = Integer.parseInt(jtf.getText());
    			jtf.setText("0");
    			break;
    		case "×": 
    			operator = 3;
    			firstNumber = Integer.parseInt(jtf.getText());
    			jtf.setText("0");
    			break;
    		case "÷": 
    			operator = 4;
    			firstNumber = Integer.parseInt(jtf.getText());
    			jtf.setText("0");
    			break;
    		case "C": 
    			jtf.setText("0");
    			break; 
    		case "◀" :
    			if (jtf.getText().length() == 1) {
    				jtf.setText("0");
    			} else {
    				jtf.setText(oldText.substring(0,jtf.getText().length()-1));
    			}
    			break;
    		case "sqr" :
    			if (jtf.getText().length() == 0) break;
    			else {
    				firstNumber = Integer.parseInt(jtf.getText());
    				result2 = Math.sqrt((double) firstNumber);
    				jtf.setText(String.valueOf(result2));
    			}
    			break;
    		case "1/x" :
    			if (jtf.getText().length() == 0) break;
    			else {
    				firstNumber = Integer.parseInt(jtf.getText());
    				result2 = 1.0/firstNumber;
    				jtf.setText(String.valueOf(result2));
    			}
    			break;
    		case "%" :
    			operator = 5;
    			firstNumber = Integer.parseInt(jtf.getText());
    			jtf.setText("0");
    			break;
    			
    		case "=": 
    			switch(operator) {
    				case 1: 
    					secondNumber = Integer.parseInt(jtf.getText());
    					result1 = firstNumber + secondNumber;
    					jtf.setText(String.valueOf(result1));
    					break;
    				case 2:
    					secondNumber = Integer.parseInt(jtf.getText());
    					result1 = firstNumber - secondNumber;
    					jtf.setText(String.valueOf(result1));
    					break;
    				case 3:
    					secondNumber = Integer.parseInt(jtf.getText());
    					result1 = firstNumber * secondNumber;
    					jtf.setText(String.valueOf(result1));
    					break;
    				case 4:
    					secondNumber = Integer.parseInt(jtf.getText());
    					result2 = firstNumber / (double) secondNumber;
    					jtf.setText(String.valueOf(result2));
    					break;
    				case 5:
    					secondNumber = Integer.parseInt(jtf.getText());
    					result1 = firstNumber % secondNumber;
    					jtf.setText(String.valueOf(result1));
    					break;
    			}
    			break;
    			
    		case "0": case "1": case "2": case "3": case "4": 
    		case "5": case "6": case "7": case "8": 		
    		case "9": 
    			if(oldText.equals("0")) oldText = "";
    			jtf.setText(oldText + s);
    			break;	
    		
    		
    		}
    	}
    }
    
    public class Swing13 {
    	public static void main(String[] args) {
    
    		new Calculator();
    
    	}
    
    }

     

     

     

    개선 할 점 

     

    1. 결과 표시 후 다음 숫자 입력할 때 자동 초기화 

    2. 계산될 숫자 표시 

    3. 계산한 내역 표시

     

     

    달력 

    달력 모양 구현 

     

    1. 패널 3개 만들기 : 요일, 날짜, 기능버튼(년월 textField 포함)

    -> 요일은 1*7, 날짜는 6*7의 GridLayout, 기능버튼 패널은 FlowLayout을 이용한다. 

    2. 월~일 총 7개의 버튼 제작, for문을 통해 날짜가 될 textfield 제작(수정될 수 없도록 setEditable(false) 설정)

    폰트나 컬러등도 함께 설정한다.

    3. year와 month를 출력, 입력받을 TextField 만들기. 전역변수로 제작한다. 함께 전역변수로 사용할 변수도 정의한다.

    4. 컨테이너는 BorderLayout을 이용한다 (north, center, south 사용)

    5. 캘린더에서 오늘 날짜를 가져와 년,월 TextField에 세팅한다.

    6. 출력될 순서에 맞춰 컨테이너에 적재한다. 

    7. 알맞게 날짜를 채워줄 메소드(drawCalaendar())를 제작한다

    -> 방법은 Calendar 클래스를 이용한 달력 제작과 거의 동일

    8. actionPerformed 메서드에 다음달, 저번달, 입력한 달의 달력을 표시하는 확인 기능을 구현 한다.

    -> 이것도 거의 동일 (addActionListener 잊지 말기)

    9. 윈도우 설정을 하고 (setTitle, setSize ... ) drawCalaendar()를 호출한다.

     

    package days21;
    
    import java.awt.event.*;
    import java.util.Calendar;
    import java.awt.*;
    import javax.swing.*;
    
    class Calendars extends JFrame implements ActionListener {
    	
    	static int year = 0;
    	static int month = 0;
    	static JTextField[] jt = new JTextField[42];
    	//1년 달력의 42개(42주)의 열을 제작 
    	
    	JTextField y;
    	JTextField m;
    	
    	Calendars() {
    	
    		Container con = getContentPane();
    		con.setLayout(new BorderLayout());
    		
    		JPanel jp1 = new JPanel();	//월~금 요일
    		JPanel jp2 = new JPanel();	//6*7 날짜
    		JPanel jp3 = new JPanel();	//이전달다음달버튼
    		
    		jp1.setLayout(new GridLayout(1,7));
    		jp2.setLayout(new GridLayout(6,7));
    		jp3.setLayout(new FlowLayout());
    		
    		jp1.add(new JButton("일")).setForeground(Color.RED); //색지정
    		jp1.add(new JButton("월"));
    		jp1.add(new JButton("화"));
    		jp1.add(new JButton("수"));
    		jp1.add(new JButton("목"));
    		jp1.add(new JButton("금"));
    		jp1.add(new JButton("토")).setForeground(Color.BLUE);
    		
    		Font f = new Font("굴림", Font.BOLD, 20);
    		
    		
    		//for문을 통해 날짜가 될 textfield 제작
    		for(int i=0; i<42; i++) {
    			jt[i] = new JTextField(); //textfield 객체 생성
    			jt[i].setFont(f);	//폰트설정
    			jt[i].setHorizontalAlignment(SwingConstants.RIGHT);	//오른쪽정렬
    			jt[i].setEditable(false);	//수정 불가 -> 설정 시 글자색이 연해짐
    			jt[i].setBackground(Color.WHITE); 
    			if(i%7==6) jt[i].setForeground(Color.BLUE); //토요일
    			else if(i%7==0) jt[i].setForeground(Color.RED); //일요일
    			else jt[i].setForeground(Color.BLACK);
    			jp2.add(jt[i]);
    		}
    		
    		y = new JTextField(6);
    		y.setFont(f);
    		y.setHorizontalAlignment(SwingConstants.CENTER);
    		y.setBackground(Color.WHITE);
    		
    		m = new JTextField(4);
    		m.setFont(f);
    		m.setHorizontalAlignment(SwingConstants.CENTER);
    		m.setBackground(Color.WHITE);
    		
    		Calendar Today = Calendar.getInstance();
    		y.setText(String.valueOf(Today.get(Calendar.YEAR)));
    		m.setText(String.valueOf(Today.get(Calendar.MONTH)+1));
    		
    		JButton b = new JButton("확인");
    		JButton b1 = new JButton("이전달");
    		JButton b2 = new JButton("다음달");
    		
    		b.addActionListener(this);
    		b1.addActionListener(this);
    		b2.addActionListener(this);
    		
    		con.add(jp1, BorderLayout.NORTH);
    		con.add(jp2, BorderLayout.CENTER);
    		con.add(jp3, BorderLayout.SOUTH);
    		
    		jp3.add(b1);
    		jp3.add(y);
    		jp3.add(new JLabel("년"));
    		jp3.add(m);
    		jp3.add(new JLabel("월"));
    		jp3.add(b);
    		jp3.add(b2);
    		
    		//윈도우 생성
    		setTitle("스윙 캘린더");
    		setSize(600, 500);
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setVisible(true);	
    //		
    		year = Integer.parseInt(y.getText());
    		month = Integer.parseInt(m.getText());
    		drawCalendar();
    			
    	}
    	
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		//이전달 다음달 버튼에 따라 year,month 변수를 계산 후
    		//drawCalendar() 호출
    	
    		String s = e.getActionCommand();
    		switch(s) {
    			case "이전달": 
    				if(month == 1) {
    					year--; month = 12;
    				} else month--;
    				break;
    			case "다음달":
    				if(month == 12) {
    					year++; month = 1;
    				} else month++;
    				break;
    			case "확인":
    				int tempY = Integer.parseInt(y.getText());
    				int tempM = Integer.parseInt(m.getText());
    				if(tempY>=1&&tempM<=3000) year = Integer.parseInt(y.getText());
    				if(tempM>=1 && tempM<=12) month = Integer.parseInt(m.getText());
    		}
    		
    		y.setText(String.valueOf(year));
    		m.setText(String.valueOf(month));
    	
    		for(int i=0; i<jt.length; i++) jt[i].setText("");
    		drawCalendar();
    	}
    	
    	private void drawCalendar() {
    		//해당 년월의 달력을 화면에 표시
    		Calendar sDay = Calendar.getInstance();
    		Calendar eDay = Calendar.getInstance();
    		
    		sDay.set(year,month-1,1); //오늘 날짜 월의 1일
    		eDay.set(year,month,1);
    		eDay.add(Calendar.DATE,-1); //오늘 날짜 월의 말일
    		
    		int START_WEEK = sDay.get(Calendar.DAY_OF_WEEK); //시작 요일
    		
    		int k;
    	
    		//TextField가 다 비워져 있는 상태에서
    		//1일자의 요일(1,2,3,4...)번째 (k-1)의 TextField부터 날짜 표시
    		//이전 칸들은 비워둔채로 시작
    		//각 TextField에 sDay의 값들을 표시 -> 일자만 표시
    		//한 번 반복마다 날짜는 1일씩 늘어난다. (eDay<=sDay까지)
    		for(int i=START_WEEK-1; sDay.before(eDay)||sDay.equals(eDay); sDay.add(Calendar.DATE, 1)) {
    			//1일부터 말일까지
    			int day = sDay.get(Calendar.DATE);
    			jt[i++].setText(String.valueOf(day));
    			
    		}
    			
    	}
    	
    }
    public class Swing14 {
    	public static void main(String[] args) {
    		
    		new Calendars();
    	}
    }

     

     

     

     

    체크 박스 만들기 

    checkbox는 ActionListener가 아닌 ItemListener을 implements한다.

    ItemListener는 체크박스가 선택되었는지 아닌지, 상태가 true인지 false인지를 구별해준다.

     

    전체적인 틀은 ActionListener를 사용할 때와 거의 같다.

     

    import java.awt.event.*;
    import java.awt.*;
    import javax.swing.*;
    
    class JCheckBoxTest extends JFrame implements ItemListener {
    	
    	JTextField jtf;
    	JCheckBox jcb1;
    	JCheckBox jcb2;
    	JCheckBox jcb3;
    	JCheckBox jcb4;
    	
    	JCheckBoxTest() {
    		
    		jcb1 = new JCheckBox("JSP");
    		jcb2 = new JCheckBox("PHP");
    		jcb3 = new JCheckBox("ASP");
    		jcb4 = new JCheckBox("SEREVELT");
    		jtf = new JTextField(30);
    		
    		Font f = new Font("굴림", Font.BOLD, 20);
    		jcb1.setFont(f);
    		jcb2.setFont(f);
    		jcb3.setFont(f);
    		jcb4.setFont(f);
    		jtf.setFont(f);
    		
    		Container con = getContentPane();
    		con.setLayout(new FlowLayout());
    		con.add(jcb1);
    		con.add(jcb2);
    		con.add(jcb3);
    		con.add(jcb4);
    		con.add(jtf);
    		
    		jcb1.addItemListener(this);
    		jcb2.addItemListener(this);
    		jcb3.addItemListener(this);
    		jcb4.addItemListener(this);
    		
    		setTitle("체크박스테스트");
    		setSize(600, 150);
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setVisible(true);	
    	}
    
    	@Override
    	public void itemStateChanged(ItemEvent e) {
    		//상태가 true/false 중 어떻게 변했는지 감지
    		String s  = "";
    		if(jcb1.isSelected()) s = s + "JSP ";
    		if(jcb2.isSelected()) s = s + jcb2.getActionCommand() + " ";
    		if(jcb3.isSelected()) s = s + "ASP ";
    		if(jcb4.isSelected()) s = s + jcb4.getActionCommand() + " ";
    		//선택될 내용을 직접 입력하거나 getActionCommand()를 사용할 수 있다.
    		
    		jtf.setText("현재 선택 항목 : " + s);
    	}
    	
    }
    public class Swing16 {
    
    	public static void main(String[] args) {
    		
    		new JCheckBoxTest();
    	}
    }

     

     

     

    라디오버튼 만들기 

    라디오버튼은 체크박스와는 달리 복수 선택이 불가하다.

    -> 단 자체 기능으로 복수 선택이 안되는 것은 아니다.. 라디오 버튼이라면 응당 복수 선택이 안되야 한다는 것...

    --> 이때 필요한 것이 ButtonGroup이다 buttonGroup에 먼저 버튼들을 담고나서 버튼들을(그룹이 아닌 버튼을 직접) 적재하면 복수 선택이 되지 않는다.

     

    import java.awt.event.*;
    import java.awt.*;
    import javax.swing.*;
    
    //라디오 버튼
    class JRadioButtonTest extends JFrame implements ActionListener {
    
    	JRadioButton jrb1;
    	JRadioButton jrb2;
    	JRadioButton jrb3;
    	JRadioButton jrb4;
    	ButtonGroup bg;
    	JTextField jtf;
    	
    	JRadioButtonTest() {
    		jrb1 = new 	JRadioButton("승마");
    		jrb2 = new 	JRadioButton("골프");
    		jrb3 = new 	JRadioButton("글라이딩");
    		jrb4 = new 	JRadioButton("스쿠버");
    		jtf = new JTextField(30);
    		
    		Container con = getContentPane();
    		con.setLayout(new FlowLayout());
    		
    		Font f = new Font("굴림", Font.BOLD, 20);
    		jrb1.setFont(f);
    		jrb2.setFont(f);
    		jrb3.setFont(f);
    		jrb4.setFont(f);
    		jtf.setFont(f);
    		
    		bg = new ButtonGroup();
    		bg.add(jrb1);
    		bg.add(jrb2);
    		bg.add(jrb3);
    		bg.add(jrb4);
    		
    		con.add(jrb1);
    		con.add(jrb2);
    		con.add(jrb3);
    		con.add(jrb4);
    		con.add(jtf);
    		
    		jrb1.addActionListener(this);
    		jrb2.addActionListener(this);
    		jrb3.addActionListener(this);
    		jrb4.addActionListener(this);
    		
    		setTitle("라디오박스 테스트");
    		setSize(600, 150);
    		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    		setVisible(true);	
    	}
    	@Override
    	public void actionPerformed(ActionEvent e) {
    		if(jrb1.isSelected()) jtf.setText(jrb1.getActionCommand() + " 이/가 선택되었습니다.");
    		else if(jrb2.isSelected()) jtf.setText(jrb2.getActionCommand() + " 이(가) 선택되었습니다.");
    		else if(jrb3.isSelected()) jtf.setText(jrb3.getActionCommand() + " 이(가) 선택되었습니다.");
    		else jtf.setText(jrb4.getActionCommand() + " 이(가) 선택되었습니다.");
    		
    	}
    	
    
    }
    public class Swing17 {
    
    	public static void main(String[] args) {
    		
    		new JRadioButtonTest();
    
    	}
    }

     

     

     

     

     

    '학원 > Java' 카테고리의 다른 글

    21-11-18 IO#2 (File)  (0) 2021.11.18
    21-11-17 Swing 콤보상자, Thread, IO  (0) 2021.11.17
    21-11-15 Swing  (0) 2021.11.15
    21-11-11 Collection#2, Exception  (0) 2021.11.11
    21-11-10 DecimalFomat#2, interface, Collection  (0) 2021.11.10

    댓글

Designed by Tistory.