2010-02-10 32 views
7

Tôi đang cố gắng theo mẫu MVP (cụ thể Passive-View) trong một ứng dụng java swing ui.View Model Presenter và Composite Xem

Thiết kế cơ bản của ứng dụng sẽ nhắc điều khiển trình hướng dẫn. Màn hình được chia thành hai phần chính:

  • chế độ xem đang kích hoạt.
  • thanh điều hướng tĩnh, có các nút điều hướng.

Người dùng có thể sử dụng các nút để thay đổi chế độ xem hiện hoạt, nhưng thanh luôn được hiển thị.

Tạo mô hình kịch bản này, tôi có một loạt các trình thu thập khác nhau, mỗi trình bày riêng của nó, giao diện xem và triển khai chế độ xem (sử dụng JPanel). Sau đó, tôi có một người trình bày Shell, xem intefrace và xem thực hiện, bằng cách sử dụng một JFrame. Ý tưởng là vỏ sẽ tải đầu tiên và luôn được hiển thị, hiển thị thanh điều hướng phía dưới và để lại một khoảng trống cho chế độ xem đang kích hoạt. Người dẫn chương trình shell sẽ cho phép thiết lập các màn hình hoạt động hiện nay, phần nào như thế này:

interface View { 
} 

class Presenter { 
    View view; 

    public Presenter(View view) { 
     this.view = view; 
    } 

    public View getView() { 
     return view; 
    } 

} 

interface ShellView extends View { 
    void setActiveView(View activeView); 
} 

class ShellPresenter extends Presenter { 
    private ShellView shellView; 

    public void setActivePresenter(Presenter activePresenter) { 
     shellView.setActiveView(activePresenter.getView()); 
    } 
} 

class ShellFrame implements ShellView { 
    private JFrame frame; 
    private JPanel activePanel; 
    private JPanel navigationBar; 

    public ShellFrame() { 
     Container c = frame.getContentPane(); 
     c.add(activePanel); 
     c.add(navigationBar); 
    } 

    public setActiveView(View activeView) { 
     ??? 
    } 
} 

Vấn đề là trong phương pháp setActiveView: Tôi không chắc chắn làm thế nào để thiết lập các activeview đến activePanel, khi Xem giao diện là chung và như vậy không biết gì về JPanels. Rõ ràng là tôi cũng không muốn các diễn giả của tôi biết về JPanels.

+0

Bạn đã bao giờ tìm ra cách để làm điều này? Không có câu nào trong số những câu trả lời này đặc biệt tốt. Tôi vừa đăng chủ đề này: http://stackoverflow.com/questions/17836421/how-dumb-can-mvp-views-really-be – durron597

Trả lời

1

bạn có thể thay đổi định nghĩa về xem để:

interface View { 
    JComponent getContainer(); 
} 

Vì vậy mà mỗi điểm có thể dễ dàng nhận được các nội dung xem? Shell không cần biết việc thực hiện JComponent đang được trả về.

1

Xem giao diện của bạn cần phải cung cấp một số cách để có được một cái gì đó thể hiển thị trong một JPanel:

interface View { 
    Component getComponent(); 
} 

Sau đó, trong ShellFrame (giả sử bạn sử dụng BorderLayout, như tôi sẽ), bạn có thể thiết lập các quan điểm theo cách sau:

public setActiveView(View activeView) { 
    activePanel.add(activeView.getComponent(), BorderLayout.CENTER);  
} 
1

Vấn đề là JFramecủa bạn làView, không phải từng chế độ xem phụ đang hoạt động riêng lẻ. Chế độ xem đang hoạt động ngay bây giờ là công việc hiển thị và do đó phải được thực hiện bởi View, không phải bởi Presenter. Hãy tưởng tượng bạn muốn trao đổi trong một khác nhau View rằng thay vì chỉ có một chế độ xem phụ có thể nhìn thấy, tất cả chúng đều hiển thị, nhưng cái đang hoạt động có màu nền khác. Người trình bày chỉ kiểm soát cái nào đang hoạt động, nhưng View kiểm soát những gì có nghĩa là hoạt động.

Vì vậy, nhiệm vụ của bạn không thể được thực hiện mà không phá vỡ đóng gói bởi vì bạn đang cố gắng để làm một công việc mà nó rất tự nhiên phá vỡ đóng gói. Vì vậy, tôi sẽ làm một cái gì đó như thế này:

class PresenterManager { 
    private Presenter activePresenter; 
    private List<Presenter> allPresenters; 

    IView view; 

    PresenterManager(IView view) { 
     this.view = view; 
     view.subscribe(this); 
    } 

    void addPresenter(Presenter p) { 
     allPresenters.add(p); 
    } 

    void setView(int index) { 
     view.setView(index); 
     activePresenter = allPresenters.get(index); 
    } 
} 

class SwingView implements IView { 
    List<SubView> allViews; 
    SubView activeView; 
    int lastIndex; 

    public void setView(int index) { 
     if(index != lastIndex) { 
      activeView.setVisible(false); 
      activeView = allViews.get(index); 
      lastIndex = index; 
     } 
    } 
} 
Các vấn đề liên quan