我正在爲使用Swing的應用程序編寫GUI,爲了維護代碼和可讀性,我希望在整個系統中遵循一致的模式。什麼是你最好的Swing設計模式和技巧?
我讀過的大部分文章和書籍(或者至少是書本章節)似乎都提供了大量有關如何創建和安排各種組件的示例,但忽略了編寫完整GUI的大圖。
什麼是應用程序GUI設計的最佳提示,以及在設計或重構GUI應用程序時遵循哪些模式?
我正在爲使用Swing的應用程序編寫GUI,爲了維護代碼和可讀性,我希望在整個系統中遵循一致的模式。什麼是你最好的Swing設計模式和技巧?
我讀過的大部分文章和書籍(或者至少是書本章節)似乎都提供了大量有關如何創建和安排各種組件的示例,但忽略了編寫完整GUI的大圖。
什麼是應用程序GUI設計的最佳提示,以及在設計或重構GUI應用程序時遵循哪些模式?
使用佈局管理器。你可能會認爲只需要用硬編碼的位置來定位所有的東西就更簡單了(特別是如果你使用圖形化佈局工具的話),但是當需要更新gui或者國際化時,你的後繼者會恨你。 (請相信我,我是一開始就使用佈局管理器的人,以及忽視我的人的繼任者。)
避免使用GUI佈局設計器(構建器)。稍後它會讓你的代碼更清潔和更容易維護。
確實,如果你用一個建造者開始你的GUI,你幾乎承諾整個使用這個建造者GUI的整個生命週期。這有時可以接受,有時不可以。 – Eddie 2009-01-30 17:27:01
是的,這是真的。不同的構建者以不相互兼容的不同格式存儲元數據。唯一的例外是Instantiations Swing Designer,它直接與代碼一起工作。 所有這些代碼都不會被手動編輯(無法讀取),這會稍後再咬你。 – Marko 2009-01-30 17:30:23
我不同意。如果您知道Swing,那麼由GUI構建器生成的任何代碼都將具有足夠的可讀性。問題在於,通過使用GUI構建器,您無法很好地瞭解Swing。良好的分離當然是必要的。 – willcodejavaforfood 2009-02-01 14:49:47
mvc是你的朋友。
養成你的回調產生線程來完成實際工作的習慣,然後當你的回調變成一個耗時的怪物時,你不會有凍結的GUI。
絕對把GUI放在一個類中,而把邏輯放在另一個類或多個類中 - 盡最大可能。如果您使用MVC (Model-View-Controller)模式,則會自動發生。如果你不這樣做,GUI將很快變得難以維繫複雜。
儘量不要將文本編碼到您的應用程序中。 Swing guis可以很容易地寫成數據驅動,可以考慮在xml文件中定義你的GUI(包括組件名稱和位置/佈局屬性)。
我工作的系統有很多屬性表(它們只是一堆一堆的控件,一頁接一頁地) - 如果沒有數據驅動,幾乎不可能維護或國際化。
如果您決定使用GUI構建器,請不要修改它輸出的代碼(如果可以避免的話) - 最好從外部類綁定到GUI。想想如果你必須在沒有建造者的情況下做到這一點會發生什麼 - 難以移植嗎?不可能?
理解揮杆的陷阱 - 只能從AWT線程修改GUI組件,儘可能迅速返回AWT線程(生成一個新的線程,如果你做任何事情,需要大於100ms),
嘗試最好讓代碼保持乾爽 - 這可能是Swing GUI的一個真正的編程挑戰 - 同樣,數據驅動的代碼是我發現的不會重複代碼的唯一方式,如 新的JButton(「...」) ;
如果您的數據基於屬性表,請認真考慮創建綁定機制以將控件與數據綁定。對於DRY代碼來說,一個好的目標是每個控件的控制特定的代碼行,以便從數據庫中獲取一段數據到您的GUI,並讓用戶編輯它並將其返回到數據庫。這意味着你應該可以通過不做任何事情來修改你的數據來添加一個新的控件。
這是一個更抽象的關於GUI代表什麼的高層次的答案,而不是它的機制。
根據任務的不同,它可能是一種很難說這樣你的用戶可以在概念上把握什麼GUI正在做什麼。我已經做了一些非常棘手的工作,涉及GUI,我最成功的方法是將一組複雜的控件放入用戶期望的佈局中。
例如我寫了一個系統來管理2臺設備的一個在T1線路(有點像調制解調器)的任一端。這些控件真的很難理解 - 像「創建回送,測試遠端信號,測試近端位模式,發送各種位模式......」(這是一個巨大的過度簡化,比這更糟糕)
我必須真正理解這個問題,所以我去了一位技術支持代表,他幫助客戶解決了這個問題。他向我展示了手冊中的圖表,並向我介紹了該圖表上不同的控件。我用圖形重新創建了它(大部分只是一個簡單的線條圖,但它顯示了兩端和它們之間的連接),然後使用圖形區域來表示控件和反饋(顏色變化)。你可以通過視覺看到信號正在傳出。當你在遠端打開一個環回時,你可以看到這條線路將信號環回到它的外線,然後你可以看到顏色的變化,因爲你的近端開始得到它發出它的另一條線路的模式。
「控件」比這個顯著比較繞口,但是GUI也減少到需要什麼客戶來理解問題。
在此之後,我們有客戶回來給我們告訴我們,他們從未能夠前算出這個東西出來,但現在他們完全得到它!
此演示文稿比GUI實現的佈線更爲重要。
查看應用程序框架API(和http://java.sun.com/developer/technicalArticles/javase/swingappfr/)。這是一個非常棒的API來構建您的swing應用程序,例如:所有樣式(顏色,字體,圖標...)都在一個簡單的配置文件中定義。 。
切勿的JDialog,JFrame的或派生的JInternalFrame定義你的表格,對話框...
從JPanel的派生而這將帶給您follwing優點:
您不應該擴展JFrame,JDialog,JPanel,JButton,Janything類(儘管錶行爲的某些擴展只在擴展時纔可用)。如果您想做自定義組件,可以擴展JComponent。如果應該實現模型(例如通過擴展抽象模型),聽衆(例如通過擴展適配器),但就是這樣。通常不需要/不得不擴展擺動組件,而且最好不要這樣做,因爲它使您的代碼與超類的實現相關聯。
構圖更容易時避免繼承。
比如我見過像這樣的很多:
public class CustomerSupportApp extends JFrame {
JList<Customer> customers;
OtherBusinessComponent importantComponent;
etc. etc
}
這是混合業務邏輯與表現。它只是使變化從困難變爲不可能。
更好的是:
public class CustomerSupportApp {
JList<Customer> customers;
OtherBusinessComponent importantComponent;
// The app HAS-A frame but not IS-A frame
JFrame frame;
etc. etc
}
避免生成當用戶點擊操作按鈕多次線程太多。在第一次點擊時禁用按鈕,在後臺線程中產生動作,完成後再次啓用按鈕。這對短期運行任務可能不是問題。
我認爲並行的一個良好的工作知識往往是低估。您確實需要熟悉Swing的線程策略和常規同步技術,才能構建響應式GUI和高效的後端。
大量使用MVC模式。這裏有一個簡單的例子,我的意思是:
class Person
{
String firstName;
String lastName;
// and getters and setters...
}
class PersonSwingModel
{
private Person person;
private javax.swing.text.PlainDocument firstName;
private javax.swing.text.PlainDocument lastName;
// and getters and setters...
// Create some method like init() that initializes PlainDocument values
// to attributes in model.
}
class SavePersonAction extends AbstractAction
{
private PersonSwingModel model;
// and getters and setters...
}
class PersonSwingView extends JFrame
{
private PersonSwingModel model;
private javax.swing.JTextField firstName;
private javax.swing.JTextField lastName;
private SavePersonAction savePersonAction; // hook up to JButton/JMenuItem
// and getters and setters...
// Create some method like init() which binds PlainDocument to JTextField
// and Actions to JButtons or JMenuItems
}
我看到一些人不同意擴展JFrame或JPanel。我不。適用於我。
另外,使用LayoutManagers。 GridBagLayout功能非常強大。如果使用它,則定義一些GridBagConstraints常量(如LABEL_GBC和FIELD_GBC)並繼續重用它們。
這裏是我的四個孩子:http://blue-walrus.com/swing-design-patterns/ – 2013-07-02 07:30:31