JAVA记事本界面实现

一、总体介绍

本文仿照了电脑中自带记事本的界面,主界面包含菜单项(JMenu):文件,编辑,格式,查看,帮助;菜单子项(JMenuItem):文件中的新建,新窗口,打开,保存,另存为,页面设置,打印,退出;编辑中的撤销,剪切,复制,粘贴,删除,查找,查找下一个,查找上一个,替换,转到,全选,时间/日期;格式中的自动换行,字体;查看中的缩放,状态栏;帮助中的查看帮助,发送反馈,关于记事本;文本输入区域为文本框嵌入滚动面板。

本文只实现了界面显示,而不含具体功能,最终实现的主界面如下图:

图1 记事本界面

查找窗口的界面:查找内容标签,查找内容输入单行文本框,查找下一个和取消按钮,区分大小写复选框,向上和向下单选按钮,界面图如下:

图2 查找界面

替换窗口的界面:查找内容和替换标签,查找内容和替换内容输入单行文本框,查找下一个、替换、全部替换和取消按钮,区分大小写复选框,向上和向下单选按钮,界面图如下:

图3 替换界面

转到窗口界面:行号标签,行号输入单行文本框,转到和取消按钮,界面图如下:

图4 转到界面

二、界面设计

(一)、主界面

主界面放置在JFrame窗口中,本文主类名为MyNotepad,在实现时继承了JFrame类。

public class MyNotepad extends JFrame

首先对主界面进行设置,包含窗口显示位置和大小、窗口布局管理器和名称的设置,因为继承了JFrame类,故可以直接使用其中的方法。其中,BorderLayout布局将窗口分为了上下左右中5个部分,未添加组件的部分会被组件存在的部分占据。

/*setBounds(x,y,width,height)
x,y:窗口在屏幕上的显示位置,左上角为(0,0)
width,height:窗口的宽度和高度
*/
setBounds(150,150,600,550);
// 默认窗口关闭按钮动作不执行任何操作
setDefaultCloseOperation(0);
//指定窗口布局管理器为BorderLayout
setLayout(new BorderLayout());
String name = "新建文本文档.txt";
// 窗口图标,即主界面最左上角的图片,图片路径需改为自己电脑中某张图片的路径,不设置图片也可
ImageIcon image = new ImageIcon("C:\\Users\\abc\\Desktop\\miao.jpg");
setIconImage(image.getImage());
// 设置记事本名称
setTitle(name + " - 记事本");

界面顶部是一个菜单栏JMenuBar,菜单栏中包含了5个菜单JMenu,每个菜单点击后都会出现下拉列表,列表中的元素可以是菜单子项JMenuItem,也可以是其他类型,例如,格式菜单下的自动换行是一个复选框类型的菜单子项JCheckBoxMenuItem,查看菜单下的缩放是一个菜单JMenu,在缩放菜单下同样可以存在下拉列表。界面中间是文本区域JTextArea,将文本区域放入滚动面板JScrollPane中就可以实现文本的滚动下滑效果。各部分的声明如下:

JMenuBar jmenu;//菜单栏(菜单的容器)
JMenu jm_file,jm_edit,jm_format,jm_look,jm_help;//菜单
JMenuItem file_newfile,file_newwindow,file_open,file_save,file_saveas,file_design,file_print,file_exit;//文件的菜单项  
JMenuItem edit_undo,edit_cut,edit_copy,edit_paste,edit_delete,edit_find,edit_findnext,edit_findpre,edit_replace,edit_goto,edit_all,edit_time;//编辑的菜单项
//格式的菜单项
JCheckBoxMenuItem format_linewrap;//自动换行复选框
JMenuItem format_font;
//查看的菜单项
JMenu look_zoom;//缩放菜单
JMenuItem look_status;
//缩放的菜单项
JMenuItem increase,reduce,source;
//帮助的菜单项
JMenuItem help_item1,help_item2,help_item3;
JTextArea jtext;//文本区域
JScrollPane jspane;//滚动面板
String name;//记事本名称

知道了各组件怎么创建后,就该考虑怎么将组件放到我想放到的位置了。菜单栏要放到窗口的顶部,可以调用JFrame类中的setJMenuBar方法,将我们定义的菜单栏作为参数传入。

