[java]代码库
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTabbedPane;
import javax.swing.JTable;
import javax.swing.JTextArea;
import javax.swing.JToolBar;
import javax.swing.JTree;
import javax.swing.Timer;
import javax.swing.border.BevelBorder;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.text.BadLocationException;
import javax.swing.tree.DefaultMutableTreeNode;
/**
* 一个简单的文本编辑器,能够编辑html、java、cpp、txt文件, 并支持java的编译与运行
*/
public class SimpleEditor extends JFrame {
/******** 菜单栏、菜单和菜单项 *********/
JMenuBar menuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenu optionMenu = new JMenu("Option");
JMenu advanceMenu = new JMenu("Advance");
JMenu helpMenu = new JMenu("Help");
JMenu editMenu = new JMenu("Edit");
JMenuItem newMenuItem = new JMenuItem("new");
JMenuItem openMenuItem = new JMenuItem("Open");
JMenuItem saveMenuItem = new JMenuItem("Save");
JMenuItem exitMenuItem = new JMenuItem("exit");
JMenuItem findMenuItem = new JMenuItem("Find");
JMenuItem findNextMenuItem = new JMenuItem("Find Next");
JMenuItem replaceMenuItem = new JMenuItem("Replace");
JMenuItem compileMenuItem = new JMenuItem("Compile");
JMenuItem buildMenuItem = new JMenuItem("Build");
JMenuItem stopFlashMenuItem = new JMenuItem("Stop Flash");
JMenuItem startFlashMenuItem = new JMenuItem("Start Flash");
JMenuItem helpMenuItem = new JMenuItem("Help");
JMenuItem copyMenuItem = new JMenuItem("Copy");
JMenuItem cutMenuItem = new JMenuItem("Cut");
JMenuItem pasteMenuItem = new JMenuItem("Paste");
/******** 文件内容的显示 ****/
// 用多个文本域存放多个文件内容,文本域放在JScrollPane里
// 而JScrollPane放在JTabbedPane中,这就是一个多页面的布局
// 多个文本域,每个文本域显示一个文件的内容
JTextArea[] fileTextAreas = new JTextArea[10];
// 编译或者运行时的控制台信息
JTextArea consoleTextArea = new JTextArea();
JScrollPane[] fileScrollPanes = new JScrollPane[10];
JScrollPane consoleScrollPane;
// 多个文本域放在不同tab里
JTabbedPane fileTabbedPane = new JTabbedPane();
/********** 工具栏以及工具栏上的按钮 **********/
JToolBar toolBar = new JToolBar();
JButton openButton = new JButton(new ImageIcon(loadImage("image/open.gif")));
JButton newButton = new JButton(new ImageIcon(loadImage("image/new.gif")));
JButton saveButton = new JButton(new ImageIcon(loadImage("image/save.gif")));
JButton helpButton = new JButton(new ImageIcon(loadImage("image/help.gif")));
JButton exitButton = new JButton(
new ImageIcon(loadImage("image/close.gif")));
JButton compileButton = new JButton(new ImageIcon(
loadImage("image/compile.gif")));
JButton buildButton = new JButton(new ImageIcon(
loadImage("image/build.gif")));
JButton copyButton = new JButton(new ImageIcon(loadImage("image/copy.gif")));
JButton cutButton = new JButton(new ImageIcon(loadImage("image/cut.gif")));
JButton pasteButton = new JButton(new ImageIcon(
loadImage("image/paste.gif")));
// 该文本域显示当前光标在当前文本域中的行号
JTextArea showLineNoTextArea = new JTextArea();
// 对话框窗体,程序中所有对话框都显示在该窗体中
JFrame dialogFrame = new JFrame();
/***** 文件名以树型结构在左边显示 *******/
JTree tree;
DefaultMutableTreeNode root;
DefaultMutableTreeNode[] nodes = new DefaultMutableTreeNode[10];
/******* 组件之间的分隔栏 ******/
JSplitPane leftRightSplitPane;
JSplitPane lineNoConsoleSplitPane;
JSplitPane treeFlashSplitPane;
JSplitPane tabbedLineNoSplitPane;
/********** 文件选择、存储相关 ********/
// 文件过滤器
Filter fileFilter = new Filter();
// 文件选择器
FileChooser fileChooser = new FileChooser();
// 文件读写控制,0表示文件选择器读文件,1文件选择器标示写文件
int fileChooser_control = 0;
FileWriter fileWriter;
// tabbedPane中tab页的当前数量
int tb = 1;
int find_control = 0;
// 文本域的控制器,指向当前操作的文本域
int textAreas_control = 0;
// 当前文本域中的文本
String currentTextInTextArea;
// 标志文件是否为新建的,如果是新建的文件,为true
boolean[] newFileFlags = new boolean[10];
// 存放打开文件所在的目录
String[] directory = new String[10];
/******** 查找替换相关 ****/
// 正在查找的字符串及其长度
String findWord;
int fingWordLength;
// 保存正在查找的字符串在文本域中的文本的位置
int findIndex;
// 被替换的文本的长度
int replaceLength = 0;
/******** 用于显示Flash的控制器 ****/
JLabel flashLabel = new JLabel(new ImageIcon(
loadImage("image/Juggler0.gif")));
Timer timer = new Timer(100, new Act_timer());
int timerControl = 0;
/******** 帮助相关 ****/
Font font = new Font("Courier", Font.TRUETYPE_FONT, 14);
JTextArea helpTextArea = new JTextArea();
JFrame helpFrame = new JFrame("Help");
// 构造函数
public SimpleEditor() {
super("文本编辑器");
// 为窗体添加键盘事件处理器
// 下面这一行非常重要,表示窗体能够接受焦点。
// 如果没有这一句,按键盘会无效。
this.setFocusable(true);
this.addKeyListener(new MyKeyListener());
// 为窗体添加窗口事件处理器
this.addWindowListener(new WindowListener());
// 初始化
init();
setLocation(200, 200);
setVisible(true);
pack();
// 初始时启动动画
timer.start();
}
private void init() {
/******* 初始化文本域、目录、树节点 *********/
for (int i = 0; i < 10; i++) {
nodes[i] = new DefaultMutableTreeNode("File" + (i + 1));
newFileFlags[i] = true;
fileTextAreas[i] = new JTextArea();
// 设置文本域中文本的字体
fileTextAreas[i].setFont(font);
// 为文本域的插入光标设置颜色
fileTextAreas[i].setCaretColor(Color.yellow);
// 设置文本域的背景和前景颜色
fileTextAreas[i].setBackground(new Color(70, 80, 91));
fileTextAreas[i].setForeground(Color.pink);
// 为文本域插入光标设置事件处理器
fileTextAreas[i].addCaretListener(new CaretLis_lineNo());
// 为文本域键盘设置事件处理器
fileTextAreas[i].addKeyListener(new MyKeyListener());
directory[i] = new String("/");
fileScrollPanes[i] = new JScrollPane(fileTextAreas[i],
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
}
root = new DefaultMutableTreeNode("正在编辑的文件");
root.add(nodes[0]);
tree = new JTree(root);
tree.setEditable(false);
tree.setForeground(new Color(200, 150, 10));
tree.setBackground(new Color(70, 80, 91));
// 初始化控制台文本域
consoleTextArea.setFont(font);
consoleScrollPane = new JScrollPane(consoleTextArea,
JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,
JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
consoleTextArea.setForeground(new Color(200, 150, 10));
consoleTextArea.setBackground(new Color(70, 80, 91));
consoleTextArea.addMouseListener(new MouseListener_console());
// 初始化显示当前光标行数的文本域
showLineNoTextArea.setEnabled(false);
showLineNoTextArea.setFont(font);
showLineNoTextArea.setBackground(new Color(70, 80, 91));
showLineNoTextArea.setDisabledTextColor(Color.yellow);
/************** 初始化菜单 *************/
// 初始化菜单项
newMenuItem.addActionListener(new Act_NewFile());
openMenuItem.addActionListener(new Act_OpenFile());
saveMenuItem.addActionListener(new Act_SaveFile());
exitMenuItem.addActionListener(new Act_ExitEditor());
findMenuItem.addActionListener(new Act_Find());
findNextMenuItem.addActionListener(new Act_FindNext());
replaceMenuItem.addActionListener(new Act_Replace());
compileMenuItem.addActionListener(new Act_Compile());
buildMenuItem.addActionListener(new Act_Build());
helpMenuItem.addActionListener(new Act_Help());
copyMenuItem.addActionListener(new Act_Copy());
cutMenuItem.addActionListener(new Act_Cut());
pasteMenuItem.addActionListener(new Act_Paste());
stopFlashMenuItem.addActionListener(new Act_StopFlash());
startFlashMenuItem.addActionListener(new Act_StartFlash());
startFlashMenuItem.setEnabled(false);
// 初始化菜单
fileMenu.add(newMenuItem);
fileMenu.add(openMenuItem);
fileMenu.add(saveMenuItem);
fileMenu.add(exitMenuItem);
optionMenu.add(findMenuItem);
optionMenu.add(findNextMenuItem);
optionMenu.add(replaceMenuItem);
advanceMenu.add(compileMenuItem);
advanceMenu.add(buildMenuItem);
advanceMenu.addSeparator();
advanceMenu.add(stopFlashMenuItem);
advanceMenu.add(startFlashMenuItem);
helpMenu.add(helpMenuItem);
editMenu.add(copyMenuItem);
editMenu.add(cutMenuItem);
editMenu.add(pasteMenuItem);
// 初始化菜单栏
menuBar.add(fileMenu);
menuBar.add(optionMenu);
menuBar.add(advanceMenu);
menuBar.add(editMenu);
menuBar.add(helpMenu);
// 将菜单栏添加到窗体中
setJMenuBar(menuBar);
/*********** 初始化工具栏以及按钮 **********/
// 初始化按钮
newButton.addActionListener(new Act_NewFile());
openButton.addActionListener(new Act_OpenFile());
saveButton.addActionListener(new Act_SaveFile());
exitButton.addActionListener(new Act_ExitEditor());
compileButton.addActionListener(new Act_Compile());
buildButton.addActionListener(new Act_Build());
helpButton.addActionListener(new Act_Help());
copyButton.addActionListener(new Act_Copy());
cutButton.addActionListener(new Act_Cut());
pasteButton.addActionListener(new Act_Paste());
// 为工具栏设置提示信息,当鼠标在工具栏按钮上停留一段时间时,会显示提示信息
newButton.setToolTipText("New");
openButton.setToolTipText("Open");
saveButton.setToolTipText("Save");
exitButton.setToolTipText("Exit");
helpButton.setToolTipText("Help");
compileButton.setToolTipText("Compile");
buildButton.setToolTipText("Build");
copyButton.setToolTipText("Copy");
cutButton.setToolTipText("Cut");
pasteButton.setToolTipText("Paste");
newButton.setBorder(new BevelBorder(BevelBorder.RAISED));
openButton.setBorder(new BevelBorder(BevelBorder.RAISED));
saveButton.setBorder(new BevelBorder(BevelBorder.RAISED));
exitButton.setBorder(new BevelBorder(BevelBorder.RAISED));
helpButton.setBorder(new BevelBorder(BevelBorder.RAISED));
compileButton.setBorder(new BevelBorder(BevelBorder.RAISED));
buildButton.setBorder(new BevelBorder(BevelBorder.RAISED));
cutButton.setBorder(new BevelBorder(BevelBorder.RAISED));
copyButton.setBorder(new BevelBorder(BevelBorder.RAISED));
pasteButton.setBorder(new BevelBorder(BevelBorder.RAISED));
// 初始化工具栏
toolBar.add(newButton);
toolBar.add(openButton);
toolBar.add(saveButton);
toolBar.add(copyButton);
toolBar.add(cutButton);
toolBar.add(pasteButton);
toolBar.add(compileButton);
toolBar.add(buildButton);
toolBar.add(exitButton);
toolBar.add(helpButton);
/******** 初始化tab页面板和组件间的分隔栏 *********/
fileTabbedPane.addTab("File1", fileScrollPanes[0]);
fileTabbedPane.addChangeListener(new Act_ChangeTab());
// 文件目录树和Flash之间的分隔栏
treeFlashSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
flashLabel, tree);
// 文件文本域面板与指示光标所在行文本域面板之间的分隔栏
tabbedLineNoSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, true,
fileTabbedPane, showLineNoTextArea);
// 右边上2个面板与控制台面板的分隔栏
lineNoConsoleSplitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT,
true, tabbedLineNoSplitPane, consoleScrollPane);
// 左边大面板与右边大面板之间的分隔栏
leftRightSplitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, true,
treeFlashSplitPane, lineNoConsoleSplitPane);
// 设置分隔栏两边面板显示的宽度,如果分割条是左右分割,则参数表示分割条的横坐标
// 如果分割条是上下分割,则参数表示分割条的纵坐标
leftRightSplitPane.setDividerLocation(150);
tabbedLineNoSplitPane.setDividerLocation(460);
lineNoConsoleSplitPane.setDividerLocation(500);
treeFlashSplitPane.setDividerLocation(120);
// 初始化帮助
initHelp();
getContentPane().setLayout(new BorderLayout());
getContentPane().add(toolBar, BorderLayout.NORTH);
getContentPane().add(leftRightSplitPane);
}
/**
* 初始化帮助信息
*/
private void initHelp() {
// 帮助信息主要显示菜单的快捷方式
// field存放JTable的表头信息,即表的标题
String[] field = { "MenuItem", "ShortCut Key" };
// data存放JTable的数据。
Object[][] data = { { " New ", " Ctrl+N " },
{ " Open ", " F12 " },
{ " Save ", " Ctrl+S " },
{ " Exit ", " Ctrl+X " },
{ " Find ", " Alt " },
{ " Find Next ", " F3 " },
{ " Compile ", " F9 " },
{ " Build ", " F5 " },
{ " Copy ", " Ctrl+C " },
{ " Cut ", " Ctrl+X " },
{ " Paste ", " Ctrl+Y " },
{ " Help ", " Ctrl+H " }, };
// 用表头和数据构造一个表
JTable help_Table = new JTable(data, field);
help_Table.setFont(font);
// 不可编辑帮助信息表
help_Table.setEnabled(false);
// 为表和文本域设置背景和前景颜色
helpTextArea.setFont(new Font("Courier", Font.TRUETYPE_FONT, 16));
helpFrame.getContentPane().setLayout(new BorderLayout());
help_Table.setForeground(Color.pink);
helpTextArea.setForeground(Color.pink);
help_Table.setBackground(new Color(70, 80, 91));
help_Table.setSelectionBackground(new Color(70, 80, 91));
helpTextArea.setBackground(new Color(70, 80, 91));
helpTextArea
.setText(" If you want to use this software with all functions,\n"
+ " You must do the things following:\n"
+ " 1: install jdk_1.3 or Higher than it ;\n"
+ " 2: set your classpath and path correctly;\n"
+ " 3: if you want to use the compile and build functions,\n"
+ " you should save your edited File in the save directory\n"
+ " with this software.\n ");
// 将文本域和表加到窗体中
helpFrame.getContentPane().add(
new JScrollPane(help_Table,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
BorderLayout.CENTER);
helpFrame.getContentPane().add(
new JScrollPane(helpTextArea,
JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED),
BorderLayout.NORTH);
}
// 退出编辑器
private void exitEditor() {
// 弹出一个选择确认对话框,请求确认退出
if ((JOptionPane.showConfirmDialog(this, "你确定文本编辑器?", "退出",
JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION)) {
// 如果选择YES,则退出。
// dispose方法用于释放资源
// 释放由此 Window、其子组件及其拥有的所有子组件所使用的所有本机屏幕资源。
// 即这些 Component 的资源将被破坏,它们使用的所有内存都将返回到操作系统,并将它们标记为不可显示。
// 通过随后对 pack 或 show 的调用重新构造本机资源,可以再次显示 Window 及其子组件。
// 重新创建的 Window 及其子组件的状态在移除 Window 的点上与这些对象的状态将是一样的(不考虑这些操作之间的其他更改)。
dispose();
System.exit(0);
}
}
/**
* 键盘事件处理器
*/
public class MyKeyListener extends KeyAdapter {
// 覆盖父类的keyPressed方法,处理键被按下时的事件。
public void keyPressed(KeyEvent e) {
// 按F12打开文件
if (e.getKeyCode() == KeyEvent.VK_F12) {
(new Act_OpenFile()).actionPerformed(null);
}
// 按Ctrl加S键保存文件
else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_S) {
(new Act_SaveFile()).actionPerformed(null);
}
// 按Alt键查找
else if (e.isAltDown()) {
(new Act_Find()).actionPerformed(null);
}
// 按F3查找下一个
else if (e.getKeyCode() == KeyEvent.VK_F3) {
(new Act_FindNext()).actionPerformed(null);
}
// 按F4替换
else if (e.getKeyCode() == KeyEvent.VK_F4) {
(new Act_Replace()).actionPerformed(null);
}
// 按Ctrl加N新建文件
else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_N) {
(new Act_NewFile()).actionPerformed(null);
}
// 按Ctrl加E退出编辑器
else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_E) {
(new Act_ExitEditor()).actionPerformed(null);
}
// 按F5运行Java程序
else if (e.getKeyCode() == KeyEvent.VK_F5) {
(new Act_Build()).actionPerformed(null);
}
// 按F9编译Java源代码
else if (e.getKeyCode() == KeyEvent.VK_F9) {
(new Act_Compile()).actionPerformed(null);
}
// 按Ctrl加H显示帮助
else if (e.isControlDown() && e.getKeyCode() == KeyEvent.VK_H) {
(new Act_Help()).actionPerformed(null);
}
}
}
/**
* 窗口事件侦听器
*/
public class WindowListener extends WindowAdapter {
// 处理关闭窗口事件
public void windowClosing(WindowEvent e) {
exitEditor();
}
}
/**
* 文件选择器
*/
class FileChooser extends JFileChooser {
public FileChooser() {
// 文件选择器默认位置为当前文件夹
super("./");
}
/**
* 提交选择
*/
public void approveSelection() {
String filename = null;
// fileChooser_control == 0表示现在是打开文件,需要读
if (fileChooser_control == 0) {
// 打开文件时,在左边的树中添加一个节点
root.add(nodes[tb]);
remove(tree);
tree = new JTree(root);
tree.setBackground(new Color(70, 80, 91));
treeFlashSplitPane.setRightComponent(tree);
treeFlashSplitPane.setDividerLocation(120);
// 新建一个tab页,用于装新打开的文件
fileTabbedPane.addTab("File" + (tb + 1), fileScrollPanes[tb]);
fileTabbedPane.setSelectedIndex(tb);
// 将当前文本域设置到新打开的文件上
textAreas_control = tb;
tb++;
// 获取待打开的文件名
filename = fileChooser.getSelectedFile().getName();
// 获取待打开的文件所在的目录,将目录保存至数组,这样在保存文件的时候,能够将文件名保存到目录中
directory[textAreas_control] = fileChooser
.getCurrentDirectory().toString();
fileTextAreas[textAreas_control].setText(null);
try {
// 将文件内容显示到文本域中
String str;
BufferedReader breader = new BufferedReader(new FileReader(
directory[textAreas_control] + "/" + filename));
while (true) {
str = breader.readLine();
if (str == null) {
break;
}
fileTextAreas[textAreas_control].append(str + '\n');
}
} catch (Exception e_open) {
JOptionPane.showMessageDialog(dialogFrame.getContentPane(),
"读取发生错误");
}
} else if (fileChooser_control == 1) {
// fileChooser_control == 1表示现在是保存新文件,需要写
filename = fileChooser.getSelectedFile().getName();
directory[textAreas_control] = fileChooser
.getCurrentDirectory().toString();
try {
// 将文本域中的内容写到文件中
fileWriter = new FileWriter(directory[textAreas_control]
+ "/" + filename);
fileWriter
.write(fileTextAreas[textAreas_control].getText());
fileWriter.close();
} catch (Exception e_save) {
JOptionPane.showMessageDialog(dialogFrame.getContentPane(),
"读取发生错误");
}
}
// 关闭对话框
dialogFrame.dispose();
// 更新文件目录树中的名字
root.remove(nodes[textAreas_control]);
nodes[textAreas_control] = new DefaultMutableTreeNode(filename);
root.add(nodes[textAreas_control]);
// 将当前显示的树删除、显示新的树
remove(tree);
tree = new JTree(root);
tree.setBackground(new Color(70, 80, 91));
treeFlashSplitPane.setRightComponent(tree);
treeFlashSplitPane.setDividerLocation(120);
// 将tab页的标题改为文件名
fileTabbedPane.setTitleAt(textAreas_control, filename);
// 无论是打开、还是保存,这个文件不是已经新建的,所以置为false
newFileFlags[textAreas_control] = false;
}
/**
* 取消选择
*/
public void cancelSelection() {
dialogFrame.dispose();
}
}
/**
* 文件过滤器,只支持编辑".java,*.html,*.txt,*.cpp"文件
*/
class Filter extends FileFilter {
// 覆盖FileFilter的accept方法
public boolean accept(File file1) {
return (file1.getName().endsWith(".java") || file1.isDirectory()
|| file1.getName().endsWith(".html")
|| file1.getName().endsWith(".txt") || file1.getName()
.endsWith(".cpp"));
}
public String getDescription() {
return (".java,*.html,*.txt,*.cpp");
}
}
/**
* 用于侦听文本组件插入符的位置更改的侦听器 获取当前光标在文件中的行号
*/
class CaretLis_lineNo implements CaretListener {
public void caretUpdate(CaretEvent e) {
try {
showLineNoTextArea
.setText(" Cursor at the "
+ (fileTextAreas[textAreas_control]
.getLineOfOffset(fileTextAreas[textAreas_control]
.getCaretPosition()) + 1)
+ " line in the file of "
+ fileTabbedPane.getTitleAt(textAreas_control));
} catch (BadLocationException eB) {
System.out.println("IO Wrong");
}
}
}
/**
* 控制台文本域中鼠标事件的侦听器 当控制台中有错误信息时,表明Java源文件编译有问题,定位到出错的行号。
*/
class MouseListener_console extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
// 获取光标在控制台文本域中的位置
int off_err = consoleTextArea.getCaretPosition();
int line_no = 0;
try {
// 根据光标位置,定位它在控制台文本域中的行
int index = -1;
int line_err = consoleTextArea.getLineOfOffset(off_err - 1);
// 获取光标所在行的起始字符在文本域中的位置
int start_err = consoleTextArea.getLineStartOffset(line_err);
// 获取光标所在行的起始位置到光标位置之间文本,即错误信息
String err_str = consoleTextArea.getText(start_err, off_err
- start_err);
// 高亮显示错误信息
consoleTextArea.select(start_err, off_err);
// 分析错误信息中是否有编译器指出的Java源文件行号,这里假定最多10000行源程序
for (line_no = 0; line_no < 10000; line_no++) {
index = err_str.indexOf(":" + line_no + ":");
if (index > 0) {
break;
}
}
// 如果能够分析出Java源文件的行号,则在文件文本域中高亮显示。
if (index != -1) {
fileTextAreas[textAreas_control].requestFocus();
fileTextAreas[textAreas_control].select(
fileTextAreas[textAreas_control]
.getLineStartOffset(line_no - 1),
fileTextAreas[textAreas_control]
.getLineEndOffset(line_no - 1));
}
} catch (BadLocationException eB) {
System.out.println("IO Wrong");
}
}
}
/**
* 切换tab页事件
*/
class Act_ChangeTab implements ChangeListener {
public void stateChanged(ChangeEvent e) {
// 切换tab页时,更新textAreas_control的值。
textAreas_control = fileTabbedPane.getSelectedIndex();
}
}
/**
* 新建文件事件
*/
class Act_NewFile implements ActionListener {
public void actionPerformed(ActionEvent e_ji0) {
// 建立新文件时,更新树和tab页。
root.add(nodes[tb]);
remove(tree);
tree = new JTree(root);
tree.setBackground(new Color(70, 80, 91));
treeFlashSplitPane.setRightComponent(tree);
treeFlashSplitPane.setDividerLocation(120);
fileTabbedPane.addTab("File" + (tb + 1), fileScrollPanes[tb]);
fileTabbedPane.setSelectedIndex(tb);
textAreas_control = tb;
tb++;
}
}
/**
* 打开文件事件
*/
class Act_OpenFile implements ActionListener {
public void actionPerformed(ActionEvent e_ji1) {
// 打开已有文件
// 将文件选择器置为打开文件状态
fileChooser_control = 0;
fileChooser.setApproveButtonText("打开");
fileChooser.addChoosableFileFilter(fileFilter);
dialogFrame.getContentPane().add(fileChooser);
dialogFrame.setSize(550, 350);
dialogFrame.setTitle("请选择要打开的文件!");
dialogFrame.setVisible(true);
fileTextAreas[textAreas_control].setCaretPosition(0);
}
}
/**
* 保存文件事件
*/
class Act_SaveFile implements ActionListener {
public void actionPerformed(ActionEvent e_ji2) {
System.out.println("Act_SaveFile" + textAreas_control);
if (newFileFlags[textAreas_control]) {
// 对于新建的文件,需要指定文件存储路径,因此调用了文件选择起存储文件
// 将文件选择器置为保存文件状态
fileChooser_control = 1;
fileChooser.setApproveButtonText("保存");
fileChooser.addChoosableFileFilter(fileFilter);
dialogFrame.getContentPane().add(fileChooser);
dialogFrame.setTitle("请输入文件名!");
dialogFrame.setSize(550, 350);
dialogFrame.setVisible(true);
} else {
try {
// 对于已经存在的文件,直接保存
// 写文件,将当前文本域中文本写入到文件。
fileWriter = new FileWriter(directory[textAreas_control]
+ "/"
+ fileTabbedPane.getTitleAt(textAreas_control));
fileWriter
.write(fileTextAreas[textAreas_control].getText());
fileWriter.close();
} catch (Exception e_save) {
JOptionPane.showMessageDialog(null, "读取发生错误");
}
}
}
}
/**
* 退出编辑器事件
*/
class Act_ExitEditor implements ActionListener {
public void actionPerformed(ActionEvent e_ji3) {
// 退出编辑器
exitEditor();
}
}
/**
* 查找事件
*/
class Act_Find implements ActionListener {
public void actionPerformed(ActionEvent e_ji4) {
// 查找对话框
findWord = JOptionPane.showInputDialog("请输入查找内容");
if (findWord == null) {
JOptionPane.showMessageDialog(null, "查找失败!");
} else {
// 根据查找内容在当前文本域中进行匹配
fingWordLength = findWord.length();
currentTextInTextArea = fileTextAreas[textAreas_control]
.getText();
findIndex = currentTextInTextArea.indexOf(findWord);
if (findIndex < 0) {
JOptionPane.showMessageDialog(null, " 查找内容不存在 ");
} else {
// 如果找到了,则将鼠标键盘焦点放在当前文本域中,并将匹配字符串标示出来
fileTextAreas[textAreas_control].requestFocus();
fileTextAreas[textAreas_control].select(findIndex,
findIndex + fingWordLength);
}
}
}
}
/**
* 查找下一个事件
*/
class Act_FindNext implements ActionListener {
public void actionPerformed(ActionEvent e_ji4_next) {
// 查找下一个匹配的字符串
currentTextInTextArea = fileTextAreas[textAreas_control].getText();
findIndex = currentTextInTextArea.indexOf(findWord, findIndex + 1);
if (findIndex < 0) {
JOptionPane.showMessageDialog(null, " 查找已经到达文件尾! ");
} else {
fileTextAreas[textAreas_control].select(findIndex, findIndex
+ fingWordLength);
}
}
}
/**
* 替换事件
*/
class Act_Replace implements ActionListener {
public void actionPerformed(ActionEvent e_ji5) {
// 替换对话框
Object[] endButton1 = { "Replace", "Cancel" };
String message1 = "确认替换?";
currentTextInTextArea = fileTextAreas[textAreas_control].getText();
// 获取被替换的内容
String seek_word = JOptionPane.showInputDialog("请输入查找内容");
// 获取替换后的内容
String replace_word = JOptionPane.showInputDialog("请输入替换内容");
// 如果用户输入的查找内容不为null,则开始进行替换操作
if (seek_word != null) {
// 获取查找内容的长度,也就是将来替换的长度
replaceLength = seek_word.length();
while (true) {
// 先获取当前文本域的文本,再进行查找
currentTextInTextArea = fileTextAreas[textAreas_control]
.getText();
findIndex = currentTextInTextArea.indexOf(seek_word,
findIndex + replaceLength);
if (findIndex < 0) {
// 文本中不存在查找内容
JOptionPane.showMessageDialog(null, "查找已经到达文件尾!");
break;
} else {
// 查找成功,则标示出查找内容
fileTextAreas[textAreas_control].requestFocus();
fileTextAreas[textAreas_control].select(findIndex,
findIndex + replaceLength);
// 替换确认
JOptionPane end1 = new JOptionPane(message1,
JOptionPane.WARNING_MESSAGE,
JOptionPane.DEFAULT_OPTION, null, endButton1);
JDialog endD1 = end1.createDialog(end1, "请选择");
endD1.setVisible(true);
Object push1 = end1.getValue();
if (push1 == endButton1[0]) {
// 如果用户选择替换,则将文本域中被标示的文字用replace替换
fileTextAreas[textAreas_control]
.replaceSelection(replace_word);
}
}
}
}
}
}
/**
* 编译compile事件
*/
class Act_Compile implements ActionListener {
public void actionPerformed(ActionEvent e_ji6) {
// compile一个java源文件
// 控制台信息
consoleTextArea.setText(null);
// 目前只支持编译java类
if ((fileTabbedPane.getTitleAt(textAreas_control)).indexOf(".java") > -1) {
try {
int count;
byte input[] = new byte[256];
String InputString;
// 编译java源文件的命令"javac"
String[] command = {
"javac",
directory[textAreas_control]
+ "/"
+ fileTabbedPane
.getTitleAt(textAreas_control) };
// 当前应用程序启动一个新进程,用于执行命令
Process p = Runtime.getRuntime().exec(command);
// 读取执行命令时的错误输出
BufferedInputStream bufin = new BufferedInputStream(
p.getErrorStream());
// 这里仅仅读取前1024个字节
bufin.mark(1024);
count = bufin.read(input);
if (count <= 0) {
// 编译没有错误
consoleTextArea.append("Compile to "
+ fileTabbedPane.getTitleAt(textAreas_control)
+ " Success");
} else {
// 编译失败
InputString = new String(input, 0, count);
consoleTextArea.append("Compile to "
+ fileTabbedPane.getTitleAt(textAreas_control)
+ " Fail\n" + InputString);
}
} catch (IOException e) {
System.err.println("IO error: " + e);
}
} else {
consoleTextArea.append(fileTabbedPane
.getTitleAt(textAreas_control)
+ " is not a java File !\n Please Check it again!");
}
}
}
/**
* 运行build事件
*/
class Act_Build implements ActionListener {
public void actionPerformed(ActionEvent e_ji7) {
// build一个Java类
consoleTextArea.setText(null);
if ((fileTabbedPane.getTitleAt(textAreas_control)).indexOf(".java") > -1) {
try {
int count;
byte input[] = new byte[256];
String InputString;
// 获取java类的名字,去掉java源文件名的后五个字母".java"
String class_name;
int length = (fileTabbedPane.getTitleAt(textAreas_control))
.length();
class_name = (fileTabbedPane.getTitleAt(textAreas_control))
.substring(0, length - 5);
// 运行java类的命令"java"
String[] command = { "java", "-classpath",
directory[textAreas_control], class_name };
Process p = Runtime.getRuntime().exec(command);
BufferedInputStream bufin = new BufferedInputStream(
p.getErrorStream());
bufin.mark(256);
count = bufin.read(input);
if (count <= 0) {
// 运行没有错误
consoleTextArea.append("Build to "
+ fileTabbedPane.getTitleAt(textAreas_control)
+ " Success");
} else {
// 运行有错误
InputString = new String(input, 0, count);
consoleTextArea.append("Builld to "
+ fileTabbedPane.getTitleAt(textAreas_control)
+ " Fail\n" + InputString);
}
} catch (IOException e) {
System.err.println("IO error: " + e);
} catch (IndexOutOfBoundsException e2) {
System.err.println("IO error: " + e2);
}
} else {
consoleTextArea.append(fileTabbedPane
.getTitleAt(textAreas_control)
+ " is not a java File !\n Please Check it again!");
}
}
}
/**
* 显示帮助Help事件
*/
class Act_Help implements ActionListener {
public void actionPerformed(ActionEvent e_ji9) {
helpFrame.pack();
helpFrame.setVisible(true);
helpFrame.requestFocus();
helpFrame.setLocation(200, 0);
}
}
class Act_Copy implements ActionListener {
public void actionPerformed(ActionEvent e_ji9) {
// 复制事件,直接调用JTextArea的copy方法
fileTextAreas[textAreas_control].copy();
}
}
class Act_Cut implements ActionListener {
public void actionPerformed(ActionEvent e_ji10) {
// 剪贴事件,直接调用JTextArea的cut方法
fileTextAreas[textAreas_control].cut();
}
}
class Act_Paste implements ActionListener {
public void actionPerformed(ActionEvent e_ji11) {
// 粘贴事件,直接调用JTextArea的paste方法
fileTextAreas[textAreas_control].paste();
}
}
/**
* 动画显示事件
*/
class Act_timer implements ActionListener {
public void actionPerformed(ActionEvent e_time) {
// Flash显示,一共就4个图片文件,按顺序显示
if (timerControl > 4) {
timerControl = 0;
}
flashLabel.setIcon(new ImageIcon(loadImage("image/Juggler"
+ timerControl + ".gif")));
timerControl++;
}
}
/**
* 停止动画事件
*/
class Act_StopFlash implements ActionListener {
public void actionPerformed(ActionEvent E_stop) {
// Flash控制。停止动画
timer.stop();
startFlashMenuItem.setEnabled(true);
stopFlashMenuItem.setEnabled(false);
}
}
/**
* 启动动画事件
*/
class Act_StartFlash implements ActionListener {
public void actionPerformed(ActionEvent E_start) {
// Flash控制。启动动画
timer.start();
startFlashMenuItem.setEnabled(false);
stopFlashMenuItem.setEnabled(true);
}
}
/**
* 从jar包中读取图片文件
*
* @param name
* @return 返回一个图片对象
*/
private java.awt.Image loadImage(String name) {
try {
java.net.URL url = getClass().getResource(name);
// 根据URL中内容新建一个图片文件
return createImage((java.awt.image.ImageProducer) url.getContent());
} catch (Exception ex) {
return null;
}
}
public static void main(String args[]) {
new SimpleEditor();
}
}
[代码运行效果截图]