원2 2021. 4. 19. 16:19
728x90
반응형

Bank 안에 myBank를 문서로 만들어서 저장하고 로드하는 파일을 만들 수 있게 하는 코드를 만들면 자동으로 생성.

package javaProject;

import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.List;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Scanner;
import java.util.Set;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;

public class Bank extends JFrame {
	HashMap<String, Integer> hm = new HashMap<>(); // <이름, 돈>int 는 객체고 integer은 클래스형,잔액을 가짐
	private List list; // 다른곳에서도 쓰기 위해 필드 값으로 올렸음 전역변수.

	public Bank() {
		setTitle("Bank");
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setLayout(new GridLayout(1, 2)); // 1행 2열.
		// 왼쪽화면
		JPanel p1 = new JPanel(); // 이름있는 라인 (1번째) 패널생성, JPanel 기본 레이아웃 :FlowLayout
		p1.add(new JLabel("이름")); // add는 추가
		JTextField tfName = new JTextField(15); // 15자리 입력받기
		p1.add(tfName);

		JButton btn = new JButton("계좌생성"); // 2번째 라인

		JPanel p2 = new JPanel(); // 잔액있는 라인 (3번째)
		p2.add(new JLabel("잔액")); // 라벨 만들기
		JTextField tfBalance = new JTextField(15);
		tfBalance.setEditable(false); // 처음입력할 때 수정을 못하게 막는것.
		p2.add(tfBalance);

		JPanel p3 = new JPanel(); // 입출금 돈 입력 라인 (4번째)
		JTextField tfMoney = new JTextField(15);
		p3.add(tfMoney);
		p3.add(new JLabel("원")); // 라벨 만들기

		JPanel p4 = new JPanel(); // 입금, 출금, 파일 버튼 라인 (5번째)
		JButton inputBtn = new JButton("입금");
		JButton outBtn = new JButton("출금");
		JButton fileBtn = new JButton("파일로 저장");
		p4.add(inputBtn);
		p4.add(outBtn);
		p4.add(fileBtn);

		JPanel panel = new JPanel(); // 왼쪽을 전체로 묶어버리는 패널
		panel.add(p1);
		panel.add(btn);
		panel.add(p2);
		panel.add(p3);
		panel.add(p4);

		// 오른쪽 화면
		list = new List(); // import할때 java.util 말고 java.awt를 해줘야한다.
							// 생성자 안에 만들어서 load에서 못찾는다. List를 전역변수로 선언했음 현재.

		// JFrame에 왼쪽, 오른쪽 배치
		add(panel);
		add(list);

		// 계좌생성 : 맵에 추가 , list에 이름 출력
		btn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) { // 이름aaa를 입력하면 저장하는 곳
				if (tfName.getText().isEmpty())
					return; // isEmpty() : 공백은 return끝내버리겠다.
				// 계좌 생성버튼을 누를때, 공백값을 없애줌.
				hm.put(tfName.getText().trim(), 0); // hm : map의 객체
				// tfName.getText() : tfName에 있는 글자를 가져옴 , trim은 앞뒤 공백제거.
				list.add(tfName.getText().trim()); // list 에 추가
				tfName.setText(""); // aaaa 입력후 이름창을 지워버리는 함수
				// System.out.println(hm);
			}
		});
		// list를 클릭하면(tf) 해당 이름, 잔액 넣기.
		list.addItemListener(new ItemListener() { // aaa 입력후 계좌 생성은 ItemEvent , Listener임.

			@Override
			public void itemStateChanged(ItemEvent e) {
				String name = list.getSelectedItem().trim(); // 이름 넣기
				tfName.setText(name);

				tfBalance.setText(hm.get(name) + ""); // map hm.에 잔액이 있다. +""이 되면 문자열 출력
				tfMoney.setText("");
			}
		});

		// 입금
		inputBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				/*
				 * 리스트에 선택된 계좌 잔액에 입금한 금액을 더해서 잔액을 수정하고 map도 수정
				 */
				try { // 터지는걸 방지하고 오류부분을 보기쉽게 출력하는것.
					String name = list.getSelectedItem().trim(); // 계좌를 구해옴
					int money = Integer.parseInt(tfMoney.getText()); // 입금할 돈.
					int balance = hm.get(name) + money; // 잔액을 가져옴 기본금+추가금
					tfBalance.setText(balance + ""); // 잔액 수정 ""을 붙이는 이유 : setText는 String형
					hm.put(name, balance); // 맵 수정 put은 입력
					tfMoney.setText(""); // 입금하고 입금자리 비우기
				} catch (NumberFormatException n) {
					new MessageBox("입력 오류!!!", "숫자를 입력하세요.");
				} catch (NullPointerException n2) { // MessageBox를 사용하는 이유 :
					new MessageBox("오류!!", "계좌를 선택하세요"); // 오류창을 띄우게 하려고
				}

			}
		});

		// 출금
		outBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) {
				/*
				 * 리스트에 선택된 계좌 잔액에 출금한 금액을 빼서 잔액을 수정하고 map도 수정
				 */
				try {
					String name = list.getSelectedItem().trim();
					int money = Integer.parseInt(tfMoney.getText()); // 입력받을 돈.
					int balance = hm.get(name) - money; // 기본금-출금
					if (balance < 0) {
						// System.out.println("잔액이 부족합니다."); // 여기선 콘솔창에 뜸
						new MessageBox("잔액부족", name + "님 잔액이 부족합니다.");
						// 새 클래스 파일 MessageBox을 만들어줌
						return; // else 를 써도 되지만 안되면 return을 써서 끝내버릴 수도 있다. -2000이 안되게함.
					}
					tfBalance.setText(balance + "");
					hm.put(name, balance);
					tfMoney.setText(""); // 출금하고 출금자리 비워주기

				} catch (NumberFormatException n) { // NumberFormatException 숫자형식이 아니다.
					new MessageBox("출금 오류!!", "숫자를 입력하세요");
				} catch (NullPointerException n2) { // NullPointerException 포인터가 맞지 않다.
					new MessageBox("출금계좌오류!!", "계좌를 선택하세요");
				}

			}
		});

		// 파일로 저장 (맵 -> 파일) 이동
		fileBtn.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent e) { // ActionEvent의 변수 e
				File dir = new File("src\\javaProject"); // 파일의 위치를 찾는다.
				File file = new File(dir, "myBank.txt"); // 파일 저장 이름.

				try {
					FileWriter fw = new FileWriter(file); // 내보내는 객체 FileWriter
					Set<String> set = hm.keySet(); // map의 key값만을 추출
					Iterator<String> it = set.iterator();
					while (it.hasNext()) {
						String name = it.next();
						fw.write(name + " "); // 공백사이에 한칸 띄어야 한다.
						fw.write(hm.get(name) + "\n");
					}
					fw.close();
				} catch (IOException e1) {
					new MessageBox("오류", "파일 저장 실패");
				}
			}
		});

		setSize(500, 300);
		setVisible(true);
		load(); // 불러오기
	}

	private void load() { // 파일을 읽어서 map에 추가시키고 list에 이름 출력
		hm.clear();
		File dir = new File("src\\javaProject"); // 파일을 찾을 위치
		File file = new File(dir, "myBank.txt"); // 파일 저장할 이름.

		try {
			if (!file.exists()) { // 파일이 없다면
				file.createNewFile();
				return;
			}
			Scanner sc = new Scanner(file); // 입력받을 값
			while (sc.hasNext()) {
				String name = sc.next().trim(); // 이름
				int balance = sc.nextInt(); // 잔액
				hm.put(name, balance); // map에 추가
				list.add(name + "\n");
			}
			sc.close();
		} catch (IOException e) {
			new MessageBox("오류", "파일 로드 실패");
		}

	}

	public static void main(String[] args) {
		new Bank();

	}

}

package javaProject;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;

	// 새로운 MessageBox를 띄워주기 위해서 만듬 콘솔창에 잔액부족을 띄우지 않고 새창에 띄우려고
public class MessageBox extends JFrame{
	
	public MessageBox(String title, String msg) { // 여기의 타입을 늘려줘야 Bank의 MessageBox에도 입력가능
		setTitle(title);
		setLayout(new FlowLayout());
		JButton closeBtn = new JButton("닫기"); // 버튼의 닫기를 표시
		add(new JLabel(msg)); // 받아온 메세지를 출력
		add(closeBtn);
		closeBtn.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				dispose(); // 여기는 MessageBox만 닫게 해주는 것.
				
			}
		});
		
		setSize(300,100);
		setVisible(true);
	}
}

실행 창
입금, 출금, 파일로 저장 가능.

728x90
반응형