2013-08-21 2 views
0

세 페이지가있는 소프트웨어를 만들고 싶습니다. "홈 페이지"(JFrame "프레임"에 그려져 있음), "페이지 2"및 " 3 페이지.두 번째 페이지에서 세 번째 페이지를 호출 할 수 없습니다.

페이지 2와 3은 "프레임"에 그려집니다.

하나는 페이지의 왼쪽에있는 탐색 창을 사용하고 주요 내용은 오른쪽에 있습니다.

현재 두 번째 페이지로 이동할 수 있습니다. JFrame에 페이지 2를 그리기 위해 호출 된 클래스는 페이지 3을 호출 할 수 없습니다. 다음과 같이

내 코드는 다음과 같습니다

// The Home Page 

package Try; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JFrame; 
import javax.swing.JPanel; 

public class HomePage { 
    JPanel panelHomeWrapper = new JPanel(); 
    JPanel panelNavigation = new JPanel(); 
    JPanel panelDisplay = new JPanel(); 

    JButton buttonNavigation = new JButton("Button Home = Menu Items"); 
    JButton buttonBody = new JButton("Button body Page Home = Home body Items"); 

    public static void main (String[] args) { 
     HomePage home = new HomePage(); 
     home.homePanel(); 
    } 

    public void homePanel() { 
     JFrame frame = new JFrame("Home"); 

     JButton button = new JButton("Button"); 

     ActionListener actionListener = new ActionListener() { 
      public void actionPerformed(ActionEvent actionEvent) { 
       System.out.println("Panel 2 was called."); 

       Page2 panel2 = new Page2(); 

       panelNavigation.remove(buttonNavigation); 
       panelDisplay.remove(buttonBody); 

       panelNavigation.add(panel2.buttonNavigation); 
       panelDisplay.add(panel2.buttonBody); 

       panelNavigation.validate(); 
       panelNavigation.repaint(); 

       panelDisplay.validate(); 
       panelDisplay.repaint(); 
      } 
     }; 

     button.addActionListener(actionListener); 


     buttonNavigation.addActionListener(actionListener); 

     panelNavigation.add(buttonNavigation); 
     panelDisplay.add(buttonBody); 

     panelHomeWrapper.add(panelNavigation); 
     panelHomeWrapper.add(panelDisplay); 

     frame.add(panelHomeWrapper); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.setSize(455, 355); 
     frame.setVisible(true); 
    } 
} // End of Home Page 

페이지 2

// Page 2 

package Try; 

import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import javax.swing.JButton; 
import javax.swing.JPanel; 

public class Page2 { 
    JButton buttonNavigation = new JButton("Button 2 = Menu Items"); 
    JButton buttonBody = new JButton("Button body Page 2 = Page 2 body Items"); 

    ActionListener actionListenerCallAnotherPage = new ActionListener() { 
     @Override 
     public void actionPerformed(ActionEvent actionEvent) { 
      System.out.println("Button Body 3 was called."); 

      HomePage home = new HomePage(); 
      Page3 panel3 = new Page3(); 

      home.panelDisplay.remove(buttonBody); 
      home.panelDisplay.add(panel3.buttonBody3); 

      home.panelDisplay.validate(); 
      home.panelDisplay.repaint(); 

     } 
    }; 

    public void addAction() { 
     buttonNavigation.addActionListener(actionListenerCallAnotherPage); 
    } 
} 

페이지 3

// Page 3 

package Try; 

import javax.swing.JButton; 

public class Page3 { 
    JButton buttonBody3 = new JButton("Page 3"); 
} // End of Page 3 

날 2 클래스를 만드는 방법을 알아내는 데 도움하십시오 (2 페이지) 3 등급 (3 페이지)에 전화하십시오. 모두에게 미리 감사드립니다.

답변

2

문제는 Page2 클래스의 방법 addAction가 호출되지 않습니다 사실 것 같다. actionListenerCallAnotherPagebuttonNavigationJButton에 등록하는 데 책임이있는 것 같습니다.