// 菜单栏,声明后菜单栏还不存在,需要new一下才会创建菜单栏对象
jmenu = new JMenuBar();
// setJMenuBar为菜单栏提供了一个固定的位置,即顶部
setJMenuBar(jmenu);

接下来,要将我们的5个菜单依次放入菜单栏中,例如,要放入文件菜单:

jm_file = new JMenu("文件(F)");//括号内参数即它在窗口中显示的名字
jmenu.add(jm_file);

其余菜单的添加同理,添加的顺序对应菜单栏中排列顺序,先添加的在左边。

在添加完菜单后,就该为每个菜单添加属于它的下拉列表,添加顺序即是从上到下的排列顺序,同样以文件菜单为例:

file_newfile = new JMenuItem("新建(N)");
file_newwindow = new JMenuItem("新窗口(W)");
jm_file.add(file_newfile);
jm_file.add(file_newwindow);

其余菜单的添加同样如此,复选框和菜单也是通过add添加到相应的菜单下,在菜单下的菜单也可以通过add添加属于它的元素。至此,菜单栏的设置就完成了。接下来,我们要添加一个可滚动的文本区域到窗口的中间位置,同时自定义文本区域输入文本的字体样式。

jtext = new JTextArea();
jtext.setFont(new Font("宋体", Font.PLAIN, 14));// 设置字体样式(字体,风格,字号)
jtext.setWrapStyleWord(true);//设置单词在一行不足容纳时换行   
jtext.setTabSize(2);//Tab键在文本框中的移动距离
// 添加滚动面板
jspane = new JScrollPane(jtext);
/*一个容器如果使用了布局管理器,则该容器内的组件或容器应该使用setPreferredSize(new Dimension(w,h))来设置尺寸
如果是绝对布局,即setLayout(null),则该容器内的组件或容器应该使用setSize(w,h))来设置尺寸。*/
jspane.setPreferredSize(new Dimension(600, 550));
add(jspane, BorderLayout.CENTER);//add为所继承的JFrame窗口的函数,第2个参数为放在布局管理器中的位置

最后,下拉列表中的分割线只需要在相应的菜单下addSeparator()即可,例如,为编辑菜单添加分割线:

jm_edit.addSeparator();

到这里窗口的主界面显示部分就完成了,只要将窗口设置成可见就可以在运行后看到了。

setResizable(true);//窗口可拖动调整大小
setVisible(true);// 设置窗口可见

(二)、查找、替换窗口界面

用JDialog窗体作为其他组件的容器,布局方式采用了流式布局中的左对齐,即组件按从左到右排列,且一行不能排满时靠左排列。单行文本框JTextField,JTextArea为多行文本区域。JLabel标签,对文本框输入内容的描述。JButton按钮,JCheckBox复选框,JRadioButton与ButtonGroup组合使用实现多个按钮只能选一个的功能。

JDialog findDialog=new JDialog(this,"查找",false);//false时允许与其他窗口同时打开
Container con=findDialog.getContentPane();//获取对话框面板     
con.setLayout(new FlowLayout(FlowLayout.LEFT)); //左对齐
JLabel findContentLabel=new JLabel("查找内容(N):");  
JTextField findText=new JTextField(15);  
JButton findNextButton=new JButton("查找下一个(F):");
JCheckBox matchCheckBox=new JCheckBox("区分大小写(C)");  
ButtonGroup bGroup=new ButtonGroup();  
JRadioButton upButton=new JRadioButton("向上(U)");  
JRadioButton downButton=new JRadioButton("向下(U)");  
downButton.setSelected(true); //默认选中向下按钮
bGroup.add(upButton);  
bGroup.add(downButton);  
/*ButtonGroup类用于为一组按钮创建一个多斥(multiple-exclusion)作用域。 
使用相同的 ButtonGroup 对象创建一组按钮意味着“开启”其中一个按钮时,将关闭组中的其他所有按钮。
JRadioButton类实现一个单选按钮,此按钮项可被选择或取消选择,并可为用户显示其状态。 
与 ButtonGroup 对象配合使用可创建一组按钮,一次只能选择其中的一个按钮。 
(创建一个 ButtonGroup 对象并用其 add 方法将 JRadioButton 对象包含在此组中。)*/  
JButton cancel=new JButton("取消");

