Java文本编辑器实现方法详解

本文实例讲述了Java文本编辑器实现方法。分享给大家供大家参考,具体如下:

结构分析:

  • 界面布局 : EditFrame
  • main方法所在: EditText
  • 打开功能实现:  FileReadThread
  • 保存跟能实现:  save

实际运行效果:

附:完整代码实现

一、 EditFrame

包括一个菜单Menu

底部:日期时间

代码附上:

public class EditFrame extends JFrame {
 // TODO 自动生成的构造函数存根
 boolean saveFlag = false;
 File saveFileRoot = null;
 JFrame jFrame;
 JPanel jPanelSouth;
 JMenuBar jMenuBar1;
 JMenu jMenu1;
 JMenuItem jMenuItem1;
 JMenuItem jMenuItem2;
 JMenuItem jMenuItem3;
 JMenuItem jMenuItem4;
 JSeparator jSeparator1;
 JTextArea jTextArea;
 JScrollPane scrollPane;// 滚动条
 public EditFrame() {
 // TODO 自动生成的构造函数存根
 jFrame = new JFrame("水中鱼之1999-文本编辑器");
 jPanelSouth = new JPanel();
 jMenuBar1 = new JMenuBar();
 jMenu1 = new JMenu("文件");
 jMenuItem1 = new JMenuItem("打开");
 jMenuItem2 = new JMenuItem("保存");
 jMenuItem3 = new JMenuItem("另存为");
 jMenuItem4 = new JMenuItem("退出");
 jSeparator1 = new JSeparator();
 jTextArea = new JTextArea();
 scrollPane = new JScrollPane(jTextArea);
 jFrame.setSize(800, 500);
 jFrame.setLocationRelativeTo(null);
 jFrame.setVisible(false);

 setLayout();
 setSouthPanel();
 // set relationship for your component
 setRelationShip();
 // 设置 scrollPane for TextArea
 setScscrollPane();
 iniClick();
 }
 private void setRelationShip() {
 jFrame.add(BorderLayout.CENTER, scrollPane);
 jFrame.add(BorderLayout.SOUTH, jPanelSouth);
 jMenu1.add(jMenuItem1);
 jMenu1.add(jMenuItem2);
 jMenu1.add(jMenuItem3);
 jMenu1.add(jSeparator1);
 jMenu1.add(jMenuItem4);
 jMenuBar1.add(jMenu1);
 jFrame.setJMenuBar(jMenuBar1);
 }
 private void setLayout() {
 GridLayout gridLayout = new GridLayout(1, 2);
 jPanelSouth.setLayout(gridLayout);
 }
 private void setScscrollPane() {
// jTextArea.setLineWrap(true);// 设置满一行自动换行
 scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
 scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
 }
 private void setSouthPanel() {
 // add time for SouthPanel
 JLabel jLabelDate = new JLabel("Date");
 JLabel jLabelTime = new JLabel("Time");
 Timer timeAction = new Timer(1000, new ActionListener() {
  public void actionPerformed(ActionEvent e) {
  long timemillis = System.currentTimeMillis();
  // 转换日期显示格式
  SimpleDateFormat date = new SimpleDateFormat("yyyy 年 MM 月 dd 日 ");
  jLabelDate.setText("  当前日期: " + date.format(new Date(timemillis)));
  SimpleDateFormat time = new SimpleDateFormat("HH:mm:ss ");
  jLabelTime.setText("  当前时间: " + time.format(new Date(timemillis)));
  }
 });
 jPanelSouth.add(jLabelDate);
 jPanelSouth.add(jLabelTime);
 timeAction.start();
 }
 private void iniClick() {
 jFrame.addWindowListener(new WindowListener() {
  @Override
  public void windowOpened(WindowEvent e) {
  // TODO Auto-generated method stub
  }
  @Override
  public void windowIconified(WindowEvent e) {
  // TODO Auto-generated method stub
  }
  @Override
  public void windowDeiconified(WindowEvent e) {
  // TODO Auto-generated method stub
  }
  @Override
  public void windowDeactivated(WindowEvent e) {
  // TODO Auto-generated method stub
  }
  @Override
  public void windowClosing(WindowEvent e) {
  // TODO Auto-generated method stub
  int x = JOptionPane.showConfirmDialog(null, "确认退出么?", "友情提示", JOptionPane.OK_CANCEL_OPTION,
   JOptionPane.WARNING_MESSAGE);
  if (x == 0) {
   System.exit(0);
  }
  }
  @Override
  public void windowClosed(WindowEvent e) {
  // TODO Auto-generated method stub
  }
  @Override
  public void windowActivated(WindowEvent e) {
  // TODO Auto-generated method stub
  }
 });
 jMenuItem4.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
  // TODO Auto-generated method stub
  int x = JOptionPane.showConfirmDialog(null, "确认退出么?", "友情提示", JOptionPane.OK_CANCEL_OPTION,
   JOptionPane.WARNING_MESSAGE);
  if (x == 0) {
   System.exit(0);
  }
  }
 });
 jMenuItem1.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
  // TODO Auto-generated method stub
  FileReadThread fileReadThread = new FileReadThread(EditFrame.this);// 开启文件读取线程
  fileReadThread.start();
  System.out.println(saveFileRoot);
  saveFlag = true;
  jTextArea.setText("");
  }
 });
 jMenuItem3.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
  // TODO Auto-generated method stub
  Save save = new Save(EditFrame.this);
  save.start();
  saveFlag = true;
  }
 });
 jMenuItem2.addActionListener(new ActionListener() {
  @Override
  public void actionPerformed(ActionEvent e) {
  // TODO Auto-generated method stub
  if (!saveFlag) {
   Save save = new Save(EditFrame.this);
   save.start();
   saveFlag = true;
  } else {
   new Save(EditFrame.this, saveFileRoot);
  }
  }
 });
 }
 public JTextArea getjTextArea() {
 return jTextArea;
 }
 public void setjTextArea(JTextArea jTextArea) {
 this.jTextArea = jTextArea;
 }
 public File getSaveFileRoot() {
 return saveFileRoot;
 }
 public void setSaveFileRoot(File saveFileRoot) {
 this.saveFileRoot = saveFileRoot;
 }
 public JFrame getjFrame() {
 return jFrame;
 }
 public void setjFrame(JFrame jFrame) {
 this.jFrame = jFrame;
 }
}

