春天里,百花香...
#
摘要: 控件數組是VB提供的一個優秀的設計解決方案,它能很方便快捷的處理大批同類控件的響應和時間處理,但不知為什么在C#中這個優秀特性沒有傳承下來,甚為可惜,本文將要探討就是如何在C# WinForm程序實現它.
總結起來,在C#中創建控件數組很簡單,首先在類中創建一個控件類型的數組,然后初始化它,具體初始化是動態創建還是鏈接到已有控件可以根據情況自行選擇,然后為數組元素添加事件,最后實現事件即可,在事件實現中即可以通過轉化sender來得到相應控件.
閱讀全文
摘要: "個人事務備忘錄"使用C#編成,用于進行個人每天的事務管理,它分三個頁面,"某日事務"頁面用于添加,刪除和轉移事務;"日歷"頁面用于以日歷形式列舉每天需要做的和已經做完的事務;"事務詳細"頁面用于查詢具體事務.
閱讀全文
摘要: C#做的小工具"文件批量命名器"下載及介紹
閱讀全文
摘要: 小工具"目錄文件比較器"下載及介紹
閱讀全文
MVC有MVC1和MVC2的區別,它們的區別在于MVC1中用Model來通知View進行改變,而MVC2中使用Controller來通知View.在桌面程序中一般采用MVC1,而Web程序多采用MVC2,這是因為web程序中,Model無法知道View的原因.
在Swing程序中,我們通常采用讓View實現Observer接口,讓Model繼承Observable類來實現MVC1,而讓Controller把它們創建及連接起來,具體代碼如下:

public class XXXControl
{
private XXXModel model = null;
private XXXView view = null;


public XXXControl()
{
model = new XXXModel();
view = new XXXView();
model.addObserver(view);
}

.
.
.
}
而Model進過處理后得到了結果,它采用Observable的notifyObservers()方法來通知View進行改變,而View的public void update(Observable o, Object arg)方法將相應這一改變,它通過解析Observable類型的對象o得到處理結果,再進行具體的表現層改變.
粗看起來MVC各司其職,很完美,但還有不和諧的隱患:
1.View必須知道解析Model,造成了二者的耦合.
2.View非得實現Observer接口,Model非得繼承Observable類,這個處理不是必要的.
3.這種模式只適合即時處理,即相應很快的處理,對于耗時過程并不適合.
4.由于Model中數據眾多,很多時候我們還需要建立一個常量類來區分各種情況和決定View更新的地方,進一步加重了類之間的耦合程度.
綜上,我覺得對于稍大的Swing程序,MVC2+線程回調方式更適合,它的主要處理是:
1.依然由Controller創建View和Model,它們擔負的職責也和原來一樣,但是View不實現Observer接口,Model不繼承Observable類,它們該怎么樣還是怎么樣,而讓Controller來充當它們之間的中介者.
2.如果是即時處理,可以在Controller中添加事件處理時就直接寫來.如果是耗時處理,可以將View和Model的引用(或Model中元素的引用)傳遞給一個線程處理類,具體的運算和界面反應在線程處理類中完成.
下面是一個調用例子:
new FetchTablesThread(model.getDataSource(), view,schema).start();
下面是線程類的例子:

