
Notepad_Java_Version.png
這個(gè)小玩意兒是寒假第二個(gè)小工程了,用了兩個(gè)晚上搞定。第一個(gè)是我的個(gè)人博客頁(yè)面的重寫,歡迎去踩O(∩_∩)Ohttp://taxuewwl.github.io。
這次還是使用了Java編寫,使用了swing,雖然是線程不安全的,不過(guò)比起awt還是有很多優(yōu)點(diǎn)的。
第一個(gè)版本實(shí)現(xiàn)了文檔的打開(kāi)、關(guān)閉、編輯以及保存?;旧蠈?shí)現(xiàn)了一個(gè)記事本所具有的主要功能。廢話不多說(shuō),用代碼進(jìn)行講解吧。
import java.awt.BorderLayout;
import java.awt.FileDialog;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.*;
public class MainFrame extends JFrame{
//設(shè)置組件
private JMenuBar menuBar;
private JMenu fileMenu;
private JMenu helpMenu;
private JTextArea jTextArea;
private JScrollPane jScrollPane;
private JMenuItem openItem, closeItem, saveItem,aboutItem;
private FileDialog open,save;
private File file;
MainFrame() {
Init();
}
這段代碼基本上交代了我的想法,將界面的設(shè)置以及組件添加放到一個(gè)方法中,便于后續(xù)修改及新功能添加。
能看到主要聲明了下拉菜單及其菜單項(xiàng),一個(gè)文本框以及右側(cè)滾動(dòng)條。
public void Init(){
JFrame frame = new JFrame("記事本·偽");
frame.setBounds(300, 300, 700, 450);
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
menuBar = new JMenuBar();//菜單欄
fileMenu = new JMenu("文件");
helpMenu = new JMenu("幫助");
jTextArea = new JTextArea(10, 40);
Font x = new Font("Monospaced",1,20);
jTextArea.setFont(x);
jTextArea.setLineWrap(true);//到達(dá)指定寬度則換行
//應(yīng)當(dāng)首先利用構(gòu)造函數(shù)指定JScrollPane的控制對(duì)象,此處為JTextArea,然后再添加JScrollPane
//添加進(jìn)面板
jScrollPane = new JScrollPane(jTextArea);
//設(shè)置滾動(dòng)條自動(dòng)出現(xiàn)
jScrollPane.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jScrollPane.setViewportView(jTextArea);
openItem = new JMenuItem("打開(kāi)");
saveItem = new JMenuItem("保存");
closeItem = new JMenuItem("關(guān)閉");
aboutItem = new JMenuItem("關(guān)于");
//添加兩個(gè)選項(xiàng)卡到JMenu
//添加字菜單項(xiàng)到菜單項(xiàng)
menuBar.add(fileMenu);
menuBar.add(helpMenu);
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(closeItem);
helpMenu.add(aboutItem);
//放置菜單項(xiàng)及輸入框
frame.add(menuBar, BorderLayout.NORTH);
frame.add(jScrollPane, BorderLayout.CENTER);
//添加對(duì)話框,參見(jiàn)API文檔Dialog構(gòu)造方法 ;
//FileDialog 類顯示一個(gè)對(duì)話框窗口,用戶可以從中選擇文件。
//由于它是一個(gè)模式對(duì)話框,當(dāng)應(yīng)用程序調(diào)用其 show 方法來(lái)顯示對(duì)話框時(shí),它將阻塞其余應(yīng)用程序,直到用戶選擇一個(gè)文件。
open = new FileDialog(frame,"打開(kāi)文檔",FileDialog.LOAD);
save = new FileDialog(frame,"保存文檔",FileDialog.SAVE);
Event();
frame.setVisible(true);
}
這一堆代碼是將組件添加進(jìn)了面板,由于是swing,便使用了JFrame,自帶部分事件監(jiān)聽(tīng),因此設(shè)置了關(guān)閉方式為EXIT_ON_CLOSE。
這里有一個(gè)小插曲,糾結(jié)了二十分鐘。
問(wèn)題發(fā)生在JScrollPane的添加。我原來(lái)的想法是將其指定為文本框的一個(gè)子組件,然后再將文本框添加到框架中。代碼如下
jScrollPane = new JScrollPane(jTextArea);
Container container=frame.getContentPane();
container.add(scroll,BorderLayout.EAST);
但是我這樣做之后發(fā)現(xiàn)滾動(dòng)條被文本框覆蓋。想到是否為添加順序問(wèn)題,便進(jìn)行了幾次調(diào)整,發(fā)現(xiàn)問(wèn)題依舊。
查找API文檔后才發(fā)現(xiàn)是我的想法錯(cuò)了,應(yīng)當(dāng)為JScrollPane指定目標(biāo),然后添加JScrollPane,也就是說(shuō)我的想法正好是相反的。修改后的代碼如下
jScrollPane = new JScrollPane(jTextArea);
...
frame.add(jScrollPane, BorderLayout.CENTER);
接著看代碼
public void Event() {
closeItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
aboutItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "仿記事本\n實(shí)現(xiàn)打開(kāi),關(guān)閉,保存及編輯文本\n"
+ "made by SnoWalker(踏雪無(wú)痕)\nwudi911psyou@gmail.com");
}
});
openItem.addActionListener(new ActionListener()//菜單條目監(jiān)聽(tīng):打開(kāi)
{
public void actionPerformed(ActionEvent e)
{
open.setVisible(true);
String dirPath = open.getDirectory();//獲取對(duì)話框目錄;FileDialog類的方法
String fileName= open.getFile(); //獲取對(duì)話框選定文件
if(dirPath==null || fileName==null) //點(diǎn)取消
return;
jTextArea.setText("");//打開(kāi)文件之前清空文本區(qū)域
file = new File(dirPath,fileName);
try
{
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while ((line=br.readLine()) !=null)
{
//將給定文本追加到文檔結(jié)尾。如果模型為 null 或者字符串為 null 或空,則不執(zhí)行任何操作。
//雖然大多數(shù) Swing 方法不是線程安全的,但此方法是線程安全的。
jTextArea.append(line+"\r\n");
}
}
catch (IOException ie){
throw new RuntimeException("讀取失?。?);
}
}
});
saveItem.addActionListener(new ActionListener()//菜單條目監(jiān)聽(tīng):保存
{
public void actionPerformed(ActionEvent e)
{
if(file==null)
{
save.setVisible(true);
String dirPath = save.getDirectory();
String fileName= save.getFile();
if(dirPath==null || fileName==null)
return;
file = new File(dirPath,fileName);
}
try
{
BufferedWriter bw = new BufferedWriter(new FileWriter(file));
String text = jTextArea.getText();
bw.write(text);
bw.close();
}
catch (IOException ex)
{
throw new RuntimeException();
}
}
});
}
public static void main(String[] args){
new MainFrame();
}
}