二、测试类 EditText

分两部分:

1.闪屏 由于加载页面需要时间 原想用 SplashScreen 由于打包成jar包才能用所以这里用jframe进行替代

闪屏图片直接粘贴到:

2.new 一个EditFrame 对象, 闪屏结束后设置为可见

public class EditText {
 public static void main(String[] args) {
 new Thread() {
  @Override
  public void run() {
  // TODO Auto-generated method stub
  EditFrame editFrame = new EditFrame();

  JFrame jFrame = new JFrame();
  JPanel jPanel = new javax.swing.JPanel(){
    protected void paintComponent(java.awt.Graphics g){
      super.paintComponent(g);
      g.drawImage(new ImageIcon("experiment_bac.jpg").getImage(),0,0,400,250,null);
    }
  };
  jFrame.add(jPanel);
  jFrame.setVisible(true);
  jFrame.setSize(400, 300);
  jFrame.setLocationRelativeTo(null);

  try {
   sleep(1500);
  } catch (InterruptedException e) {
   // TODO Auto-generated catch block
   e.printStackTrace();
  }
  jFrame.dispose();
  editFrame.getjFrame().setVisible(true);
  }
 }.start();
 }
}

三、FileReadThread

调用swing自带的 JFileChooser

选择文件路径

class FileReadThread extends Thread {
 private EditFrame test;
 public FileReadThread(EditFrame test ) {
 this.test = test;
 }
 @Override
 public void run() {
 JFileChooser chooser = new JFileChooser("d:/");
 chooser.setFileFilter(new FileFilter() {// 定义文件过滤器,仅显示文件夹和txt文本
  @Override
  public String getDescription() {
  return null;
  }
  @Override
  public boolean accept(File file) {
  if (file.isDirectory() || file.getName().endsWith(".txt"))
   return true;
  return false;
  }
 });
 int option = chooser.showOpenDialog(test);
 if (option == JFileChooser.APPROVE_OPTION) {
  File selFile = chooser.getSelectedFile();
  try {
  BufferedReader reader = new BufferedReader(new InputStreamReader(new FileInputStream(selFile), "gbk"));
  test.setSaveFileRoot(selFile);
  String line = null;
  while ((line = reader.readLine()) != null) {
   test.getjTextArea().append(line + "\n");
   Thread.sleep(30);// 线程暂停,以看到读取过程效果
  }
  } catch (Exception e1) {
  e1.printStackTrace();
  }
  JOptionPane.showMessageDialog(test, "读取完毕");
 }
 }
}

