About My Editor Afritxia 12.29.2002
引言
这是一篇关于Java语言程序设计的文章.不是从"Hello, World"开始教你怎样使用Java,而是以我自己开发的一个应用程序:JMDEditor(Java Multiple Docment Editor)为主轴(假设读者已经学过Java语言),讲述Java的基本GUI组件的使用方法,部分技巧以及我在开发过程中的一些感想.
希望通过此文能够帮助那些初学Java的人,迅速提高自己的编程水平.
本文预计将分期发表,所包括的内容有:
菜单,工具条GUI设计
文本编辑区设计(撤消重做,行列显示,查找与替换)
文件I/O操作
多文档实现及管理
不管你有任何想法,你都可以通过以下的E-Mail地址告诉我:
祝各位好运!
菜单,工具条GUI设计
javax.swing组件中所提供的GUI很有Java自己的风格.我经常会在Windows和Linux两个系统下写些程序,用过几个堪称经典的代码编辑器.这些编辑器虽然各个功能强大,但强大的有点过分,而且有一部分功能我实在是用不上.所以随着学会Java语言,我为自己写了一个叫作JMDEditor(Java Multiple Document Editor)的软件,以便在Windows和Linux两个系统下使用.同时,以此方式进一步掌握Java程序设计.在写这个软件的过程中,我学到了不少东西,所以想在这里和各位交流一下.就算是抛砖引玉吧.
菜单,通常我是用类似这样的方法来建立菜单的:
JMenuBar mainMenu=new JMenuBar();
JMenu file=new JMenu("File");
JMenuItem newf=new JMenuItem("New File");
JMenuItem open=new JMenuItem("Open ...");
JMenuItem save=new JMenuItem("Save");
JMenuItem saveAs=new JMenuItem("Save As ...");
JMenuItem exit=new JMenuItem("Exit");
[当然还有很多语句,但篇幅有限,所以我就不写了.为了体现出主要的设计思想,包括这之后的所有代码都只拣最主干的部分.]
然后,添加并设置每一个菜单及菜单项:[1.0版是这样实现的]
private void initMainMenu()
{
newf.addActionListener(...);
newf.setMnemonic('N');
newf.setAccelerator(...);
file.add(newf);
open.addActionListener(...);
open.setMnemonic('O');
open.setAccelerator(...);
file.add(open);
file.addSeparator();
save.addActionListener(...);
save.setMnemonic('S');
save.setAccelerator(...);
file.add(save);
// ... ...
file.setMnemonic('F'); // 这样按Alt+F就可以选中"File"主菜单
mainMenu.add(file);
setJMenuBar(mainMenu);
}
这其中有不少语句都是重复的.而重复操作的几乎都是JMenuItem类的对象.所以我考虑用循环来解决这个问题,这是很自然想到的:[1.1版是这样实现的]
JMenuItem[] fileMIs={
newf, open, save, saveAs, exit // ... ...
};
char[] fileMnemonics={
'N', 'O', 'S', 'A', 'X'
};
KeyStroke[] fileKSs={
//... ...
};
private void initFileMenu()
{
for(int i=0; i<fileMIs.lenght; i++)
{
fileMIs[i].setMnemonic(fileMnemonics[i]);
fileMIs[i].setAccelerator(fileKSs[i]);
fileMIs[i].addActionListener(...);
file.add(fileMIs[i]);
}
file.setMnemonic('F');
mainMenu.add(file);
}
private void initMainMenu()
{
initFileMenu();
setJMenuBar(mainMenu);
}
把相同的属性提到父类里去,如果你有一些OO程序开发经验就应该知道这些.况且上述程序设计思想简直还是停留在面向结构的程序设计思想上,并没有充分发挥OO程序设计思想的优点.所以又有了改进:[1.2, 1.3版中出现]
JComponent[] fileMIs={
new MyMenuItem("New File", 'N', FileAction, KeyEvent.VK_N),
new MyMenuItem("Open ...", 'O', FileAction, KeyEvent.VK_O),
new MyMenuItem("Save", 'S', FileAction, KeyEvent.VK_S),
new MyMenuItem("Save As ...", 'A', FileAction),
new JSeparator(),
new MyMenuItem("Exit", 'X', FileAction)
};
private void initMenu(JMenu m, JComponent[] mi){
int len=mi.length;
for(int i=0; i<len; i++) m.add(mi[i]);
m.setMnemonic(m.getActionCommand().charAt(0));
mainMenu.add(m);
}
private void initMainMenu()
{
initMenu(file, fileMIs);
setJMenuBar(mainMenu);
}
private class MyMenuItem extends JMenuItem
{
public MyMenuItem(String label, char memo, int stroke, Action a)
{
super(label);
setMnemonic(memo);
setAccelerator(KeyStroke.getKeyStroke(stroke, ActionEvent.CTRL_MASK, true));
addActionListener(a);
}
public MyMenuItem(String label, char memo, Action a)
{
super(label);
setMnemonic(memo);
addActionListener(a);
}
}
而当我看了<< Mastering Java 2 >>一书中有关Java GUI的一些范例说明时,受到了一些启发.固,也就有了更新的,更接近面向对象的方式来构建菜单:[正打算要用]
private class FileMenu extends JMenu
{
public FileMenu()
{
super("File");
setMnemonic('F');
initFileMenu();
}
private void initFileMenu()
{
add(new MyMenuItem("New File", 'N', KeyEvent.VK_N));
add(new MyMenuItem("Open ...", 'O', KeyEvent.VK_O));
add(new MyMenuItem("Save", 'S', KeyEvent.VK_S));
add(new MyMenuItem("Save As ...", 'A'));
addSeparator();
add(new MyMenuItem("Exit", 'X'));
}
}
public JMenuBar createMenu()
{
JMenuBar mainMenu=new JMenuBar();
mainMenu.add(new FileMenu());
return mainMenu;
}
private class MyMenuItem extends JMenuItem
{
public MyMenuItem(String Cmd, char Memo, int stroke)
{
super(Cmd);
setMnemonic(Memo);
setAccelerator(KeyStroke.getKeyStroke(stroke, ActionEvent.CTRL_MASK, true));
// addActionListener(...); // ??
}
public MyMenuItem(String Cmd, char Memo)
{
super(Cmd);
setMnemonic(Memo);
}
}
菜单有了,接下来就是工具条了.起初,工具条中的按钮图标颜色是可以变换深浅的,因为我画了三组图标.然后用:
String path="resource/";
JButton newf=new JButton(new ImageIcon(path+"New.gif"));
newf.setRolloverIcon(new ImageIcon(path+"New_0.gif"));
newf.setPressedIcon(new ImageIcon(path+"New_1.gif"));
newf.setRolloverEnabled(true);
的语句使其可以变换颜色深度.但后来我觉得还是Word的工具图标样式好一点.就是鼠标移到图标上以后,图标按钮才绘制出3D效果边框.否则,看上去就是一个平面图标.当然在Swing组件里我并不打算实现和其一模一样的效果,我只希望鼠标移到工具图标上时,工具图标才绘制按钮边框.否则擦掉不画(有点类似于jEdit 3.0.1的工具图标效果).虽然那是一个简单的效果,但是,在我的1.2版的菜单诞生之前我始终不知道应该怎样去实现这种效果.后来,解决了:
private class MyButton extends JButton
{
public MyButton(String label)
{
super(label);
setMargin(new Insets(1, 1, 1, 1));
setFocusPainted(false);
setBorderPainted(false);
addMouseListener(new MouseAdapter(){
public void mouseEntered(MouseEvent e){
setBorderPainted(true);
}
public void mouseExited(MouseEvent e){
setBorderPainted(false);
}
});
}
}
工具条的建立方式,在Java的演示程序Notepad中好象不是象我这样简单的往JPanel里加入一组JButton完事的,好象是在读取什么资源.尽管我的工具条生成方式简陋,不过对于初学者说来,还算是简单明了.
因为初次发表自己的文章,所以只写了一些在简单的东西,不敢罗嗦太多.本人初入Java语言,欠缺经验,略显稚嫩,惟恐有些疏漏,还请各位提出宝贵意见.
最后,列出JMDEditor的一些简要信息
JMDEditor (Java Multiple Document Editor)
运行环境: SUN Microsystem Java 1.3(在1.4下编译要做轻微改动)
用户界面: 采用有内置窗口的MDI风格.
编 辑 器: 支持多级撤消,重做,查找与替换.
支持多文档(要不,怎么敢叫Multiple Document呢?).
提供HTML文档格式的用户使用说明(没写完,如果我只是自己用,就没必要写)
代码长度: 11个文件,约2287行.可以提供源代码.
参考书籍:(名称|出版社|作者)
Mastering Java 2 / Java2从入门到精通 SYBEX/PHEI John Zukowski著/邱仲潘译
Java程序设计入门教程 青年出版社 林邦杰著
继续写?听凭各位的意见了.