天天看點

JAVA模拟win7記事本 使用JAVA模拟記事本

 使用JAVA模拟記事本

學校老師叫用java swing寫一個記事本,雖然java窗體不是java的強項,但還是可以作為練習熟悉一下的。

因為記事本這種單一的小東西,是以不需要什麼耦合不需要太低,雖然背離了低耦合,但是寫起來是相當友善

按win7模拟出來的記事本。

大體把所需類分為如下:

JAVA模拟win7記事本 使用JAVA模拟記事本

1,文本域建立與功能

2,編輯菜單功能

3,檔案菜單功能

3,格式菜單功能

4,幫助菜單功能

5,檢視菜單功能

6,總菜單

7,主函數(主界面)

8,系統剪切闆工具

9,狀态欄

10,界面設定

界面參考如下

JAVA模拟win7記事本 使用JAVA模拟記事本

下面進入正式代碼分析(使用部分代碼分析,具體代碼後面用連結給出):

1,檔案

JAVA模拟win7記事本 使用JAVA模拟記事本

需要一個儲存路徑的變量,然後文本域裡也需要有一個變量判斷是否被修改過

建立:

這裡需要判斷檔案是否被修改過,如果有,詢問使用者是否儲存,然後再操作,如果沒有,直接清空文本域類容與清空儲存的路徑

if (CreateText.isChangeT()) {
			int change = JOptionPane.showConfirmDialog(null, "是否将儲存更改", "記事本",
					0);
			switch (change) {
			case JOptionPane.YES_NO_OPTION:
				if (textpath == null) {
					FileTool.setSave("儲存");
				} else {
					FileTool.setPreserve();
				}
				CreateText.getJTexts().setText("");
				textpath = null;
				CreateText.setChangeT(false);
				break;
			case JOptionPane.CLOSED_OPTION:
				break;
			case JOptionPane.NO_OPTION:
				CreateText.getJTexts().setText("");
				textpath = null;
				CreateText.setChangeT(false);
				break;
			default:

				break;
			}

		} else {
			CreateText.getJTexts().setText("");
			textpath = null;
			CreateText.setChangeT(false);
		}
           

打開:

就是一個流,但是要先判斷文本域裡的類容是否被修改過,如果有,就詢問使用者是否儲存,然後再實作用檔案選擇器選擇路徑讀取的操作,打開後,要把打開的路徑替換原來的儲存路徑,然後文本是否修改改為否