有了组件之后,就要将组件以一定的方式放入容器中,本文采用的是先将组件放入JPane面板,再将面板按左对齐的流式布局排列。向面板中添加组件同样是用add添加,面板中可以自定义选择各种布局方式进行布局,也可以采用默认的布局方式FlowLayout(流式布局),本文的面板1采用的是GridLayout(网格布局)。

//创建查找对话框的界面  
JPanel panel1=new JPanel();  
JPanel panel2=new JPanel();  
JPanel panel3=new JPanel();  
JPanel directionPanel=new JPanel();  
directionPanel.setBorder(BorderFactory.createTitledBorder("方向"));  
//设置directionPanel组件的边框;  
//BorderFactory.createTitledBorder(String title)创建一个新标题边框,使用默认边框(浮雕化)、默认文本位置(位于顶线上)、默认调整 (leading) 以及由当前外观确定的默认字体和文本颜色,并指定了标题文本。  
directionPanel.add(upButton);  
directionPanel.add(downButton);  
//GridLayout(rows,cols):将面板分为2行1列的网格,1个组件放入1个或多个网格,默认1个
panel1.setLayout(new GridLayout(2,1));
panel1.add(findNextButton);  
panel1.add(cancel);  
panel2.add(findContentLabel);  
panel2.add(findText);  
panel2.add(panel1);  
panel3.add(matchCheckBox);  
panel3.add(directionPanel);  
con.add(panel2);  
con.add(panel3);

JDialog窗体和JFrame窗口一样,要在运行后显示需要自己设置

findDialog.setSize(410,180);//窗体尺寸(宽,高)
findDialog.setLocation(230,280);//显示位置(x,y),屏幕左上角为(0,0)
//与JFrame的setBounds(150,150,800,600)功能一样
findDialog.setResizable(false);//不可调整大小  
findDialog.setVisible(true);//显示

替换窗口的界面与查找窗口类似。

(三)、转到窗口

转到窗口的各组件定义:

gotoDialog = new JDialog(this,"转到指定行",false);//窗体
Container con = gotoDialog.getContentPane();//获取窗体面板
JButton gotobutton = new JButton("转到");
JButton cancel = new JButton("取消");
gotoDialog.setLayout(null);//无布局管理器
JLabel linenumber = new JLabel("行号(L):");//标签
field = new JTextField();//单行文本框

组件的布局采用自定义位置布局,即确定每个组件的宽高和在屏幕中显示的位置。

linenumber.setBounds(10, 12, 400, 30);
field.setBounds(10, 42, 350, 28);
gotobutton.setBounds(180, 84, 80, 28);
gotobutton.setContentAreaFilled(false);//转到按钮不填充,可去上文观察转到按钮与查找窗口按钮的区别
cancel.setBounds(270, 84, 80, 28);
cancel.setContentAreaFilled(false);//取消按钮不填充
gotoDialog.setBounds(200, 200, 400, 160);
gotoDialog.setResizable(false);//窗体不可调整大小
con.add(linenumber);
con.add(field);
con.add(gotobutton);
con.add(cancel);

同时,行号文本框的初始值设为当前光标所在行的行号,并选中初始值。

try{
    int pos = jtext.getCaretPosition();//获取当前光标所在的位置
    int row = jtext.getLineOfOffset(pos)+1;//将组件文本中的偏移量转换为行号
    field.setText(String.valueOf(row));//将整数类型转成字符类型放入文本框
    field.requestFocus(); //把输入焦点放到文本框
    field.selectAll();//选中文本框中的值
}catch(BadLocationException badlocation){
    System.out.println("bad location");
}

getCaretPosition获取的是光标从上至下,从左至右计数所得的偏移总量。getLineOfOffset函数可能出现错误位置异常,因此需要进行异常处理。窗体的显示同以上窗体。

gotoDialog.setVisible(true);

三、总结

