Java

Java getSource()

승모근뭉치 2023. 2. 5. 16:58

프로젝트 내 src 내 javabasic 패키지 내 Ex2PhotoInfoSave.java

package javabasic;

import java.awt.Canvas;
import java.awt.Color;
import java.awt.FileDialog;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JTextField;

public class Ex2PhotoInfoSave extends JFrame implements ActionListener {
	MyPhoto myPhoto;// 내부클래스
	JButton btnPhoto, btnSave, btnOpen;
	JTextField txtName, txtAge;
	JComboBox<String> comboBlood;
	Image photoImage;
	String imageName = "C:\\java0901\\image\\귀여운 아이콘\\c1.png";// 파일에 저장할 이미지명

	public Ex2PhotoInfoSave(String title) {
		// TODO Auto-generated constructor stub
		super(title);
		this.setBounds(700, 100, 400, 400);// 시작위치x,y,크기 w,h
		// super로 해도 되고 this로 해도 됨 super는 조상
		// this로 해도 상속을 받아서 괜찮음
		// this.getContentPane().setBackground(Color.orange);//프레임위에 있는 패널의 색상 변경
//		this.getContentPane().setBackground(new Color(211,225,208));//프레임위에 있는 패널의 색상 변경
		this.getContentPane().setBackground(Color.white);// 프레임위에 있는 패널의 색상 변경
		this.setDesign();// 디자인 코드
		this.setVisible(true);// 보이게 하기
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);// 프로그램을 종료해주는 메서드
	}

	@Override
	public void actionPerformed(ActionEvent e) {
		// TODO Auto-generated method stub
		Object ob = e.getSource();
		if (ob == btnPhoto)// 사진가져오기 버튼
		{
//			FileDialog 이용해서 사진을 가져오면 사진 변경되도록 해보세요
//			FileDialog fd=new FileDialog(this, "사진가져오기", FileDialog.LOAD);
			FileDialog dlg = new FileDialog(this, "사진가져오기", FileDialog.LOAD);
			dlg.setVisible(true);
//			fd.setVisible(true);
//			취소가 아닌경우 사진 출력
			if (dlg.getDirectory() != null) {
				imageName = dlg.getDirectory() + dlg.getFile();
//				Image생성
				photoImage = new ImageIcon(imageName).getImage();
//				paint 메서드 호출
				myPhoto.repaint();
			}
//			String fileDir=fd.getDirectory();
//			String fileName=fd.getFile();
//							
//			if(fileDir!=null)
//			{
//				photoImage=new ImageIcon(fileDir+fileName).getImage();
//				myPhoto.repaint();
//			}

		} else if (ob == btnSave)// 정보 저장
		{
//			입력한 이름.txt 로 저장하기(java0901 폴더에)
//			입력체크-이름이나 나이를 입력안하면 경고메세지후 메서드 종료

//			if(txtName.getText()=="" || txtAge.getText()=="")
//			{
//				JOptionPane.showMessageDialog(this, "경고메세지 : 이름이나 나이를 입력안했어요. 이름이나 나이를 입력하세요.");
//				return;
//			}
//			
//			FileWriter fw=null;
//			try {
//				fw=new FileWriter("C:\\java0901\\"+txtName.getText()+".txt");
//				fw.write(imageName+"\n");
//				fw.write(txtName.getText()+"\n");
//				fw.write(comboBlood.getSelectedItem()+"\n");
//				fw.write(txtAge.getText()+"\n");
//				
//				photoImage=new ImageIcon("C:\\java0901\\image\\귀여운 아이콘\\c1.png").getImage();
//				myPhoto.repaint();
//				
//				txtName.setText("");
//				txtAge.setText("");
//				
//				comboBlood.setSelectedIndex(0);
//				
//			} catch (IOException e1) {
//				// TODO Auto-generated catch block
//				e1.printStackTrace();
//			} finally {
//				if(fw!=null)
//					try {
//						fw.close();
//					} catch (IOException e1) {
//						// TODO Auto-generated catch block
//						e1.printStackTrace();
//					}
//			}
////			파일에 한줄에 정보한개씩
//			이미지명(첫줄),이름(2번째줄),혈액형(3번째줄),나이(4번째줄)에 저장

//			이미지는 처음 이미지로 초기화. 이름과 나이는 지우고,
//			혈액형은 다시 1번째꺼로 초기화

			String name = txtName.getText().trim();// trim():양쪽 공백제거
			String blood = comboBlood.getSelectedItem().toString();
			String age = txtAge.getText().trim();
			if (name.length() == 0) {
				JOptionPane.showMessageDialog(this, "이름을 입력해주세요");
				txtName.requestFocus();
				return;
			}
			if (age.length() == 0) {
				JOptionPane.showMessageDialog(this, "나이를 입력해주세요");
				txtAge.requestFocus();
				return;
			}
			
			
			FileWriter fw = null;
			try {
				int iage = Integer.parseInt(age);
				fw = new FileWriter("C:\\java0901\\" + name + ".txt");
//				저장
				fw.write(imageName + "\n");
				fw.write(name + "\n");
				fw.write(blood + "\n");
				fw.write(age + "\n");
			} catch (IOException e1) {
				// TODO Auto-generated catch block
				e1.printStackTrace();
			} catch (NumberFormatException e2) {
				JOptionPane.showMessageDialog(this, "나이는 정수만 입력해주세요");
				e2.printStackTrace();
			} finally {
				try {
					if (fw != null) fw.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
			}

			photoImage = new ImageIcon("C:\\java0901\\image\\귀여운 아이콘\\c1.png").getImage();
			myPhoto.repaint();
			txtName.setText("");
			txtAge.setText("");
			comboBlood.setSelectedIndex(0);

		} else if (ob == btnOpen)// 정보 가져오기
		{
//			해당 이름으로 된 파일을 불러오면 그 데이타로
//			사진,이름,혈액형,나이가 변경되도록 한다
			FileReader fr = null;
			BufferedReader br = null;
			FileDialog dlg = new FileDialog(this, "파일열기", FileDialog.LOAD);
			dlg.setVisible(true);
			if (dlg.getDirectory() != null) {
				String fileName = dlg.getDirectory() + dlg.getFile();
				try {
					fr = new FileReader(fileName);
					br = new BufferedReader(fr);
//					1번째 데이타는 사진명
					imageName = br.readLine();// 사진명
//					System.out.println("가져올 정보 중 사진명 : " + imageName);
					photoImage = new ImageIcon(imageName).getImage();
					myPhoto.repaint();

//					2번째 데이타는 이름
					String name = br.readLine();
					txtName.setText(name);

//					3번째-혈액형
					String blood = br.readLine();
					comboBlood.setSelectedItem(blood);

//					4번째-나이
					String age = br.readLine();
					txtAge.setText(age);

				} catch (FileNotFoundException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				} finally {
					try {
						if (br != null)
							br.close();
						if (fr != null)
							fr.close();
					} catch (IOException e1) {
						// TODO: handle exception
					}
				}

			}
		}
	}

//	사진을 출력할 캔바스내부클래스
	class MyPhoto extends Canvas {
		@Override
		public void paint(Graphics g) {
			// TODO Auto-generated method stub
			super.paint(g);
			g.drawImage(photoImage, 10, 10, 120, 150, this);
		}
	}

	public void setDesign() {
		this.setLayout(null);
//		사진 버튼
		btnPhoto = new JButton("사진가져오기");
		btnPhoto.setBounds(20, 20, 120, 25);
		this.add(btnPhoto);
		btnPhoto.addActionListener(this);

//		사진 출력
//		임시사진 일단 출력하기
		photoImage = new ImageIcon("C:\\java0901\\image\\귀여운 아이콘\\c1.png").getImage();
		myPhoto = new MyPhoto();// 내부 클래스 생성
		myPhoto.setBounds(20, 50, 120, 150);
		this.add(myPhoto);

//		사진 우측으로 이름,혈액형 나이 입력
		JLabel lbl1 = new JLabel("이름");
		lbl1.setBounds(190, 30, 50, 25);
		this.add(lbl1);

		JLabel lbl2 = new JLabel("혈액형");
		lbl2.setBounds(190, 80, 50, 25);
		this.add(lbl2);

		JLabel lbl3 = new JLabel("나이");
		lbl3.setBounds(190, 130, 50, 25);
		this.add(lbl3);

		txtName = new JTextField();
		txtName.setBounds(260, 30, 60, 25);
		this.add(txtName);

		String[] blood = { "A", "B", "O", "AB" };
		comboBlood = new JComboBox<String>(blood);
		comboBlood.setBounds(260, 80, 80, 25);
		this.add(comboBlood);

		txtAge = new JTextField();
		txtAge.setBounds(260, 130, 60, 25);
		this.add(txtAge);

//		버튼 2개
		btnSave = new JButton("고객정보저장");
		btnSave.setBounds(50, 230, 130, 50);
		btnSave.setBackground(Color.red);
		btnSave.setForeground(Color.yellow);
		btnSave.addActionListener(this);// 이벤트
		this.add(btnSave);

		btnOpen = new JButton("고객정보가져오기");
		btnOpen.setBounds(200, 230, 150, 50);
		btnOpen.setBackground(Color.orange);
		btnOpen.setForeground(Color.blue);
		btnOpen.addActionListener(this);// 이벤트
		this.add(btnOpen);
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		new Ex2PhotoInfoSave("고객정보관리");
	}

}

