第十三周课程总结
本周老师讲解了运用JFrame,JMenu,JMenuBar,JMenuItem,JTextArea,JScrollPane,JFileChooser等这些组件来写一个简单的日记本。
前期的准备工作编辑图形界面
public class BookDemo implements ActionListener{
private JFrame frame;
private JMenu fileMenu,editMenu;//菜单
private JMenuBar bar;//存放菜单的组件
private JMenuItem newItem,openItem,saveItem,saveasItem,closeItem;//在菜单中创建新的菜单项
private JTextArea area;//定义一个文本域
private ImageIcon newIcon,openIcon,saveIcon,saveasIcon,closeIcon;
private JScrollPane scroll;//定义一个滚动条
JFileChooser chooser;
File file;
FileDialog savedia;
public BookDemo(){
frame = new JFrame("记事本");
fileMenu = new JMenu("文件");
bar = new JMenuBar();
editMenu = new JMenu("编辑");
newItem = new JMenuItem("新建(N)");
openItem = new JMenuItem("打开(O)");
saveItem = new JMenuItem("保存(S)");
saveasItem = new JMenuItem("另存为(A)");
closeItem = new JMenuItem("关闭(X)");
//在菜单项上加入图片
newIcon = new ImageIcon("d:" + File.separator + "image1" + File.separator + "1.png");
openIcon = new ImageIcon("d:" + File.separator + "image1" + File.separator + "2.png");
saveIcon = new ImageIcon("d:" + File.separator + "image1" + File.separator + "3.png");
saveasIcon = new ImageIcon("d:" + File.separator + "image1" + File.separator + "4.png");
closeIcon = new ImageIcon("d:" + File.separator + "image1" + File.separator + "5.png");
newItem = new JMenuItem("新建(N)", newIcon);
openItem = new JMenuItem("打开(O)", openIcon);
saveItem = new JMenuItem("保存(S)", saveIcon);
saveasItem = new JMenuItem("另存为(A)", saveIcon);
closeItem = new JMenuItem("关闭(X)", closeIcon);
//加入可编辑的文本域,并根据自身需要加入垂直和水平的滚动条
area = new JTextArea();
scroll = new JScrollPane(area,JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
//添加文件菜单和编辑菜单
bar.add(fileMenu);
bar.add(editMenu);
//在文件菜单上添加菜单项
fileMenu.add(newItem);
fileMenu.add(openItem);
fileMenu.add(saveItem);
fileMenu.add(saveasItem);
fileMenu.add(closeItem);
//添加菜单项的助记符
newItem.setMnemonic(KeyEvent.VK_N);
openItem.setMnemonic(KeyEvent.VK_O);
saveItem.setMnemonic(KeyEvent.VK_S);
saveasItem.setMnemonic(KeyEvent.VK_A);
closeItem.setMnemonic(KeyEvent.VK_X);
//添加快捷键的组合键
newItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N,KeyEvent.CTRL_DOWN_MASK));
openItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O,KeyEvent.CTRL_DOWN_MASK));
saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S,KeyEvent.CTRL_DOWN_MASK));
saveasItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_A,KeyEvent.CTRL_DOWN_MASK));
closeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_X,KeyEvent.CTRL_DOWN_MASK));
//在菜单项上加入动作监听器
newItem.addActionListener(this);
openItem.addActionListener(this);
saveItem.addActionListener(this);
saveasItem.addActionListener(this);
closeItem.addActionListener(this);
area.setEditable(true);//使文本域可编辑
frame.add(scroll);
frame.setJMenuBar(bar);
frame.setVisible(true);
frame.setSize(400, 300);
}
截图
加入动作监听(发生操作时调用)
@Override
public void actionPerformed(ActionEvent event) {
Object obj = event.getSource();
if(obj instanceof JMenuItem) {
JMenuItem item = (JMenuItem) obj;
方法
首先用event.getSource(),获得一个ActionEvent事件,getSource()返回的是Object类型。
instanceof 操作符用于判断一个引用类型所引用的对象是否是一个类的实例。instanceof 操作符左边的操作元是一个引用类型,右边的操作元是一个类名或接口。
obj instanceof JMenuItem,也就是说判断这个动作事件的来源是不是菜单里面的菜单项发起的。
又因为instanceof的多态性,对于引用类型变量,Java 编译器只根据变量被显示声明的类去编译。instanceof 左边操作元被显式声明的类型与右边操作元必须是同一种类或继承关系,即位于继承树的同一个继承分支上,否则编译出错。所以JMenuItem item = (JMenuItem) obj;把obj的类型强制转换成JMenuItem。
日记本的打开功能
}else if(item == openItem) {
chooser = new JFileChooser();
chooser.showOpenDialog(null);
file = chooser.getSelectedFile();
try {
FileInputStream fis= new FileInputStream(file);
byte[] b = new byte[fis.available()];
fis.read(b);
area.append(new String(b));
fis.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
方法
要实现文件的打开功能,也就是从程序中读取数据,首先要通过文件选择框选择要打开的文件,然后将内容显示在文本区中。这里运用到了InputStreamReader,将输入的字节流变为字符流,将文件中的数据读入到程序。书上清晰的画图描述:
area.append(new String(b));是把读取的字符变为字节在文本域中显示出来。
运行截图
日记本的保存功能
}else if(item == saveItem) {
if(file!=null) {
try {
PrintStream out = new PrintStream(new FileOutputStream(file));
out.print(this.area.getText());
out.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}else if(file == null){
savedia = new FileDialog(frame,"保存",FileDialog.SAVE);
savedia.setVisible(true);
String diaPath = savedia.getDirectory();
String fileName = savedia.getFile();
if(diaPath == null ||fileName == null) {
file = new File(diaPath,fileName);
}
}
方法
保存功能也就是把文本域中的内容保存到文件,这里使用到了打印流,运用到了public PrintStream(OutputStream out)这个构造方法,是为了更方便的输出数据。
运行截图
日记本的另存为功能
}else if(item == saveasItem) {
chooser.showSaveDialog(null);
file = chooser.getSelectedFile();
if(!file.exists()) {
try {
if(!file.exists()) {
file.createNewFile();
}
FileOutputStream fos=new FileOutputStream(file);
byte[] b = area.getText().getBytes();
fos.write(b);
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
方法
另存为功能与保存功能类似,这里运用到OutputStreamWriter,将一个字符流的输出对象变为字节流的输出对象。
运行截图
学习总结
老师讲解了很多组件,包含了很多构造方法和普通方法,还是得消化吸收。总的来说,对于图形界面,有了基本的了解,如何运用学习的知识编写更厉害更漂亮的图形界面,还得反复阅读书本知识,深入思考,加上创新思维,才能做的更好。笔记本的其他功能还得继续学习。