국비교육(22-23)

22일차(1)/java 퀴즈 : input, output 활용 예제

서리/Seori 2022. 11. 4. 14:23

22일차(1)/java 퀴즈 : input, output 활용 예제

 

 

1. JTextField에 문자열을 입력하고 추가 버튼을 누르면
 입력한 문자열이 myFolder/memo.txt파일에 append 되도록 해보세요.
  
2. 불러오기 버튼을 누르면 myFolder/memo.txt 파일에 있는 모든 문자열을
 JTextArea에 출력하도록 해보세요.

 

 

 

QuizMain1

package test.main;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/*
 *  1. JTextField에 문자열을 입력하고 추가 버튼을 누르면
 *  입력한 문자열이 myFolder/memo.txt파일에 append 되도록 해보세요.
 * 
 *  2. 불러오기 버튼을 누르면 myFolder/memo.txt 파일에 있는 모든 문자열을
 *  JTextArea에 출력하도록 해보세요.
 */
public class QuizMain extends JFrame implements ActionListener {
   JTextField inputMsg;
   JTextArea ta;

   public QuizMain(String title) {
      super(title);
      setBounds(100, 100, 500, 500);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setLayout(new FlowLayout(FlowLayout.CENTER));
      //다른 메소드에서 사용할 수 있도록 UI의 참조값을 객체의 필드에 저장하기
      inputMsg = new JTextField(10);
      ta = new JTextArea();
      JButton addBtn = new JButton("추가");
      JButton callBtn = new JButton("불러오기");

      add(inputMsg);
      add(addBtn);
      add(callBtn);
      add(ta);
      //버튼을 눌렀을때 호출되는 메소드를 가지고있는 객체 등록      
      addBtn.addActionListener(this);
      callBtn.addActionListener(this);
      //JTextArea를 출력 전용으로 사용하겠다는 의미
      ta.setEditable(false);
      setVisible(true);
   }

   public static void main(String[] args) {
      new QuizMain("QuizMain");
   }

   //ActionListener 인터페이스 구현했기때문에 재정의한 메소드
   @Override
   public void actionPerformed(ActionEvent e) {
	  
      File memoFile = new File("C:/acorn202210/myFolder/memo.txt");
      //필요한 객체를 담을 지역변수를 미리 만들기
      FileReader fr = null;
      BufferedReader br = null;
      FileWriter pw=null;      
      try {
         String command = e.getActionCommand();
         if(command.equals("추가")) {
        	 //입력한 문자열을 읽어온다.
        	 String msg = inputMsg.getText();
        	 //memo.txt파일에 출력하기
        	 pw = new FileWriter(memoFile, true);
        	 pw.write(msg+"\r\n");
        	 pw.flush();            
         } else if(command.equals("불러오기")) {
             fr = new FileReader(memoFile);
             br = new BufferedReader(fr);
             //JTextArea에 이미 출력된 내용을 일단 삭제하고
             ta.setText("");
             while (true) {//반복문 돌면서
            	//문자열을 한줄씩 읽어들인다.
                String line = br.readLine();
                if (line == null) {//더이상 읽을 문자열이 없으면
                   break; //반복문 탈출
                }
                //읽은 문자열 한줄을 개행기호와 함께 JTextArea 객체에 출력하기
                ta.append(line+"\r\n");               
            }
         }
      } catch (Exception e1) {
         e1.printStackTrace();
      } finally {
         // exception이 발생하건 안하건 실행할 수 있는 공간에서 마무리작업을 해준다.
         try {
            // 혹시 모를 null 로 넘어오는 상황을 위해 대비
            // 닫는 작업은 열린 순서의 역순으로 하면 좋다.
            if(br != null) br.close();
            if(fr != null) fr.close();
            if(pw != null) pw.close();
         } catch (Exception e2) {
            e2.printStackTrace();
         }
      }
   }
}

 

 

- 최종 결과창!

 

 

- 먼저 JTextField, JTextArea를 필드로 지정한다.

 

 

- ActionListener는 이런 모양의 구현되지 않은 추상메소드를 가지고 있다.

 

- AcitonListener 타입을 넣어주어야 하는데 this를 넣는다는 것은,