四、save 保存

保存的调用分三种:

  • 如果该文件是打开的 那么保存到打开文件中
  • 如果该文件还未保存 这调用:进行保存
  • 如果该文件已经另存为,则直接保存到另存为得的目录下
public class Save extends Thread {
 private EditFrame area;
 private File saveFileRoot = null;
 public Save(EditFrame area, File saveFileRoot) {
 System.out.println(saveFileRoot + "123");
 String text = area.getjTextArea().getText();
 String[] lines = text.trim().split("\n");
 try {
  PrintWriter out = new PrintWriter(new FileOutputStream(saveFileRoot), true);
  for (String line : lines)
  out.println(line);
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 }
 public Save(EditFrame area) {
 this.area = area;
 JFileChooser chooser = new JFileChooser();
 chooser.setCurrentDirectory(new File("."));
 chooser.setFileFilter(new FileFilter() {
  @Override
  public boolean accept(File f) {
  return f.getName().toLowerCase().endsWith(".txt");
  }
  @Override
  public String getDescription() {
  return "SAVE TO";
  }
 });
 int r = chooser.showSaveDialog(area);
 if (r != JFileChooser.APPROVE_OPTION)
  return;
 File f = chooser.getSelectedFile();
 area.setSaveFileRoot(f);
 String text = area.getjTextArea().getText();
 String[] lines = text.trim().split("\n");
 try {
  PrintWriter out = new PrintWriter(new FileOutputStream(f), true);
  for (String line : lines)
  out.println(line);
 } catch (FileNotFoundException e) {
  // TODO Auto-generated catch block
  e.printStackTrace();
 }
 }
 public File getSaveFileRoot() {
 return saveFileRoot;
 }
 public void setSaveFileRoot(File saveFileRoot) {
 this.saveFileRoot = saveFileRoot;
 }
}

更多关于java相关内容感兴趣的读者可查看本站专题:《Java数据结构与算法教程》、《Java字符与字符串操作技巧总结》、《Java操作DOM节点技巧总结》、《Java文件与目录操作技巧汇总》和《Java缓存操作技巧汇总》

希望本文所述对大家java程序设计有所帮助。

(0)

相关推荐

  • 在spring boot中使用java线程池ExecutorService的讲解

    1. 认识java线程池 1.1 在什么情况下使用线程池? 1.单个任务处理的时间比较短 2.需处理的任务的数量大 1.2 使用线程池的好处: 1.减少在创建和销毁线程上所花的时间以及系统资源的开销 2.如不使用线程池,有可能造成系统创建大量线程而导致消耗完系统内存 1.3 线程池包括以下四个基本组成部分: 1.线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务: 2.工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以

  • 深入理解Java高级特性——注解

    博主在初学注解的时候看到网上的介绍大部分都是直接介绍用法或者功能,没有实际的应用场景,篇幅又很长导致学习的时候难以理解其意图,而且学完就忘QAQ.本篇文章中我将结合实际的应用场景尽可能由浅入深,平缓的介绍java注解. java注解是jdk1.5以后新出的特性,对于它的应用非常广泛,我们首先来看一下注解的应用,百度百科上这样说: 我们可以看到,注解的作用有三方面: 编写doc文档:这个就我们很常用的 @return 以及 @author,加了这些注解以后,就可以用jdk帮我们自动生成对应的API

  • JavaScript碎片—函数闭包(模拟面向对象)

    经过这几天的博客浏览,让我见识大涨,其中有一篇让我感触犹深,JavaScript语言本身是没有面向对象的,但是那些大神们却深深的模拟出来了面向对象,让我震撼不已.本篇博客就是在此基础上加上自己的认知,如有错误,还请见谅. 具体来说实现模拟面向对象主要是利用JavaScript函数闭包这个概念.由于JavaScript中的每一个function都会形成一个作用域,而如果变量声明在这个域中,那么外部是无法直接去访问,要想访问必须new出一个实例来,相当于Java中class.首先让我们来了解一下pr