지금 말하면 ... 이것은 거의 이득을 얻지 못한 것 같습니다.

이러한 방식으로 탐색을 하드 체인하려고하는 대신 탐색을 관리하는 일종의 모델을 사용해야합니다.

기본적으로, 당신은 차례로 각 페이지에이 모델의 참조를 전달 것이며 준비가되면 각 페이지, 다음 페이지로 이동 모델을 요청할 것입니다. 이 모델은 일종의 변경 이벤트를 발생시켜 현재 페이지가 변경되었고 뷰가 그에 따라 업데이트 될 것이라고 주 뷰에 표시합니다.

CardLayout과 함께이 작업을 수행 할 수 있습니다. 즉, 구성 요소에 대한 참조를 모델에 제공 할 필요가 없으며 대신 CardLayout과 연결된 "페이지 이름"을 사용하여 추가 디커플링 난 아직도 데이터 모델의 어떤 종류를 사용하십시오 기본 개념들이 데이터를 공유해야 할 경우에도, 서로 귀하의 의견을 분리하는 것입니다

, 프로그램 ...

모델 기반 접근 방식, 하지만 탐색 모델에 집중할 수 있습니다.

당신이 필요로하는 무엇

...

  • 가능한 모든 뷰의 일부 아이디어와 의견을 변경하는 그들이
  • 현재 "활성"보기
  • 어떤 방법으로 표시되어야 순서, 이전/다음 예를 들어 ...
  • 상태 변화에 대한 알림을 제공하는 몇 가지 방법 ...
  • 또한 실제 구성 요소와 모델을 분리하려고합니다."엄격하게"말하면서 잘못하지는 않지만, 도움이된다면 내 지식없이 수정할 수있는 곳으로 구성 요소가 전달되는 것을 좋아하지 않습니다. 보기를 업데이트하는 것은 모델의 책임이 아니라 컨트롤러의 책임입니다. 이는 화면에 표시되는 데 사용 된 실제 구성 요소가 모델과 관련이 없음을 의미합니다 ...

...

public interface ViewModel { 

    /** 
    * Returns the name of the current "active" view name 
    * @return 
    */ 
    public String getCurrentView(); 

    /** 
    * Instructs the model to move to the next view if one is 
    * available... 
    */ 
    public void nextView(); 

    /** 
    * Instructs the model to move to the previous view if one is 
    * available... 
    */ 
    public void previousView(); 

    /** 
    * Returns the number of views in this model 
    */ 
    public int size(); 

    /** 
    * Returns the name of the view at the specified index... 
    * @param index 
    * @return 
    */ 
    public String getViewAt(int index); 

    /** 
    * Adds a ChangeListeners to the model, which will be notified when 
    * the current view changes 
    */ 
    public void addChangeListener(ChangeListener listener); 

    /** 
    * Remove a ChangeListeners from the model 
    */ 
    public void removeChangeListener(ChangeListener listener); 

} 

...

지금, 나는 모든 지루한 반복 작업을 수행하는 추상 구현이 좋아 예를 들어 ...

public abstract class AbstractViewModel implements ViewModel { 

    private EventListenerList listenerList; 
    private List<String> views; 

    public void addView(String name) { 
     getViews().add(name); 
    } 

    public void removeView(String name) { 
     getViews().remove(name); 
    } 

    @Override 
    public int size() { 
     return views.size(); 
    } 

    @Override 
    public String getCurrentView() { 
     return getViewAt(getCurrentViewIndex()); 
    } 

    protected abstract int getCurrentViewIndex(); 

    protected List<String> getViews() { 
     if (views == null) { 
      views = new ArrayList<>(25); 
     } 
     return views; 
    } 

    @Override 
    public String getViewAt(int index) { 
     return index >= 0 && index < size() ? getViews().get(index) : null; 
    } 

    @Override 
    public void addChangeListener(ChangeListener listener) { 
     getListenerList().add(ChangeListener.class, listener); 
    } 

    @Override 
    public void removeChangeListener(ChangeListener listener) { 
     getListenerList().remove(ChangeListener.class, listener); 
    } 