이 Frame 객체가 AcitonListener 인터페이스를 구현하고 있어서 가능한 것!

 

.setEditable(false); : TextArea에 수정가능여부를 False로 하겠다.(읽기 전용으로 쓰겠다)

 


FileReader fr = null; 메모장에서 읽어오기
BufferedReader br = null; 좀더 편하게 읽어오기...

- 변수는 미리 만들고 참조값을 try블럭 안에서 넣어준다.

FileWriter(memoFile, true); : true를 지정해서 내용이 누적되도록 한다.

- 추가 버튼 : 입력받은 값을 읽어와서 txt파일에 출력하기
- 불러오기 버튼 : FileReader의 참조값을 BufferedReader로 포장함.

ta.append(\r\n); : TextArea의 append 메소드. 기존에 있던 내용을 유지하면서 덧붙이겠다는 것

 

 


 

QuizMain2

package test.main;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/*
 *  1. JTextField에 문자열을 입력하고 추가 버튼을 누르면
 *  입력한 문자열이 myFolder/memo.txt파일에 append 되도록 해보세요.
 * 
 *  2. 불러오기 버튼을 누르면 myFolder/memo.txt 파일에 있는 모든 문자열을
 *  JTextArea에 출력하도록 해보세요.
 */
public class QuizMain2 extends JFrame implements ActionListener {
   JTextField inputMsg;
   JTextArea ta;

   public QuizMain2(String title) {
      super(title);
      setBounds(100, 100, 500, 500);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setLayout(new BorderLayout());
      //다른 메소드에서 사용할 수 있도록 UI의 참조값을 객체의 필드에 저장하기
      inputMsg = new JTextField(10);
      ta = new JTextArea();
      JButton addBtn = new JButton("추가");
      JButton callBtn = new JButton("불러오기");

      //Jpanel 객체를 생성해서
      JPanel panel=new JPanel();
      //UI를 객체에 추가하고
      panel.add(inputMsg);
      panel.add(addBtn);
      panel.add(callBtn);      
      //패널을 프레임의 상단에 배치하기
      add(panel,BorderLayout.NORTH);
      
      //스크롤이 가능한 UI
      JScrollPane sc=new JScrollPane(ta);
      
      //JTextArea를 감싸고 있는 스크롤 패널을 프레임의 중심에 배치하기
      add(sc,BorderLayout.CENTER);
          
      //버튼을 눌렀을때 호출되는 메소드를 가지고있는 객체 등록      
      addBtn.addActionListener(this);
      callBtn.addActionListener(this);
      //JTextArea를 출력 전용으로 사용하겠다는 의미
      ta.setEditable(false);
      setVisible(true);
   }

   public static void main(String[] args) {
      new QuizMain2("QuizMain");
   }

   //ActionListener 인터페이스 구현했기때문에 재정의한 메소드
   @Override
   public void actionPerformed(ActionEvent e) {
	  
      File memoFile = new File("C:/acorn202210/myFolder/memo.txt");
      //필요한 객체를 담을 지역변수를 미리 만들기
      FileReader fr = null;
      BufferedReader br = null;
      FileWriter pw=null;      
      try {
         String command = e.getActionCommand();
         if(command.equals("추가")) {
        	 //입력한 문자열을 읽어온다.
        	 String msg = inputMsg.getText();
        	 //memo.txt파일에 출력하기
        	 pw = new FileWriter(memoFile, true);
        	 pw.write(msg+"\r\n");
        	 pw.flush();            
         } else if(command.equals("불러오기")) {
             fr = new FileReader(memoFile);
             br = new BufferedReader(fr);
             //JTextArea에 이미 출력된 내용을 일단 삭제하고
             ta.setText("");
             while (true) {//반복문 돌면서
            	//문자열을 한줄씩 읽어들인다.
                String line = br.readLine();
                if (line == null) {//더이상 읽을 문자열이 없으면
                   break; //반복문 탈출
                }
                //읽은 문자열 한줄을 개행기호와 함께 JTextArea 객체에 출력하기
                ta.append(line+"\r\n");               
            }
         }
      } catch (Exception e1) {
         e1.printStackTrace();
      } finally {
         // exception이 발생하건 안하건 실행할 수 있는 공간에서 마무리작업을 해준다.
         try {
            // 혹시 모를 null 로 넘어오는 상황을 위해 대비
            // 닫는 작업은 열린 순서의 역순으로 하면 좋다.
            if(br != null) br.close();
            if(fr != null) fr.close();
            if(pw != null) pw.close();
         } catch (Exception e2) {
            e2.printStackTrace();
         }
      }
   }    
}

 