public class FetchTablesThread extends BaseThread
{
private static Logger logger = Logger.getLogger(FetchTablesThread.class);

private String schema;

public FetchTablesThread(DataSource dataSource, SqlWindowView view,

String schema)
{
super(dataSource, view);
this.schema = schema;
}


public void run()
{
OutputPanel outputPanel = view.getTabbedPanel().getInputOutputPanel().getOutputPanel();


try
{

if (dataSource.getDbtype().equals("mysql"))
{
// Specail Process for MySql
new FetchTables4MySqlThread(dataSource, view, schema).start();

} else
{
// Ordinary Process for other DB
List tables = dataSource.getTablesInSchema(schema);


if (tables.size() > 0)
{
// Find tables under schema
view.getCatalogTablesPanel().getMultiTable().refreshTable(
tables);

outputPanel.showText(true);
String text = "Find " + tables.size()
+ " tables under schema:" + schema
+ " successfully!";
outputPanel.appendOutputText(text);
logger.info(text);

} else
{
// Can't find tables under schema
outputPanel.showText(true);
String text = "Can't find any table under schema:" + schema;
outputPanel.appendOutputText(text);
logger.info(text);
}
}

} catch (Exception ex)
{
outputPanel.showText(true);
String text = "Can't find any table under schema:" + schema+" and errorMsg="+ex.getMessage();
outputPanel.appendOutputText(text);
logger.info(text);
}
}
}
這樣做有兩個好處一是使程序結構松散化,適于修改,二是相對傳統的MVC2,Controller中事件處理的代碼也容易變得簡單而清晰,可維護性更佳.
綜上,我認為MVC2+線程回調方式是一種值得推薦的Swing桌面程序寫法.
關于線程回調方式,您可以參考:
http://m.tkk7.com/sitinspring/archive/2007/06/28/126809.html關于MVC,您可以參考:
http://junglesong.yculblog.com/post.2665424.html
摘要: 本文參考了http://www.java2s.com/Code/Java/Swing-JFC/TableSortTest.htm的做法。主要處理是取得用戶點擊的列,得到按此列排序的新數組,刪除原有元素,再把新數組加入進表格;如果已經排序,則進行逆序處理。處理完畢后,用戶點擊表頭即可實現排序和逆序。
閱讀全文
1.類代碼如下
package com.junglesong.mvc.common.menu;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
/**
* 程序風格菜單
* @author junglesong@gmail.com
*
*/
public class StyleMenu extends JMenu {
// 程序的主框架
final JFrame mainFrame;
/**
* 構造函數
* @param text:菜單條文字
* @param frame:程序的主框架
*/
public StyleMenu(String text,JFrame frame) {
super(text);
mainFrame=frame;
addSubMenuItems();
}
/**
* 添加下級菜單項
*
*/
private void addSubMenuItems() {
// 取得系統當前可用感觀數組
UIManager.LookAndFeelInfo[] arr = UIManager
.getInstalledLookAndFeels();
ButtonGroup buttongroup = new ButtonGroup();
for (int i = 0; i < arr.length; i++) {
JRadioButtonMenuItem styleMitem = new JRadioButtonMenuItem(
arr[i].getName(), i == 0);
final String className = arr[i].getClassName();
// 添加下級菜單項的事件相應
styleMitem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
try {
UIManager.setLookAndFeel(className);
SwingUtilities.updateComponentTreeUI(mainFrame);
} catch (Exception ex) {
System.out.println("Can't Change Lookandfeel Style to "
+ className);
}
}
});
buttongroup.add(styleMitem);
this.add(styleMitem);
}
}
}
2.用法如下
JMenuBar menubar = new JMenuBar();
mainFrame.setJMenuBar(menubar);
......
menubar.add(Box.createHorizontalGlue());
JMenu styleMenu = new StyleMenu("Syle", mainFrame);
menubar.add(styleMenu);
......
例圖:
我在工作過程中一般習慣把一些如代碼段,文,下載文件檔和圖片等臨時文件放在桌面上,這樣能更方便一些,但是時間一長就容易積聚很多文件,密密麻麻的,刪了吧又怕以后某時能用到,再找或者重做一個都很花時間,何況有些是不可恢復的.
為了解決這個問題,本人用微軟的JS(非JavaScript,雖然語法很像)制作了一個腳本放在桌面上,感覺桌面文件過多時就可以選上拖曳到這個腳本上,它會按日期把選上的文件自動存放到一個備份目錄里,這樣找起來就方便了,也不會丟失重要信息,如果實在沒用再刪除備份中的目錄或文件就可以了.
下面就是這個文件的代碼,如果需要使用的話拷貝這段進入寫字板,在另存為**.js的文件,放在桌面上即可使用,其中backupRoot清修改成你需要備份桌面文件的目錄.
或者從這里下載:
http://m.tkk7.com/Files/sitinspring/deskSweep.rar
var backupRoot="E:\\Backup\\";// The folder you backup files
var target = backupRoot+getCurrTime()+"\\";// subfolder under backupRoot

var fso = WScript.CreateObject("Scripting.FileSystemObject");

if(!fso.FolderExists(target))
{
fso.CreateFolder(target);
}

var args = WScript.Arguments; // Command arguments
var movedNum=0;


for(var i=0;i<args.length;i++)
{
storeFile(args(i),target);
}

WScript.Echo(movedNum.toString()+" Files have been backup to folder:"+target);


function storeFile(file,storeDir)
{

try
{

if(fso.FileExists(file))
{
fso.MoveFile(file,storeDir);
}

else if(fso.FolderExists(file))
{
fso.CopyFolder(file+"*",storeDir);
fso.DeleteFolder(file);
}
movedNum++;
}

catch(e)
{
WScript.Echo(file+" can't be backup to folder:"+target);
}
}


function getCurrTime()
{
var d, s = ""; // 聲明變量。
d = new Date(); // 創建 Date 對象。
s += d.getYear()+ "-"; // 獲取年份。
s += (d.getMonth() + 1) + "-"; // 獲取月份。
s += d.getDate() ; // 獲取日。
return(s); // 返回日期。
}
sitinspring(http://m.tkk7.com)原創,轉載請注明出處.