위 코드를 본다.

finally {
    try {
        if (br != null)
            br.close();
        if (fr != null)
            fr.close();
    } catch (IOException e1) {
        // TODO: handle exception
    }
}

void java.io.BufferedReader.close() throws IOException

void java.io.InputStreamReader.close() throws IOException

를 보면

close() 메서드는 만약에 입출력 오류가 생기면 

입출력 예외를 던진다. 그런데 어떤 경우에 입출력 오류가 생긴다는 것인지 본 적이 없다.


두 가지 경우가 있을 수 있다고 한다.


1. 버퍼안에는 아직도 가득차서 왈칵 흘러나올 데이타들이 있는데 네트워크 연결을 잃게 되는 경우다.

 

2. 버퍼 내에 쏴 흘러나오게 될 데이타가 여전히 있을 때 파일 시스템 작업을 수행할 수 있는 메모리가 만원이 되었을 경우(즉, 파일 크기에 대한 사용자의 사용 가능 제한량에 도달했을 경우)다.


두 경우 모두 버퍼 안에 아직 데이타가 있는 동안 

무언가 문제가 일어난다.

 

close() 메서드는

파일이 닫히기 전에

버퍼를 flush(버퍼 내의 내용물을 왈칵 흘러내보내 비워준다.)한다.

 