JFileChooser jfc = new JFileChooser(".");
		FileFilter ff = new FileNameExtensionFilter("文本文檔(*.txt)", "txt");
		jfc.setAcceptAllFileFilterUsed(false);
		jfc.setFileFilter(ff);
		if (jfc.showDialog(null, null) == 0) {
			CreateText.getJTexts().setText("");
			textpath = jfc.getSelectedFile().getAbsolutePath();

			Notepad.getJf().setTitle(textpath);

			try {
				InputStream input = new BufferedInputStream(
						new FileInputStream(textpath));

				byte[] by = new byte[1024];
				int len = input.read(by);
				while (len != -1) {
					CreateText.getJTexts().append(
							new String(by, 0, len));
					len = input.read(by);
				}

				input.close();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
		}
		CreateText.setChangeT(false);
           

儲存與另存為:

另存為多實作一個重新選擇路徑存儲,這個存儲不替換儲存的路徑。

儲存就是直接安已經儲存的路徑存儲,如果沒有儲存的路徑,就打開路徑選擇器選擇一個路徑,下面提供儲存的代碼(使用的緩沖流)

StringBuffer str = new StringBuffer();

		try {
			OutputStream out = new BufferedOutputStream(new FileOutputStream(
					textpath));
			
			String[] lines = CreateText.getJTexts().getText().split("\n");
			for(int i = 0;i < lines.length;i++)
			{
				System.out.println(lines[i]);
				str.append(lines[i] + "\r\n");
			}			

			out.write(str.toString().getBytes("utf-8"));
			out.close();
			CreateText.setChangeT(false);
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
           

頁面設定與列印:

由于不好測試,就實作了一個java自帶的列印機。

頁面設定也剛好帶入在裡面,頁面設定使用Robot實作模拟快捷鍵跳轉到頁面設定裡(暫時沒想到好的辦法,這種方法也有個小bug,有可能切換失敗,可以額外用一個線程,在幾十毫秒後再使用虛拟按鍵,效果應該會好很多)<—歡迎大神提出意見

private static final void setPrintf(boolean whether) {
		
		PrinterJob print = PrinterJob.getPrinterJob();
		HashPrintRequestAttributeSet attr = new HashPrintRequestAttributeSet();
		if(whether)
		{
			Robot robot = null;
			try {  
		            robot = new Robot();//建立Robot對象  
		        } catch (Exception e) {  
		            // TODO Auto-generated catch block  
		            e.printStackTrace();  
		        }
			robot.keyPress(KeyEvent.VK_ALT);
			robot.keyPress(KeyEvent.VK_S);
			robot.keyRelease(KeyEvent.VK_S);
			robot.keyRelease(KeyEvent.VK_ALT);
			
		}
		
		print.printDialog(attr);
	}
           

退出:

這個就不用說了,再詢問使用者是否儲存後,直接System.exit(0)

2,編輯

JAVA模拟win7記事本 使用JAVA模拟記事本

文本域發生改變時判斷是否可用,撤銷的稍稍特殊下面再說,剪切,複制,删除是要選中的東西有類容才能可用

撤銷:

使用UndoManager實作,關聯文本域後,用canUndo()方法來看是否可以撤銷,如果可以,就把撤銷變為可用,撤銷的方法是undo()

JAVA模拟win7記事本 使用JAVA模拟記事本
JAVA模拟win7記事本 使用JAVA模拟記事本
JAVA模拟win7記事本 使用JAVA模拟記事本
JAVA模拟win7記事本 使用JAVA模拟記事本

剪切,複制,粘貼,删除:

前三個文本域自帶有方法,在有文字被選中後,這幾個變為可用,然後分别用cut(),copy(),paste()方法來實作前三個,

删除操作由于沒有自帶的方法,就用Robot來模拟Delete鍵

下面提供,這四個選項,啥時候可用與不可用的事件方法

jta.addCaretListener(new CaretListener() {
			// 文本框類容變動事件
			@Override
			public void caretUpdate(CaretEvent arg0) {
				// TODO Auto-generated method stub

				getsetPosition();
				if (undomg.canUndo()) {
					MenuBar.getBjs(0).setEnabled(true);
				} else {
					MenuBar.getBjs(0).setEnabled(false);
				}

				if (ShearPlate.getCbt() != null) {
					MenuBar.getBjs(3).setEnabled(true);
				} else {
					MenuBar.getBjs(3).setEnabled(false);
				}
				
				if(!"".equals(jta.getText()))
				{
					MenuBar.getBjs(5).setEnabled(true);
					MenuBar.getBjs(6).setEnabled(true);
				}
				else
				{
					MenuBar.getBjs(5).setEnabled(false);
					MenuBar.getBjs(6).setEnabled(false);
				}

				if (jta.getSelectedText() != null) {
					MenuBar.getBjs(1).setEnabled(true);
					MenuBar.getBjs(2).setEnabled(true);
					MenuBar.getBjs(4).setEnabled(true);
					
				} else {
					MenuBar.getBjs(1).setEnabled(false);
					MenuBar.getBjs(2).setEnabled(false);
					MenuBar.getBjs(4).setEnabled(false);
					
				}
			}
		});
           

查詢,查找下一個,替換:

這幾個都是息息相關的,建立兩個對話框,其中一個是查詢的,一個是查找下一個,一個是替換

查找與替換都是根據光标所在位置來操作,其中替換的操作是需要選中字元來執行替換

下面是兩個窗體預覽

JAVA模拟win7記事本 使用JAVA模拟記事本

裡面有類容時,這兩個選項才可用,當查找類容有類容時按鈕才可用,然後就是對文本域裡的類容一系列操作,光标定位,然後由光标向上,向下查找,選中查找的類容,替換的時候就替換選中的類容,區分大小寫這些,也是字元串的操作之一,記不起來查查API就有了,下面提供查詢的代碼,,替換就用replace實作,代碼差異不大,代碼太多,不一一展示。

String strb = CreateText.getJTexts().getText();

		int len = CreateText.getJTexts().getCaretPosition();
		int max = CreateText.getJTexts().getText().length();
		String str;
		int ch;
		String rep = reps;
		if (upandfl) {
			rep = rep.toLowerCase();
			strb = strb.toLowerCase();
		}
		if (lefrig) {
			str = strb.substring(len, max);
			ch = str.indexOf(rep);
		} else {
			str = strb.substring(0, len - 1);
			ch = str.lastIndexOf(rep);
		}

		int scope = rep.length();

		if (ch >= 0 && ch < max) {
			if (lefrig)
				CreateText.getJTexts().select(len + ch, len + ch + scope);
			else
				CreateText.getJTexts().select(ch, ch + scope);

		} else {
			JOptionPane.showConfirmDialog(null, "未找到" + reps, "記事本", 0);
		}
           

轉到與全選:

轉到我沒寫,是以我禁用了這個選項,轉到的實作思想就是,當有類容時,變為可用,再把光标定位到所輸入的行數

全選文本域自帶有方法selectAll()

時間/日期

擷取目前日期,格式化字元串後追加到文本域裡就行,追加是預設追加到光标位置的(又能偷懶一串代碼)

public static final String getDate() {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd- HH:mm ");
		Date date = new Date();
		String str = sdf.format(date) + String.format("%tA", date);
		return str;

	}
           
JAVA模拟win7記事本 使用JAVA模拟記事本

3,格式

JAVA模拟win7記事本 使用JAVA模拟記事本

自動換行,文本域有自帶的,當自動換行時,取消橫向的滾動條,取消狀态欄禁用檢視裡的狀态欄顯示

字型需要引入本機有的字型名,由于java的swing組價支援html4與css2,是以選擇框樣式很是友善了

1,自動換行

直接給代碼,沒啥需要注意的,就是對窗體的改變與禁用隔壁檢視的狀态欄顯示

MenuBar.getGss(0).addActionListener(new ActionListener() {
			// 自動換行功能
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				if (!CreateText.getJTexts().getLineWrap()) {
					
					CreateText.getJTexts().setLineWrap(true);
					StatusBar.getStatusJp().setVisible(false);
					MenuBar.getCks().setEnabled(false);
					CreateText.getJsp().setHorizontalScrollBarPolicy(
							JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
				} else {
					
					CreateText.getJTexts().setLineWrap(false);
					StatusBar.getStatusJp().setVisible(true);
					MenuBar.getCks().setEnabled(true);
					CreateText.getJsp().setHorizontalScrollBarPolicy(
							JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
				}

			}
		});
           

2,字型

先預覽

JAVA模拟win7記事本 使用JAVA模拟記事本

讀取電腦裡的字型的檔案名,也隻需要檔案名

GraphicsEnvironment fonts = GraphicsEnvironment
				.getLocalGraphicsEnvironment();
		String[] strfile = fonts.getAvailableFontFamilyNames();
           

存儲後放到JList裡,在把JList放到滾動面闆裡,當使用者選擇類容後,就把類容放置到上面的框裡,其他三個框也是相同操作

for(int i = 0;i < strfile.length;i++)strfile[i] = "<html><font "+strfile[i] + "\">"+strfile[i]+"</font></html>";

		final JList jliw = new JList(strfile);
		jliw.addListSelectionListener(new ListSelectionListener() {

			@Override
			public void valueChanged(ListSelectionEvent arg0) {
				// TODO Auto-generated method stub
				jtf[0].setText(clearHtml((String) jliw.getSelectedValue()));
				
				jlcs.setFont(new Font((String) jtf[0].getText(),
						map.get(jtf[1].getText()), Integer.parseInt(jtf[2].getText())));
			}
		});
		jliw.setFont(new Font("微軟雅黑", Font.PLAIN, 14));
		jspw.setViewportView(jliw);
		jspw.setBounds(10, 70, 260, 200);
           

最後到确定的時候,就改變文本域裡的字型,字形,字号(預先要有三個變量存儲這三個值),下次點開的時候,三個文本框裡預設要顯示這三個值。

confirm.addActionListener(new ActionListener() {

			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub

				MyFont = jtf[0].getText();
				Fontset = jtf[1].getText();
				MyfontSize = jtf[2].getText();

				CreateText.getJTexts().setFont(
						new Font(MyFont, map.get(Fontset), Integer
								.parseInt(MyfontSize)));
				jd.dispose();
			}
		});
           

4,檢視

JAVA模拟win7記事本 使用JAVA模拟記事本

檢視裡就隻有可憐的一個狀态欄是否顯示(還有可能被隔壁的自動換行禁用),單擊他,判斷狀态欄是否顯示,顯示則隐藏,隐藏則顯示

MenuBar.getCks().addActionListener(new ActionListener() {
			// 狀态欄事件
			@Override
			public void actionPerformed(ActionEvent arg0) {
				// TODO Auto-generated method stub
				if (StatusBar.getStatusJp().isVisible()) {
					StatusBar.getStatusJp().setVisible(false);
				} else {
					StatusBar.getStatusJp().setVisible(true);
				}
			}
		});
           

5,幫助

JAVA模拟win7記事本 使用JAVA模拟記事本

這個就不說了。。寫兩個小提示框就成,我的檢視幫助沒寫,感覺沒必要,關于記事本倒是寫了一個,下面是效果,附帶一個文本域字型,字形,字号改變

JAVA模拟win7記事本 使用JAVA模拟記事本

不怎麼用java的窗體操作,感覺java強大的地方在于web和安卓,不過這個東西很練手,對字元串操作的掌控,參數的傳遞,對代碼全局的掌控,也需要點小小的邏輯(其實這是作業,順便發表一下)

代碼不足之處,歡迎指教