2011-12-22 170 views
8

直接找到我的問題。Java - 做大型GUI項目

你如何做大型的GUI項目。到目前爲止,我還沒有在java中做過任何更大的GUI項目,但是我現在的工作變得非常快並且相當大,現在我陷入了一大堆令人討厭和混亂的代碼。

因爲我來自web開發我習慣MVC框架,所以我必須在我的項目模型3包,其中i保持這種互動絲毫文件或數據庫,查看其中我把我的班表格或圖形用戶界面和控制器類的領域包我在哪裏保持我的大部分邏輯。

我被告知要分開我的邏輯以及保持一個類中的動作和另一個類中的偵聽器,但是我不知道如何鏈接所有這些。

到目前爲止,我只有1個控制器類,在那裏我執行所有關於圖形用戶界面發生什麼事情的方法。

package pft.controller; 


import java.io.IOException; 
import java.util.logging.Level; 
import java.util.logging.Logger; 
import javax.swing.JLabel; 
import javax.swing.JComboBox; 
import javax.swing.JTree; 
import java.awt.event.*; 
import javax.swing.JProgressBar; 
import pft.view.Invoke_GUI; 
import pft.model.Events; 
import pft.model.Parse; 

public class Tower_Controller { 

    public Tower_Controller() { 
    } 
    //Global variables 
    String isSelected = null; 
    int hasModules = 0; 
    int cap = 0; 
    int cpu = 0; 
    int shield = 0; 
    int armor = 0; 

    public void setName(String name){ 
     this.isSelected = name; 
    } 

    public String getName(){ 
     return this.isSelected; 
    } 

    public void setCap(int cap){ 
     this.cap = cap; 
    } 

    public int getCap(){ 
     return this.cap; 
    } 

    public void setCpu(int cpu){ 
     this.cpu = cpu; 
    } 

    public int getCpu(){ 
     return this.cpu; 
    } 

    public void setShield(int shield){ 
     this.shield = shield; 
    } 

    public int getShield(){ 
     return this.shield; 
    } 

    public void setArmor(int armor){ 
     this.armor = armor; 
    } 

    public int getArmor(){ 
     return this.armor; 
    } 


    public void invoke() throws IOException { 
     Invoke_GUI runnable = new Invoke_GUI(); 
     final JLabel tower_name = runnable.tower_name; 
     final JComboBox tower_select = runnable.tower_select; 
     final JTree module_browser = runnable.module_browser; 
     final JTree selected_modules = runnable.selected_modules; 

     final JProgressBar cap_bar = runnable.cap_bar; 
     final JProgressBar cpu_bar = runnable.cpu_bar; 

     final JLabel em_res = runnable.em; 
     final JLabel th_res = runnable.thermic; 
     final JLabel ki_res = runnable.kinetic; 
     final JLabel ex_res = runnable.explosive; 

     setTowerName(tower_name, tower_select); 
     removeTower(tower_name); 
     runnable.setVisible(true);  

    } 

    public void removeTower(final JLabel tower_name) { 
     tower_name.addMouseListener(new MouseListener() { 

      @Override 
      public void mouseClicked(MouseEvent e) { 
       if (hasModules == 1 & isSelected != null) { 
        Events evt = new Events(); 
        evt.towerHasModules(); 
       } else if (isSelected == null) { 
       } else { 
        tower_name.setText("No Control Tower selected"); 
        isSelected = null; 
       } 
      } 

      @Override 
      public void mousePressed(MouseEvent e) { 
      } 

      @Override 
      public void mouseReleased(MouseEvent e) { 
      } 

      @Override 
      public void mouseEntered(MouseEvent e) { 
      } 

      @Override 
      public void mouseExited(MouseEvent e) { 
      } 
     }); 
    } 

    public void updateVariables(String name) throws IOException{ 
     Parse tower = new Parse(); 
     String data[] = tower.towerData(name); 
     Integer x = Integer.valueOf(data[1]).intValue(); 
     setCap(x); 
    } 

    public void setTowerName(final JLabel tower_name, final JComboBox tower_select) { 
     tower_select.addActionListener(new ActionListener() { 

      @Override 
      public void actionPerformed(ActionEvent e) { 
       if (isSelected != null) { 
        Events evt = new Events(); 
        evt.towerSelected(isSelected); 
       } else { 
        tower_name.setText(tower_select.getSelectedItem().toString()); 
        setName(tower_name.toString()); 
        try { 
         updateVariables(tower_name.toString()); 
        } catch (IOException ex) { 
         Logger.getLogger(Tower_Controller.class.getName()).log(Level.SEVERE, null, ex); 
        } 
       } 
      } 
     }); 
    } 


} 

有很多教程和示例如何做小通常是單級Java GUI,但是,如何做到這一點比單個類有點大項目沒有教程或例子。