2)두번째. 레이아웃 수정(border), 스크롤추가

 

- flowLayout을 BorderLayout()); 으로 수정.
 프레임 말고 패널에 버튼을 추가해 본다!

 

- 패널을 상단(north)에 배치하고, 패널안에 텍스트상자와 버튼이 들어있다.

 

- 1번 예제보다 모양이 정돈됨

 

 

- 내용이 많아지면 뒷부분이 잘린다. 스크롤기능 추가하기.

- 스크롤할 수 있는 패널로 TextArea를 감싸는 것! 생성자의 인자로 Textarea를 받는다.(component 타입)

 

JScrollPane sc=new JScrollPane(ta);
add(sc,BorderLayout.CENTER);

- 스크롤 패널을 만들어주고, 그안에 TextArea를 넣은 후, 스크롤패널을 가운데에 배치한 것.

 

- 불러온 텍스트파일의 내용이 길어져도 잘리지 않고 스크롤 형태로 나타난다.

 

 


 

 

 

QuizMain3 (★다시 연습해보기)

- 코드의 모양 정리, 메소드 빼내기 

package test.main;

import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;

/*
 *  1. JTextField에 문자열을 입력하고 추가 버튼을 누르면
 *  입력한 문자열이 myFolder/memo.txt파일에 append 되도록 해보세요.
 * 
 *  2. 불러오기 버튼을 누르면 myFolder/memo.txt 파일에 있는 모든 문자열을
 *  JTextArea에 출력하도록 해보세요.
 */
public class QuizMain2 extends JFrame implements ActionListener {
   JTextField inputMsg;
   JTextArea ta;

   public QuizMain2(String title) {
      super(title);
      setBounds(100, 100, 500, 500);
      setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      setLayout(new BorderLayout());
      //다른 메소드에서 사용할수 있도록 UI 의 참조값을 객체의 필드에 저장하기 
      inputMsg = new JTextField(10);
      ta = new JTextArea();
      JButton addBtn = new JButton("추가");
      JButton callBtn = new JButton("불러오기");
      
      //JPanel 객체를 생성해서 
      JPanel panel=new JPanel();
      //UI 를 페널에 추가하고 
      panel.add(inputMsg);
      panel.add(addBtn);
      panel.add(callBtn);
      //페널을 프레임의 상단에 배치하기
      add(panel, BorderLayout.NORTH);
      
      //스크롤이 가능한 UI
      JScrollPane sc=new JScrollPane(ta);
      
      //JTextArea 를 감싸고 있는 스크롤 페널을 프레임의 중심에 배치하기 
      add(sc, BorderLayout.CENTER);
      
      //버튼을 눌렀을때 호출되는 메소드를 가지고 있는 객체 등록 
      addBtn.addActionListener(this);
      callBtn.addActionListener(this);
      //JTextArea 를 출력 전용으로 사용하겠다는 의미 
      ta.setEditable(false);
      setVisible(true);
   }

   public static void main(String[] args) {
      new QuizMain2("QuizMain");
   }
   
   
   //ActionListener 인터페이스를 구현했기 때문에 재정의한 메소드  
   @Override
   public void actionPerformed(ActionEvent e) {
       //어떤 버튼을 눌렀는지 알아내서 
      String command = e.getActionCommand();
      //분기한다. 
      if(command.equals("추가")) {
         saveToFile();
      } else if(command.equals("불러오기")) {
          loadFromFile();
      }
   }
   
