仿windows记事本(Java版)
返回主页
这个小玩意儿是寒假第二个小工程了,用了两个晚上搞定。第一个是我的个人博客页面的重写,欢迎去踩O(∩_∩)Ohttp://taxuewwl.github.io。
这次还是使用了Java编写,使用了swing,虽然是线程不安全的,不过比起awt还是有很多优点的。
第一个版本实现了文档的打开、关闭、编辑以及保存。基本上实现了一个记事本所具有的主要功能。废话不多说,用代码进行讲解吧。
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{
//设置组件
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();
}
这段代码基本上交代了我的想法,将界面的设置以及组件添加放到一个方法中,便于后续修改及新功能添加。
能看到主要声明了下拉菜单及其菜单项,一个文本框以及右侧滚动条。
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);//到达指定宽度则换行
//应当首先利用构造函数指定JScrollPane的控制对象,此处为JTextArea,然后再添加JScrollPane
//添加进面板
jScrollPane = new JScrollPane(jTextArea);
//设置滚动条自动出现
jScrollPane.setHorizontalScrollBarPolicy( JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
jScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
jScrollPane.setViewportView(jTextArea);
openItem = new JMenuItem("打开");
saveItem = new JMenuItem("保存");
closeItem = new JMenuItem("关闭");
aboutItem = new JMenuItem("关于");
//添加两个选项卡到JMenu
//添加字菜单项到菜单项
menuBar.add(fileMenu);
menuBar.add(helpMenu);
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(closeItem);
helpMenu.add(aboutItem);
//放置菜单项及输入框
frame.add(menuBar, BorderLayout.NORTH);
frame.add(jScrollPane, BorderLayout.CENTER);
//添加对话框,参见API文档Dialog构造方法 ;
//FileDialog 类显示一个对话框窗口,用户可以从中选择文件。
//由于它是一个模式对话框,当应用程序调用其 show 方法来显示对话框时,它将阻塞其余应用程序,直到用户选择一个文件。
open = new FileDialog(frame,"打开文档",FileDialog.LOAD);
save = new FileDialog(frame,"保存文档",FileDialog.SAVE);
Event();
frame.setVisible(true);
}
这一堆代码是将组件添加进了面板,由于是swing,便使用了JFrame,自带部分事件监听,因此设置了关闭方式为EXIT_ON_CLOSE。
这里有一个小插曲,纠结了二十分钟。
问题发生在JScrollPane的添加。我原来的想法是将其指定为文本框的一个子组件,然后再将文本框添加到框架中。代码如下
jScrollPane = new JScrollPane(jTextArea);
Container container=frame.getContentPane();
container.add(scroll,BorderLayout.EAST);
但是我这样做之后发现滚动条被文本框覆盖。想到是否为添加顺序问题,便进行了几次调整,发现问题依旧。
查找API文档后才发现是我的想法错了,应当为JScrollPane指定目标,然后添加JScrollPane,也就是说我的想法正好是相反的。修改后的代码如下
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实现打开,关闭,保存及编辑文本\n"
+ "made by SnoWalker(踏雪无痕)\nwudi911psyou@gmail.com");
}
});
openItem.addActionListener(new ActionListener()//菜单条目监听:打开
{
public void actionPerformed(ActionEvent e)
{
open.setVisible(true);
String dirPath = open.getDirectory();//获取对话框目录;FileDialog类的方法
String fileName= open.getFile(); //获取对话框选定文件
if(dirPath==null || fileName==null) //点取消
return;
jTextArea.setText("");//打开文件之前清空文本区域
file = new File(dirPath,fileName);
try
{
BufferedReader br = new BufferedReader(new FileReader(file));
String line = null;
while ((line=br.readLine()) !=null)
{
//将给定文本追加到文档结尾。如果模型为 null 或者字符串为 null 或空,则不执行任何操作。
//虽然大多数 Swing 方法不是线程安全的,但此方法是线程安全的。
jTextArea.append(line+"\r\n");
}
}
catch (IOException ie){
throw new RuntimeException("读取失败!");
}
}
});
saveItem.addActionListener(new ActionListener()//菜单条目监听:保存
{
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();
}
}