在此先感謝您的所有幫助和 意見。

+0

請查看http://en.wikipedia.org/wiki/Mediator_pattern – 2011-12-22 03:09:56

+0

請參閱['MVCGame'](http://stackoverflow.com/a/3072979/230513)。 – trashgod 2011-12-22 03:10:57

回答

6

這是我對Swing開發的一般建議。它確實討論了使用控制器來彌合視圖需求和模型接口的重要性。

GUI guidelines for swing

末鞦韆項目,我做了我設計了MVC框架,使用Spring爲定義程序和控制器的模型,然後使用註解的控制器通過視圖分派的事件連線上輸出到方法控制器。該視圖可以訪問作爲事件總線的事件調度程序,並且通過總線發送的事件通過註釋稱爲Controller上的方法。這允許任何控制器響應來自視圖的事件。因此,當Controller過大時,將每組方法重構爲另一個Controller非常簡單,並且視圖或模型不必更改。

事件總線的美妙之處在於它可以與模型共享,所以模型可以派發控制器可以註冊的異步事件。它看起來是這樣的:

public class SomeController { 

    private AuthenticationModel authenticationModel; 

    private LoginService loginService; 

    private MyApp view; 

    @Listener(event = "login") 
    public void login(LoginEvent event) { 
     view.showWaitDialog(); 
     loginService.login(event.getUserName(), event.getPassword()) 
     .onResult(new Callback<User>() { 
      public void onResult(User user) { 
       authenticationModel.setUser(user); 
       view.hideWaitDialog(); 
       view.showStartScreen(user); 
      } 
     }); 
    } 

} 

一旦這個框架已經到位這是驚人的,我們怎麼能快速把事情做好。當我們添加了功能後,它表現得相當不錯。我已經完成了大量Swing項目(迄今爲止的3個)的公平份額,並且這種架構產生了巨大的差異。

+0

+ 1巴士 – Bill 2011-12-22 05:54:42

+0

你的框架似乎很有趣,但你可以添加更多關於模型和視圖的細節? (我想實現你的框架)我有同樣的問題比斯特林公爵夫人,但我不熟悉Spring和Java註釋:( – AwaX 2015-02-09 13:20:49

3

縮放GUI的最簡單方法是將所有內容鬆散耦合。事件(Swing和你自己的)是這樣做的最好方法。除非一個類直接創建或顯示GUI元素,否則它不應該知道或關心UI中的其他任何內容。

控制器應該繼續做它應該做的事 - 響應其他事件觸發事件。但是,這些事件應該是由應用程序需求定義的應用程序級事件。控制器不應該直接操縱GUI元素。相反,你應該創建組件(可能只是JWhatever的子類),它們將事件註冊到Controller中。

例如,使用nameChanged()函數創建一個TowerEventListener接口。控制器也有一個changeTowerName()功能,當被調用時,更新模型(塔類),然後在所有註冊的TowerEventListeners上調用nameChanged()

然後創建一個TowerRenamer類,例如,包含文本框和OK按鈕以及對Controller的引用的子類JDialog(即彈出窗口)。當用戶點擊OK時,調用Controller.changeTowerName()。其他註冊爲TowerEventListeners的GUI部分將根據需要接收事件並進行更新(可能通過在UI上更新JLabel)。

注意,如果您的需求足夠簡單,您可以使用PropertyChangeEvents而不必擔心整個事件接口結構。控制器可以使用PropertyChangeSupport來觸發事件通知。

2

除了已經給出的很好的建議,我建議讀一些Trygve Reenskaug已經寫和/或記錄了on his MVC page。 70年代後期,他在這個建築風格的發展過程中在那裏。他的1979年12月發表的兩頁技術報告Models - Views - Controllers提供了對模型,視圖和控制器的最簡潔的描述。

特別值得注意的是,觀點均爲觀察者機械手的模型。控制器主要負責安排(佈線)視圖並將用戶輸入轉換爲與模型的交互。幾個MVC框架都有控制器將數據從模型中繼到視圖 - 這是完全錯誤的。 A paper from earlier in 1979包括作爲相關視圖的組合的編輯器的概念。編輯被丟棄;其功能被移入控制器和視圖。

另一篇文章,擅長描述如何應用本指南是Burbeck's How to use Model-View-Controller。它是用Smalltalk編寫的,因此它可能不會輕鬆轉換爲Java,但它是如何應用指南的很好的描述。

我認爲最重要的是考慮最初的MVC風格是爲包含同一模型的多個視圖(表示)的用戶界面創建的。這對用戶界面非常有效,但對於Web服務世界來說並沒有很好的轉化。使用MVC進行圖形用戶界面可以讓你真正看到和理解這種風格的力量。