   //파일에 문자열을 추가하는 메소드
   public void saveToFile() {
      File memoFile = new File("c:\\acorn202210\\myFolder\\memo.txt");
      //필요한 객체를 담을 지역 변수를 미리 만들기 
      FileWriter pw=null;
      try {      
       //입력한 문자열을 읽어온다. 
        String msg = inputMsg.getText();
        //memo.txt 파일에 출력하기 
        pw = new FileWriter(memoFile, true);
        pw.write(msg+"\r\n");
        pw.flush();  
      } catch (Exception e1) {
         e1.printStackTrace();
      } finally {
         // exception이 발생하건 안하건 실행할 수 있는 공간에서 마무리작업을 해준다.
         try {
            if(pw != null) pw.close();
         } catch (Exception e2) {
            e2.printStackTrace();
         }
      }      
   }
   //파일로 부터 문자열을 읽어들이는 메소드
   public void loadFromFile() {
       
      File memoFile = new File("c:\\acorn202210\\myFolder\\memo.txt");
      //필요한 객체를 담을 지역 변수를 미리 만들기 
      FileReader fr = null;
      BufferedReader br = null;
      try {  
        fr = new FileReader(memoFile);
        br = new BufferedReader(fr);
        //JTextArea 에 이미 출력된 내용을 일단 삭제하고 
        ta.setText("");
        while (true) {//반복문 돌면서 
           //문자열을 한줄씩 읽어들인다.
           String line = br.readLine();
           if (line == null) {//더이상 읽을 문자열이 없으면
              break;//반복문 탈출
           }
           //읽은 문자열 한줄을 개행기호와 함께 JTextArea 객체에 출력하기 
           ta.append(line+"\r\n"); 
        } 
      } catch (Exception e1) {
         e1.printStackTrace();
      } finally {
         // exception이 발생하건 안하건 실행할 수 있는 공간에서 마무리작업을 해준다.
         try {
            // 혹시 모를 null 로 넘어오는 상황을 위해 대비
            // 닫는 작업은 열린 순서의 역순으로 하면 좋다.
            if(br != null) br.close();
            if(fr != null) fr.close();
         } catch (Exception e2) {
            e2.printStackTrace();
         }
      }      
   }   
}

 

- ActionPerformed 가 현재 너무 복잡한 상태.
 이 안에서는 간단한 작업만 하고싶다! 어떤 버튼을 누르면 분기하는 작업만 하고싶다면?

- 추가하기, 불러오기를 if와 elseif 안에다가 넣지 않고 별도의 메소드로 분리한다.

- actionPerformed 안에는 if~else 분기만 만들어두고 외부 메소드를 호출하는 구조로 정의하기.

public void saveToFile() {
	//파일에 문자열을 추가하는 메소드//
}

public void loadFromFile() {
	//파일로부터 읽어오는 메소드//
}

 

- 위와 같은 별도의 메소드를 만들어 하단에 따로 정리한다.

 

 


 

참고) \ , " 사용법 및 출력법

 

- 윈도우의 파일구분자는 \ (역슬래시) 로 나오는데, 

  코딩에서는 보통 \ 가 특별한 의미를 갖고 있다.(\r\n 개행기호 등)
→ 그냥 문자열 안에 \ 라는 문자를 작성하고 싶을 때에는 \\ 로 두 개 작성해주면 된다.

ex) String test="ba\nana" -> ba\nana 라고 출력되게 하고 싶다.
   String test="ba\\nana" 라고 쓰면 된다!


- " " 표시하는 문자열 안에 " 라는 문자를 넣고싶다면?
ex) String test="ba"nana" → ba"nana 라고 출력되게 하고 싶다.
\ 를 앞에 붙이는 것은 특별한 의미로 해석하지 말라는 의미로 사용될 수 있다. 문자 그대로 봐달라는 뜻!(리터럴 값)
String test="ba\"nana" 역슬래시가 특별한 의미로 사용되기 때문에 앞에 \ 를 하나 더 붙여줌으로서 문자 그대로 읽히게 해준다.

 


- 윈도우의 파일구분자가 원래 \이므로, \를 인식시키기 위해서는 \\ 형태로 2개씩 찍어주어야 한다.

  (탐색기 창에서 이클립스로 복사-붙여넣기 하면 자동으로 그렇게 입력된다)

ex) C:\\myFolder\\memo.txt 를 입력하면
     C:\myFolder\memo.txt 으로 출력된다.

 

- 파일 구분자를 사용할 때는 / 를 써도 그냥 \ 와 똑같이 인식해준다.