    protected EventListenerList getListenerList() { 
     if (listenerList == null) { 
      listenerList = new EventListenerList(); 
     } 
     return listenerList; 
    } 

    protected void fireStateChanged() { 
     ChangeListener[] listeners = getListenerList().getListeners(ChangeListener.class); 
     if (listeners.length > 0) { 
      ChangeEvent evt = new ChangeEvent(this); 
      for (ChangeListener listener : listeners) { 
       listener.stateChanged(evt); 
      } 
     } 
    }  
} 
,536,

내 요구 사항을 충족시키기 위해 다른 구현을 고안 할 수 있습니다. ...

예를 들어, 여기서 "선형"뷰 모델을 제공 했으므로이 모델은 마지막 뷰까지 계속 이동하여 멈 춥니 다 또는 처음으로보고 멈추는 모든 길. 그것은 당신은 매핑 할 수있는 방법이 필요 것,

public class LinearViewModel extends AbstractViewModel { 

    private int currentIndex; 

    @Override 
    protected int getCurrentViewIndex() { 
     return currentIndex; 
    } 

    @Override 
    public void nextView() { 
     if (currentIndex + 1 < size()) { 
      currentIndex++; 
      fireStateChanged(); 
     } 
    } 

    @Override 
    public void previousView() { 
     if (currentIndex - 1 >= 0) { 
      currentIndex--; 
      fireStateChanged(); 
     } 
    }  
} 

시작하려면 ... 다른 쪽 끝 주위 플립 것, 그것은 모드 중 하나 끝에 도달 원형보기 모델을 만드는 데 많이받지 않을 것 그 뷰의 대표적인 구성 요소의 이름. 또한 지금 ...

private Map<String, Component> mapViews; 
private Component currentView; 
private LinearViewModel model; 

public ViewModelTest() { 

    // Maps the view name to the component... 
    mapViews = new HashMap<>(25); 
    model = new LinearViewModel(); 
    mapViews.put("Page01", new Page01()); 
    mapViews.put("Page02", new Page02()); 
    mapViews.put("Page03", new Page03()); 
    mapViews.put("Page04", new Page04()); 

    // Add the view names to the model... 
    model.addView("Page01"); 
    model.addView("Page02"); 
    model.addView("Page03"); 
    model.addView("Page04"); 

    // Initialise out view with the first page... 
    currentView = mapViews.get("Page01"); 
    add(currentView); 

    // Monitor for changes... 
    model.addChangeListener(new ChangeListener() { 
     @Override 
     public void stateChanged(ChangeEvent e) { 
      remove(currentView); 
      currentView = mapViews.get(model.getCurrentView()); 
      add(currentView); 
      revalidate(); 
     } 
    }); 

} 

를 모델에 대한 변경 사항을 모니터링 할 수있는 방법이 필요합니다 것입니다, 당신은 아마 궁금 어떻게합니까 다음/이전보기 내보기 이동 ...?

그렇지 않습니다. 대신, 모델 자체와 상호 작용하는 데 사용될 기본 화면에있는 탐색 모음을 만들 것입니다 ... 전체 프로세스에서 각 페이지 /보기를 분리하여 남겨 둡니다 ...

+0

답장을 보내 주셔서 감사합니다 . 나는 CardLayout을 완전히 피하려고 노력하고있다. "모델"(코드의 간단한 기본 구조)을 만드는 것을 시작하도록 도와주십시오. 그것은 크게 도움이 될 것입니다. 저는 JAVA에서 상당히 초보자이며이 시점까지 프로그래밍을 가르쳐 왔기 때문에 동료 또는 급우로부터 획득 한 기본 프로그래밍 개념으로 간주 될 수있는 것을 전혀 알지 못합니다. 다시 감사합니다. –

+0

왜 당신은'CardLayout'을 피하고 있습니까? – MadProgrammer

+0

이벤트를 통해 클래스를 호출하는 방법을 배우고 싶습니다. –

관련 문제