그래서 만약에 데이타를 파일에 쓸 때 오류가 나면 close() 메서드는 입출력예외를 던진다.

 

두 가지 경우를 찾아보는데 시간이 걸렸다. close() 메서드가 파일이 닫히기 전에 버퍼를 비워준다고 했다.

그렇다면 어떤 IOException 이 발생했다면, 결국 이 때에도 finally 문으로 간다.

BufferedReader 객체 br 과 FileReader 객체 fr 이 생성은 되었다고 한다.

그런데 입출력예외가 발생해서 br 과 fr 은 널값은 아니다.

if (br != null)
	br.close();

그래서 위의 코드와 같이 close() 메서드를 수행한다. 하지만 작업하는 중간에 입출력예외가 발생했다고 하면, 버퍼에는 오류가 발생하기 전까지의 데이타가 채워져 있다. 그러면 그 것을 비워주어야 하는데 비워주는 것은 close() 메서드가 대신한다. 왜냐하면 close() 함수가 내부적으로 flush() 메서드를 호출하기 때문이다. 그리고 나서 파일을 닫는다고 한다. 파일을 닫아야 하는데 입출력예외(네트워크 연결이 끊기거나 파일 시스템 작업 수행 가능 메모리 부족이 생기는 때이다.)가 발생하여서 파일이 종료되고 닫혀서 닫을 작업을 할 대상이 없어서 또 다시 입출력예외가 close() 메서드에서 던져지는 듯 하다..