JFrame을 상속받고 ActionLisener로 구현한다.
생성자, initLayout, menuLayout, 필수메소드 actionPerformed와 메인으로 구성되어있다.
public class Memojang extends JFrame implements ActionListener
JPanel pn = new JPanel();
JTextArea txtMemo = new JTextArea("", 10, 30);
String copyText;
// 메뉴
JMenuItem mnuNew, mnuSave, mnuOpen, mnuExit;
JMenuItem mnuCopy, mnuPaste, mnuCut, mnuDel, mnuAbout;
public Memojang() {
super("메모장");
initLayout();
menuLayout();
setBounds(200, 200, 400, 320);
setVisible(true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e)
...
..
});
}
프레임의 기본적인 사이즈와 창닫기 기능, 메소드를 추가했다.
private void initLayout() {
JScrollPane scrollPane = new JScrollPane(txtMemo); // 스크롤바
add("Center", scrollPane);
}
private void menuLayout() {
JMenuBar menuBar = new JMenuBar();
JMenu mnuFile = new JMenu("파일");
mnuNew = new JMenuItem("새문서");
mnuOpen = new JMenuItem("열기...");
mnuSave = new JMenuItem("저장...");
mnuExit = new JMenuItem("종료");
mnuFile.add(mnuNew);
mnuFile.add(mnuOpen);
mnuFile.add(mnuSave);
mnuFile.addSeparator();
mnuFile.add(mnuExit);
JMenu mnuEdit = new JMenu("편집");
mnuCopy = new JMenuItem("복사");
mnuPaste = new JMenuItem("붙여넣기");
mnuCut = new JMenuItem("잘라내기");
mnuDel = new JMenuItem("삭제");
mnuEdit.add(mnuCopy);
mnuEdit.add(mnuPaste);
mnuEdit.add(mnuCut);
mnuEdit.add(mnuDel);
JMenu mnuHelp = new JMenu("도움말");
mnuAbout = new JMenuItem("메모장이란...");
mnuHelp.add(mnuAbout);
menuBar.add(mnuFile);
menuBar.add(mnuEdit);
menuBar.add(mnuHelp);
setJMenuBar(menuBar);
// 메뉴에 리스너 장착
mnuNew.addActionListener(this);
mnuSave.addActionListener(this);
mnuOpen.addActionListener(this);
mnuExit.addActionListener(this);
mnuCopy.addActionListener(this);
mnuPaste.addActionListener(this);
mnuCut.addActionListener(this);
mnuDel.addActionListener(this);
mnuAbout.addActionListener(this);
}
메뉴바의 기본적인 제작방법은 이러하다.
메뉴바 전체를 담을 new JMenuBar 객체 < 각메뉴별 new JMenu < 각 메뉴의 항목 new JMenuItem
구조로 차례로 만든다.
객체 생성시 매개변수로 메뉴 이름을 설정하고, .add로 상위개념의 객체에 다 넣어준다.
모든 메뉴버튼에 리스너를 장착하고 actionPerformed 의 if문에서 기능을 구현한다.
@Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == mnuCopy) {
// System.out.println(txtMemo.getSelectedText());
copyText = txtMemo.getSelectedText(); <지정 구간을 copyText에 저장>
} else if (e.getSource() == mnuPaste) {
// txtMemo.setText(copyText); <Area를 copytext내용으로 바꿈>
int position = txtMemo.getCaretPosition();<커서가 있는 지점을 찾아냄.>
txtMemo.insert(copyText, position); <삽입>
} else if (e.getSource() == mnuCut) {
copyText = txtMemo.getSelectedText();
int start = txtMemo.getSelectionStart();
int end = txtMemo.getSelectionEnd(); <범위의 시작과 끝을 변수로 저장>
txtMemo.replaceRange("", start, end);
} else if (e.getSource() == mnuDel) {
int start = txtMemo.getSelectionStart();
int end = txtMemo.getSelectionEnd(); <del은 범위 내 문자를 취하지않았음>
txtMemo.replaceRange("", start, end);
} else if (e.getSource() == mnuNew) {
txtMemo.setText("");
setTitle("메모장");
} else if (e.getSource() == mnuSave) {
<경로명 및 파일명을 얻어주는 대화상자를 사용>
FileDialog dialog = new FileDialog(this, "저장", FileDialog.SAVE);
dialog.setDirectory("."); // 자기자신
dialog.setVisible(true);
if (dialog.getFile() == null)
return; <이름을 지정하지 않았으면 메소드 탈출>
String dfName = dialog.getDirectory() + dialog.getFile();
<경로와 파일명을 대화상자에서 얻어 String에 저장>
try { // 저장작업은 이곳에서..
BufferedWriter writer = new BufferedWriter(new FileWriter(dfName));
writer.write(txtMemo.getText()); // 저장
writer.close();
setTitle(dialog.getFile() + " - " + "메모장"); <저장시 창 이름 재설정>
} catch (Exception e2) {
System.out.println("save err :" + e);
}
} else if (e.getSource() == mnuOpen) {
FileDialog dialog = new FileDialog(this, "열기", FileDialog.LOAD);
dialog.setDirectory(".");
dialog.setVisible(true);
if (dialog.getFile() == null)
return;
String dfName = dialog.getDirectory() + dialog.getFile();
try {
BufferedReader reader = new BufferedReader(new FileReader(dfName));
txtMemo.setText(""); <열때 기존에 있던거 지워짐>
String line;
while ((line = reader.readLine()) != null) {
txtMemo.append(line + "\n"); <한라인씩 읽어서 txtMemo Area에 추가>
}
reader.close();
setTitle(dialog.getFile() + " - " + "메모장");
} catch (Exception e2) {
System.out.println("open err : " + e2);
}
} else if (e.getSource() == mnuExit) {
int re = JOptionPane.showConfirmDialog(this, "정말 종료할까요?", "종료", JOptionPane.YES_NO_OPTION);
if (re == JOptionPane.YES_OPTION)
System.exit(0);
else
return;
} else if (e.getSource() == mnuAbout) {
new MemoAbout(this);<이 창을 닫기 전까지 178라인은 읽지않음>
System.out.println("계속 진행");
}
}
복사,붙여넣기 기능을 만들기 위해
getSelectionStart와 End로 시작지점과 끝지점을 int형 변수로 저장해놓고
replaceRange로 지우거나, 대체하거나 String형 변수에 저장을 했다.
항목 별로 기능을 생각하며 넣으면 된다.
알고리즘은 물론이고 메소드의 사용법을 먼저 알아보고 적절히 사용해야 할거같다.
내장되어 있는 대화상자도 불러와봤는데, 이는 세이브 로드 기능이 기본적으로 있는게 아닌 파일의 경로만 반환해주기 때문에 그 반환값을 FileReader, FileWriter를 사용해서 기능을 구현해야한다.
프레임 사용 중에도 추가적인 창을 띄워야 할때가 있다.
이럴땐 클래스를 더 만들어서 JDialog를 상속시켜 만든다.
public class MemoAbout extends JDialog implements ActionListener
public MemoAbout(JFrame frame) {
super(frame); <매개변수로 부모타입을 넘겨받을예정>
setTitle("메모장이란");
setModal(true); <true면 다른작업을 못함>
JLabel lbl = new JLabel("Mini Memojang ver 0.9");
JButton btn = new JButton("닫기");
btn.addActionListener(this);
add("Center",lbl);
add("South",btn);
setBackground(Color.lightGray);
setBounds(350,350,150,150);
setVisible(true);
}
@Override
public void actionPerformed(ActionEvent e) {
dispose(); <dialog닫기>
}
간단히 정보표시의 기능만 하기때문에 코드는 간단함
여기서 setModal 기능에 집중해야하는데,
작업중 setModal이 적용된 창이 뜨면 뜬 창에서 작업을 끝내기 전까지는 이전 창을 조작할 수 없는 기능이다. 눈으로만 조작할 수 없는것이 아닌 시스템에서도 다음 줄을 읽지않는다.