本文详细介绍了主界面、查找和替换界面、转到界面的组件定义、布局管理和设置,只是一种可行的方法,仅供参考,如有问题欢迎评论指出。

  • 3
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
import java.awt.BorderLayout; import java.awt.Container; import java.awt.Font; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.InputEvent; 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.BufferedReader; import java.io.BufferedWriter; import java.io.File; import java.io.FileReader; import java.io.FileWriter; import java.io.IOException; import javax.swing.BorderFactory; 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.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.KeyStroke; import javax.swing.ScrollPaneConstants; import javax.swing.SwingConstants; public class JNotePadUI extends JFrame { private JMenuItem menuOpen; private JMenuItem menuSave; private JMenuItem menuSaveAs; private JMenuItem menuClose; private JMenu editMenu; private JMenuItem menuCut; private JMenuItem menuCopy; private JMenuItem menuPaste; private JMenuItem menuAbout; private JTextArea textArea; private JLabel stateBar; private JFileChooser fileChooser; private JPopupMenu popUpMenu; public JNotePadUI() { super("新建文本文件"); setUpUIComponent(); setUpEventListener(); setVisible(true); } private void setUpUIComponent() { setSize(640, 480); // 菜单栏 JMenuBar menuBar = new JMenuBar(); // 设置「文件」菜单 JMenu fileMenu = new JMenu("文件"); menuOpen = new JMenuItem("打开"); // 快捷键设置 menuOpen.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_O, InputEvent.CTRL_MASK)); menuSave = new JMenuItem("保存"); menuSave.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_S, InputEvent.CTRL_MASK)); menuSaveAs = new JMenuItem("另存为"); menuClose = new JMenuItem("关闭"); menuClose.setAccelerator( KeyStroke.getKeyStroke( KeyEvent.VK_Q, InputEvent.CTRL_MASK)); fileMenu.add(menuOpen); fileMenu.addSeparator(); // 分隔线 fileMenu.add(menuSave); fileMenu.add(menuSaveAs); fileMenu.addSeparator(); // 分隔线 fileMenu.add(menuClose); // 设置「编辑」菜单 JMenu editMenu = new JMenu("编辑"); menuCut = new JMenuItem("剪切"); menuCut.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_X, InputEvent.CTRL_MASK)); menuCopy = new JMenuItem("复制"); menuCopy.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_C, InputEvent.CTRL_MASK)); menuPaste = new JMenuItem("粘贴"); menuPaste.setAccelerator( KeyStroke.getKeyStroke(KeyEvent.VK_V, InputEvent.CTRL_MASK)); editMenu.add(menuCut); editMenu.add(menuCopy); editMenu.add(menuPaste); // 设置「关于」菜单 JMenu aboutMenu = new JMenu("关于"); menuAbout = new JMenuItem("关于JNotePad"); aboutMenu.add(menuAbout); menuBar.add(fileMenu); menuBar.add(editMenu); menuBar.add(aboutMenu); setJMenuBar(menuBar); // 文字编辑区域 textArea = new JTextArea(); textArea.setFont(new Font("宋体", Font.PLAIN, 16)); textArea.setLineWrap(true); JScrollPane panel = new JScrollPane(textArea, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); Container contentPane = getContentPane(); contentPane.add(panel, BorderLayout.CENTER); // 状态栏 stateBar = new JLabel("未修改"); stateBar.setHorizontalAlignment(SwingConstants.LEFT); stateBar.setBorder( BorderFactory.createEtchedBorder()); contentPane.add(stateBar, BorderLayout.SOUTH); popUpMenu = editMenu.getPopupMenu(); fileChooser = new JFileChooser(); } private void setUpEventListener() { // 按下窗口关闭钮事件处理 addWindowListener( new WindowAdapter() { public void windowClosing(WindowEvent e) { closeFile(); } } ); // 菜单 - 打开 menuOpen.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { openFile(); } } ); // 菜单 - 保存 menuSave.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { saveFile(); } } ); // 菜单 - 另存为 menuSaveAs.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { saveFileAs(); } } ); // 菜单 - 关闭文件 menuClose.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { closeFile(); } } ); // 菜单 - 剪切 menuCut.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { cut(); } } ); // 菜单 - 复制 menuCopy.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { copy(); } } ); // 菜单 - 粘贴 menuPaste.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { paste(); } } ); // 菜单 - 关于 menuAbout.addActionListener( new ActionListener() { public void actionPerformed(ActionEvent e) { // 显示对话框 JOptionPane.showOptionDialog(null, "程序名称:\n JNotePad \n" + "程序设计:\n \n" + "简介:\n 一个简单的文字编辑器\n" + " 可作为验收Java实现对象\n" + " 欢迎网友下载研究交流\n\n" + " /", "关于JNotePad", JOptionPane.DEFAULT_OPTION, JOptionPane.INFORMATION_MESSAGE, null, null, null); } } ); // 编辑区键盘事件 textArea.addKeyListener( new KeyAdapter() { public void keyTyped(KeyEvent e) { processTextArea(); } } ); // 编辑区鼠标事件 textArea.addMouseListener( new MouseAdapter() { public void mouseReleased(MouseEvent e) { if(e.getButton() == MouseEvent.BUTTON3) popUpMenu.show(editMenu, e.getX(), e.getY()); } public void mouseClicked(MouseEvent e) { if(e.getButton() == MouseEvent.BUTTON1) popUpMenu.setVisible(false); } } ); } private void openFile() { if(isCurrentFileSaved()) { // 文件是否为保存状态 open(); // 打开 } else { // 显示对话框 int option = JOptionPane.showConfirmDialog( null, "文件已修改,是否保存?", "保存文件?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null); switch(option) { // 确认文件保存 case JOptionPane.YES_OPTION: saveFile(); // 保存文件 break; // 放弃文件保存 case JOptionPane.NO_OPTION: open(); break; } } } private boolean isCurrentFileSaved() { if(stateBar.getText().equals("未修改")) { return false; } else { return true; } } private void open() { // fileChooser 是 JFileChooser 的实例 // 显示文件选取的对话框 int option = fileChooser.showDialog(null, null); // 使用者按下确认键 if(option == JFileChooser.APPROVE_OPTION) { try { // 开启选取的文件 BufferedReader buf = new BufferedReader( new FileReader( fileChooser.getSelectedFile())); // 设定文件标题 setTitle(fileChooser.getSelectedFile().toString()); // 清除前一次文件 textArea.setText(""); // 设定状态栏 stateBar.setText("未修改"); // 取得系统相依的换行字符 String lineSeparator = System.getProperty("line.separator"); // 读取文件并附加至文字编辑区 String text; while((text = buf.readLine()) != null) { textArea.append(text); textArea.append(lineSeparator); } buf.close(); } catch(IOException e) { JOptionPane.showMessageDialog(null, e.toString(), "开启文件失败", JOptionPane.ERROR_MESSAGE); } } } private void saveFile() { // 从标题栏取得文件名称 File file = new File(getTitle()); // 若指定的文件不存在 if(!file.exists()) { // 执行另存为 saveFileAs(); } else { try { // 开启指定的文件 BufferedWriter buf = new BufferedWriter( new FileWriter(file)); // 将文字编辑区的文字写入文件 buf.write(textArea.getText()); buf.close(); // 设定状态栏为未修改 stateBar.setText("未修改"); } catch(IOException e) { JOptionPane.showMessageDialog(null, e.toString(), "写入文件失败", JOptionPane.ERROR_MESSAGE); } } } private void saveFileAs() { // 显示文件对话框 int option = fileChooser.showSaveDialog(null); // 如果确认选取文件 if(option == JFileChooser.APPROVE_OPTION) { // 取得选择的文件 File file = fileChooser.getSelectedFile(); // 在标题栏上设定文件名称 setTitle(file.toString()); try { // 建立文件 file.createNewFile(); // 进行文件保存 saveFile(); } catch(IOException e) { JOptionPane.showMessageDialog(null, e.toString(), "无法建立新文件", JOptionPane.ERROR_MESSAGE); } } } private void closeFile() { // 是否已保存文件 if(isCurrentFileSaved()) { // 释放窗口资源,而后关闭程序 dispose(); } else { int option = JOptionPane.showConfirmDialog( null, "文件已修改,是否保存?", "保存文件?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE, null); switch(option) { case JOptionPane.YES_OPTION: saveFile(); break; case JOptionPane.NO_OPTION: dispose(); } } } private void cut() { textArea.cut(); stateBar.setText("已修改"); popUpMenu.setVisible(false); } private void copy() { textArea.copy(); popUpMenu.setVisible(false); } private void paste() { textArea.paste(); stateBar.setText("已修改"); popUpMenu.setVisible(false); } private void processTextArea() { stateBar.setText("已修改"); } public static void main(String[] args) { new JNotePadUI(); } }
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值