Java Swing复习(3)JMenu,做一个文本编辑器,涉及读和写操作,事件监听,处理

时间:2021-07-16 10:52:28
package www9m11;

import java.awt.FileDialog;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;

import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;

public class TestEditor implements ActionListener {
	private JFrame jf;
	private JMenuBar jmb;
	private JTextArea jta;
	private boolean wasSaved=true;
	private String filePath;
	
	
	public TestEditor() {
		jf=new JFrame("记事本");
		jta=new JTextArea(20,50);
		jmb=new JMenuBar();
		
		String[] jmLabel={"文件","编辑","帮助"};
		
		String[][] jmiLabel={{"新建","打开","","保存","另存为","","退出"},
							 {"撤销","","剪切","复制","粘贴","","查找","替换"},
							 {"关于记事本"}};
		for (int i = 0; i < jmLabel.length; i++) {
			JMenu jm=new JMenu(jmLabel[i]);
			Object o=new Object();
			for (int j = 0; j < jmiLabel[i].length; j++) {
				if("".equals(jmiLabel[i][j])){
					jm.addSeparator();//这个是 菜单中横线分隔符号  就是在 两个菜单项的
				}else{
					JMenuItem jmi=new JMenuItem(jmiLabel[i][j]);
					jmi.addActionListener(this);
					jm.add(jmi);
				}
			}
			
			jmb.add(jm);
		}
		
	}
	
	private void init(){
		jf.setJMenuBar(jmb);
		JScrollPane jsp=new JScrollPane(jta);
		jf.add(jsp);
	}
	

	private void addEventHandler(){
		jta.getDocument().addDocumentListener(new DocumentListener() {
			@Override
			public void removeUpdate(DocumentEvent e) {
//				System.out.println("TestEditor.addEventHandler().new DocumentListener() {...}.removeUpdate()");
				wasSaved=false;
			}
			@Override
			public void insertUpdate(DocumentEvent e) {
//				System.out.println("TestEditor.addEventHandler().new DocumentListener() {...}.insertUpdate()");
				wasSaved=false;
			}
			
			@Override
			public void changedUpdate(DocumentEvent e) {
//				System.out.println("TestEditor.addEventHandler().new DocumentListener() {...}.changedUpdate()");
				wasSaved=false;
			}
		});
		
		jf.addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				if(false==wasSaved){
					int op=JOptionPane.showConfirmDialog(jf, "文件没有保存是否退出?","确认退出",JOptionPane.YES_NO_CANCEL_OPTION);
					if(op!=JOptionPane.YES_OPTION){
						return;
					}
				}
				System.exit(0);
			}
		});
	}
	
	


	@Override
	public void actionPerformed(ActionEvent e) {
		String cmd=e.getActionCommand();
		if ("退出".equals(cmd)) {
			if(false==wasSaved){
				int op=JOptionPane.showConfirmDialog(jf, "文件没有保存是否退出?","确认退出",JOptionPane.YES_NO_CANCEL_OPTION);
				if(op!=JOptionPane.YES_OPTION){
					return;
				}
			}
			System.exit(0);
		}
		if("打开".equals(cmd)){
			FileDialog fd=new FileDialog(jf, "打开",FileDialog.LOAD);
			fd.setVisible(true);
//			System.out.println(fd.getDirectory());
//			System.out.println(fd.getFile());
			if(fd.getFile()==null){
				return;
			}
			filePath=fd.getDirectory()+fd.getFile();
			
			jta.setText("");
			
			//读文件 
			BufferedReader br=null;
			try {
				br=new BufferedReader(
						new InputStreamReader(
								new FileInputStream(filePath), "gbk"));
				
				String s;
				
				while((s=br.readLine())!=null){
					jta.append(s+"\n");
				}
				
			} catch (Exception e2) {
				e2.printStackTrace();
				JOptionPane.showMessageDialog(jf, "打开文件失败");
			} finally {
				if(br!=null){
					try {
						br.close();
					} catch (IOException e1) {
						e1.printStackTrace();
					}
				}
			}
			
			
			wasSaved=true;
			
		}
		if("另存为".equals(cmd)){
			FileDialog fd=new FileDialog(jf, "另存为", FileDialog.SAVE);
			fd.setVisible(true);
			if(fd.getFile()==null){
				return;
			}
			filePath=fd.getDirectory()+fd.getFile();
			
			save();
			
			wasSaved=true;
		}
		if("保存".equals(cmd)){
			if(filePath==null){
				FileDialog fd=new FileDialog(jf, "另存为", FileDialog.SAVE);
				fd.setVisible(true);
				if(fd.getFile()==null){
					return;
				}
				filePath=fd.getDirectory()+fd.getFile();
			}
			save();
			wasSaved=true;
		}
	}
	
	
	
	
	private void save(){
		//写文件
		PrintWriter pw=null;
		try {
			pw=new PrintWriter(new File(filePath),"gbk");
			
			pw.print(jta.getText());
			
		} catch (Exception e2) {
			e2.printStackTrace();
			JOptionPane.showMessageDialog(jf, "另存为失败");
		} finally {
			if(pw!=null){
				pw.close();
			}
		}
	}
	
	public void show(){
		init();
		addEventHandler();
		jf.pack();
		jf.setVisible(true);
		jf.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
	}
	
	public static void main(String[] args) {
		new TestEditor().show();
	}
}

 
 