  • Java掩码的几种使用例举

    java掩码 private static String nameMask(String name) throws Exception { if(name ==null)throw new Exception("请输入要掩码的字符串"); if(name.length()<=1) return name+"*"; return name.replaceAll("([\\u4e00-\\u9fa5]{1})(.*)", "$1&qu

  • Java抛出异常与自定义异常类应用示例

    本文实例讲述了Java抛出异常与自定义异常类.分享给大家供大家参考,具体如下: 异常处理常用方法: 常用的异常处理方法有: 一.try()catch() 语句 二.throw / throws 语句 三.自定义异常类 用途: 众所周知,当程序运行过程中,如果遇到了错误(比如数组下标越界,空指针等)程序就会自动终止,但这种错误一般是偶然的,可能是用户输入不呵呵程序编写者的意图导致,而不是程序本身问题,这是我们要做的,是让操作者知道发生了什么事情,而不是直截了当的结束程序,这时我们就用到了异常处理(

  • 浅谈Java之终止继承:Final类和Fianl方法

    前言 关键字Final不仅可以用来修饰变量,而且对类及其方法的继承也有很大的影响,本文将从类与方法两个方面介绍final关键字的功能. Final类 当关键字final用来修饰类时,其含义是该类不能再派生子类,换句话说,任何其他类都不能继承用final修饰的类,即使该类的访问权限为pubilc类型,也不能被继承:否则,将编译报错. 只有当需要确保类中的方法都不被重写时才应该建立最终(final)类,final关键字将会为这些方法提供安全,没有任何人能够重写final类中的方法,因为不能继承. 例

  • java与php的区别浅析

    java的简单介绍 Java是一种通用的面向对象编程语言,旨在生成可在任何地方使用相同代码的代码.这种编程语言是基于类的,面向对象的和人类可读的.它支持服务器端和客户端. Java既可以编译也可以解释.Java编译器将源代码转换为字节码,然后java解释器生成机器代码,该机器代码由运行java程序的机器直接执行.它可靠,分布式,便携.它可用于开发独立应用程序或基于Web的应用程序. PHP的简单介绍 PHP被称为超文本预处理器,它是一种服务器端脚本语言.它是一种动态类型语言,不需要编译代码:它是

  • Java实现的矩阵乘法示例

    本文实例讲述了Java实现的矩阵乘法.分享给大家供大家参考,具体如下: 思路: 矩阵乘法的前提是:前一矩阵的行数 == 后一矩阵的列数(rows == cols) 在满足前提的情况下:前一矩阵的第一行 与 第二个矩阵的第一列 逐个相乘.将乘积求和 作为 结果矩阵的第一个元素 类推刻得到:结果矩阵的 第 [row][col] 个元素 = 前一矩阵的第 row 行 与 后一矩阵的 col列上的元素 逐一相乘 后的乘积之和 代码及解析: 一.算法剖析: 1.设置两个for循环用来控制结果(输出)矩阵的

  • Java位掩码控制权限与(&)或(|)非(~)、>的介绍

    1. java 位掩码 java 位掩码,在java开发中很少有场景会用到掩码,但是当系统中需要判断某个对象是否有 某些权限时,可以通过位掩码来做. 位掩码 主要通过位运算,例如与(&).非(~).或(|).异或(^).移位(<<和>>)等来实现 权限判断功能. 1.1 简单介绍一下位运算符(计算均为二进制计算) << : 左移运算符,num << 1,相当于num乘以2 >> : 右移运算符,num >> 1,相当于num除

  • 详解java并发之重入锁-ReentrantLock

    前言 目前主流的锁有两种,一种是synchronized,另一种就是ReentrantLock,JDK优化到现在目前为止synchronized的性能已经和重入锁不分伯仲了,但是重入锁的功能和灵活性要比这个关键字多的多,所以重入锁是可以完全替代synchronized关键字的.下面就来介绍这个重入锁. 正文 ReentrantLock重入锁是Lock接口里最重要的实现,也是在实际开发中应用最多的一个,我这篇文章更接近实际开发的应用场景,为开发者提供直接上手应用.所以不是所有方法我都讲解,有些冷门

随机推荐