//new一个菜单栏
JMenuBar jmb = new JMenuBar();
 
//new一个20行50列的文本域   
 JTexAREA jta = new JTextArea(20,50);
//new一个菜单
fpr(int i=0;i<jmLaber.length;i++){
   Jmenu jm = new JMenu(jmLaber[i]);

//在一个菜单下new一个菜单项,并未菜单项添加监听器
for(int j=0;j<jmiLaber[i].length;j++){
    JMenuItem jmi = new JMenuItem(jmiLaber[i][j]);
    //添加监听器
    jmi.addActionListener(this);
    jm.add(jmi);
}
//n如果菜单项之间需要分割线
    jm。addSeparator();
//把一个一个的菜单添加到菜单栏中
jmb.add(jm);
//把菜单栏添加到窗口中,把文本域添加到滚动面板,再把滚动面板添加到窗口中
    jf.setJMenuBar(jmb);
    JScrollPane jsp = new JScrollPane(jta);
    jf.add(jsp);
  
添加文本域的监听
jta.getDocument().addDocumentListener(new DocumentListner(){
//在监听里面添加各种事件情况
 private void removeUpdate(DocumentEvent e){}
 private void insertUpadate(DocumentEvent e){}
private void changedUpdate(DocumentEvent e){}
});

添加窗口的监听

jf.addWindowListener(new WindowAdatpter(){
@Override
    public void windowClosing(WindowEvent e){
        if(false==wasSaved){
            int op = JOptionPane.showConfirmDialog(jf,"文件没有保存是否退出?","确认退出",JOptionPane.YES_NO_CANCEL_OPTION);
            if(op!=JOptionPane.YES_OPTION){
                return;
            }                
        }
            System.exit(0);
    }
});

以上两个监听事件都被写在addEventHandler()函数中

----------------------------------------------------分割线-----------------------------------------------------------------------

下面我们来说说actionPerformed,

这个是ActionListener这个接口里面的方法

用于接收操作事件的侦听器接口。对处理操作事件感兴趣的类可以实现此接口,而使用该类创建的对象可使用组件的 addActionListener 方法向该组件注册。在发生操作事件时,调用该对象的 actionPerformed 方法。

@Override
	public void actionPerformed(ActionEvent e) {
		String cmd=e.getActionCommand();
		if ("退出".equals(cmd)) {
			if(false==wasSaved){
				int op=JOptionPane.showConfirmDialog(jf, "文件没有保存是否退出?","确认退出",JOptionPane.YES_NO_CANCEL_OPTION);
				if(op!=JOptionPane.YES_OPTION){
					return;
				}
			}
			System.exit(0);
		}
                if("打开".equals(cmd)){
			FileDialog fd=new FileDialog(jf, "打开",FileDialog.LOAD);
			fd.setVisible(true);
                }
......
        }



 
 

---------------------------------------------文件的读和写操作------------------------------------------------------------

1.文件的读操作:

1.加载文件路径和文件名

    (1)加载文件目录

             FileDialog fd = new FileDialog(jf,"打开",FileDialog.LOAD);

            fd.setVisible(true);//设置窗口是否课件

    (2)得到路径和文件名


      filePath = fd.getDirectory()+fd.getFile();

2.读文件  

    (1)读入缓存BufferReader br

BufferedReader(InputStreamReader
                    (FileInputStream(filePath),"gbk")
                );

    (2)把缓存取出来

while((s=br.readLine())!=null){
    jta.append(s+"\n");
}

(3)关闭流

br.close();

2.文件的写操作

(1)得到写入路径和文件名

if("保存".equals(cmd)){
			if(filePath==null){
				FileDialog fd=new FileDialog(jf, "另存为", FileDialog.SAVE);
				fd.setVisible(true);
				if(fd.getFile()==null){
					return;
				}
				filePath=fd.getDirectory()+fd.getFile();
			}
            fd.setVisible(true);//设置窗口是否课件
              save();
        wasSaved=true;
}
}

(2)写文件,得到PrintWriter.print

private void save(){
		//写文件
		PrintWriter pw=null;
		try {
			pw=new PrintWriter(new File(filePath),"gbk");
			
			pw.print(jta.getText());
			
		} catch (Exception e2) {
			e2.printStackTrace();
			JOptionPane.showMessageDialog(jf, "另存为失败");
		} finally {
			if(pw!=null){
				pw.close();
			}
		}
	}