2013-04-19 3 views
-1

파일에서 데이터를 읽고 JList 및 JButton이있는 GUI에 표시하는 프로그램을 만들고 있습니다. CardLayout으로 쓰려고하는데 JList에서 항목을 선택하거나 JButton을 클릭하면 (즉, 다음, 이전, 처음과 마지막) 적절한 JPanel을 표시 할 수 있습니다. 성공적으로 파일을 읽고 GUI에 데이터를 표시 할 수 있습니다. 나는 2 가지 문제를 겪었고 온라인 검색을 시도했지만 해답을 찾지 못했습니다. 1) CardLayout을 사용하여 JPanels를 전환하려면 어떻게해야합니까? 2) 사용자가 JList에서 항목을 클릭하면 텍스트 필드의 GUI에 데이터가 표시되도록하려면 어떻게해야합니까? 특정 항목을 클릭하면 테스트로 콘솔에 인쇄되기 때문에 JList가 나타나고 ListSelectionListener가 작동합니다.ListSelectionListener 및 CardLayout

1을 제외한 모든 JPanels를 주석 처리하면 올바르게 표시되지만 모든 내용을 배치하면 전환되지 않습니다.

는 지금까지 내가 (내부 클래스로) 내 ListSelectionListener에이를 각 매우이기 때문에 각 JPanel에 대한

public class CancerSelectionListener implements ListSelectionListener { 

    @Override 
    public void valueChanged(ListSelectionEvent e) { 
     Integer selection = (Integer)(((JList) e.getSource()).getSelectedIndex()); 
     if(selection == 0) { 
      System.out.println("blah"); // works 
      // switch to the corresponding JPanel in CardLayout 
     } 

    } 
} 

String[] tester; 
    String teste; 

    listModel = new DefaultListModel(); 

    for(int i = 0; i < 36; i++) { 

     tester = _controller.readCancer(i); // reads from the file, this part works! 
     teste = tester[0]; 

     listModel.addElement(teste); 

    } 

    cancerList = new JList(listModel); 
    cancerList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
    cancerList.setSelectedIndex(-1); 
    cancerList.setVisibleRowCount(5); 

    cancerListScroller = new JScrollPane(cancerList); 

    CardLayout myCardLayout; 
    myCardLayout = new CardLayout(); 
    mainPanel2.setLayout(myCardLayout); 

    myCardLayout.show(mainPanel2, "test"); 

    CancerPanels.aplPanel apl = new CancerPanels.aplPanel(); 
    CancerPanels.fcPanels fc = new CancerPanels.fcPanels(); 
    CancerPanels.vhlsPanels vhls = new CancerPanels.vhlsPanels(); 
    CancerPanels.pdgPanels pdg = new CancerPanels.pdgPanels(); 
    CancerPanels.cebpaPanels cebpa = new CancerPanels.cebpaPanels(); 


    mainPanel2.add(apl.aplReturn(), "test"); 
    mainPanel2.add(fc.fcReturn()); 
    mainPanel2.add(vhls.vhlsReturn()); 
    mainPanel2.add(pdg.pdgReturn()); 
    mainPanel2.add(cebpa.cebpaReturn()); 
    // I have 37 JPanels that are placed in the JPanel that uses CardLayout but I didn't post all of them as it would take up lots of space 

데이터하는 것은 CancerPanels 클래스의 정적 내부 클래스에서 채워집니다 (단 1을 보여주는 ! 긴)

public class CancerPanels extends CancerGUI { 

static JPanel cards; 
static CancerController _cons = new CancerController(); 
static String[] cancerData; 
static JScrollPane treatmentsScroller = new JScrollPane(txtTreatments, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
static JScrollPane causesScroller = new JScrollPane(txtCauses, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 

static JScrollPane symptomsScroller = new JScrollPane(txtSymptoms, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 

public static class aplPanel extends JPanel { 

    public JPanel aplReturn() { 
     treatmentsScroller.setViewportView(txtTreatments); 
     txtTreatments.setEditable(false); 
     causesScroller.setViewportView(txtCauses); 
     txtCauses.setEditable(false); 
     symptomsScroller.setViewportView(txtSymptoms); 
     txtSymptoms.setEditable(false); 
     cards = new JPanel(new GridLayout(6,1)); 
     cancerData = _cons.readCancer(0); 
     resultName.setText(cancerData[0]); 
     txtSymptoms.setText(cancerData[1]); 
     txtCauses.setText(cancerData[2]); 
     txtTreatments.setText(cancerData[3]); 
     resultRate.setText(cancerData[4]); 
     resultPrognosis.setText(cancerData[5]); 
     cards.add(resultName); 
     cards.add(symptomsScroller); 
     cards.add(causesScroller); 
     cards.add(treatmentsScroller); 
     cards.add(resultRate); 
     cards.add(resultPrognosis); 
     return cards; 
    } 
} 

편집 : 여기

내 가장 최근의 시도이다. JList를 스크롤 할 수는 있지만 올바른 JPanel을 제대로 표시하지 못합니다 (실제로 마지막 버튼을 클릭 할 때마다 버튼이 작동하는 이유를 모르겠지만 아무것도 표시되지 않습니다). JComboBox에 ItemListener를 성공적으로 배치했지만 궁극적으로는 CardLayout을 작동시키고 싶습니다. 강사가 사용할 샘플 코드를 제공해 주었지만 시도해 볼 때 JPanels가 전환되지 않습니다 (또는 숨겨진 이유가 확실하지 않은 경우).

각 청취자는 전체 CancerGUI 클래스의 공개 내부 클래스입니다. JPanel의이 CardLayout에 추가되기 전에 만들어진

public CancerGUI() { 
    CancerPanels.aplPanel apl = new CancerPanels.aplPanel(); 
    CancerPanels.fcPanels fc = new CancerPanels.fcPanels(); 
    CancerPanels.vhlsPanels vhls = new CancerPanels.vhlsPanels(); 
    // more than 30 JPanels that I add to the JPanel that uses CardLayout, so I only posted 3 
    // each of them uses the GridLayout 

mainPanel2 = new JPanel(new CardLayout()); 

    mainPanel2.add(apl.aplReturn(), "1"); 
    mainPanel2.add(fc.fcReturn(), "2"); 
    mainPanel2.add(vhls.vhlsReturn(), "3"); 

CancerActionButtons _cab = new CancerActionButtons(); 

    btnNext = new JButton("Next"); 
    btnPrevious = new JButton("Previous"); 
    btnFirst = new JButton("First"); 
    btnLast = new JButton("Last"); 
    btnClear = new JButton("Clear"); 

    btnNext.addActionListener(_cab); 
    btnPrevious.addActionListener(_cab); 

    btnFirst.addActionListener(_cab); 
    btnLast.addActionListener(_cab); 

CancerItemListener _item = new CancerItemListener(); // this listener works! 
    renalC.addItemListener(_item); 
    skinC.addItemListener(_item); 
    brainC.addItemListener(_item); 
    bladderC.addItemListener(_item); 
    ovarianC.addItemListener(_item); 
    pancC.addItemListener(_item); 
    breastC.addItemListener(_item); 

String[] tester; 
    String teste; 

    listModel = new DefaultListModel(); 

    for(int i = 0; i < 36; i++) { 

     tester = _controller.readCancer(i); 
     teste = tester[0]; 

     listModel.addElement(teste); 

    } 

    cancerList = new JList(listModel); 
    cancerList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 
    cancerList.setSelectedIndex(-1); 
    cancerList.setVisibleRowCount(5); 
    cancerListScroller = new JScrollPane(cancerList); 
    ListSelection _list = new ListSelection(); 
    cancerList.addListSelectionListener(_list); 

    JScrollPane treatmentsScroller = new JScrollPane(txtTreatments, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
    treatmentsScroller.setViewportView(txtTreatments); 
    JScrollPane causesScroller = new JScrollPane(txtCauses, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
    causesScroller.setViewportView(txtCauses); 
    JScrollPane symptomsScroller = new JScrollPane(txtSymptoms, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
    symptomsScroller.setViewportView(txtSymptoms); 

public class ListSelection implements ListSelectionListener { 

    @Override 
    public void valueChanged(ListSelectionEvent e) { 
     String selection = (String)(((JList)e.getSource()).getSelectedValue()); 
     ((CardLayout) mainPanel2.getLayout()).show(mainPanel2, selection); 
     ((CardLayout) mainPanel2.getLayout()).show(mainPanel2, selection); 
    } 

} 

public class CancerActionButtons implements ActionListener { 

    @Override 
    public void actionPerformed(ActionEvent e) { 
     switch(e.getActionCommand()) { 
      case "First": 
       ((CardLayout) mainPanel2.getLayout()).first(mainPanel2);  
      cancerCount = 1;            
       break; 
      case "Last": 
       ((CardLayout) mainPanel2.getLayout()).last(mainPanel2); 
      cancerCount = 11; 
       break; 
      case "Previous": 
       ((CardLayout) mainPanel2.getLayout()).previous(mainPanel2); 
      cancerCount--; 
      cancerCount = cancerCount < 1 ? 11 : cancerCount; 
       break; 
      case "Next": 
       ((CardLayout) mainPanel2.getLayout()).next(mainPanel2); 
      cancerCount++; 
      cancerCount = cancerCount > 11 ? 1 : cancerCount;  // 
       break; 
     } 
     cancerList.setSelectedIndex(cancerCount-1); 
    } 

} 

/** 
* Inner class that responds to any user interaction with a JComboBox for 
* general types of cancers. 
*/ 

public class CancerItemListener implements ItemListener { 

    @Override 
    public void itemStateChanged(ItemEvent e) { 
     JPanel showPanel = new JPanel(); 
     if(e.getStateChange() == ItemEvent.SELECTED) { 
      String selection = (String) e.getItem(); 
      if(selection.equalsIgnoreCase("skin cancer")) { 
       CancerPanels.skin skin = new CancerPanels.skin(); 
       showPanel = skin.skinReturn(); 
      } else if (selection.equalsIgnoreCase("bladder cancer")) { 
       CancerPanels.bladder bladder = new CancerPanels.bladder(); 
       showPanel = bladder.bladderReturn(); 
      } else if (selection.equalsIgnoreCase("pancreatic cancer")) { 
       CancerPanels.pancreatic pancreatic = new CancerPanels.pancreatic(); 
       showPanel = pancreatic.returnPancreatic(); 
      } else if (selection.equalsIgnoreCase("renal cancer")) { 
       CancerPanels.renal renal = new CancerPanels.renal(); 
       showPanel = renal.returnRenal(); 
      } else if (selection.equalsIgnoreCase("ovarian cancer")) { 
       CancerPanels.ovarian ovarian = new CancerPanels.ovarian(); 
       showPanel = ovarian.ovarianReturn(); 
      } else if (selection.equalsIgnoreCase("breast cancer")) { 
       CancerPanels.breast breast = new CancerPanels.breast(); 
       showPanel = breast.returnBreast(); 
      } else if (selection.equalsIgnoreCase("brain cancer")) { 
       CancerPanels.brain brain = new CancerPanels.brain(); 
       showPanel = brain.returnBrain(); 
      } else if (selection.equalsIgnoreCase("von hippel-lindau syndrome")) { 
       CancerPanels.vhlsPanels vhls = new CancerPanels.vhlsPanels(); 
       showPanel = vhls.vhlsReturn(); 
      } 
      JOptionPane.showMessageDialog(null, showPanel); 
     } 
    } 
}   

별도의 클래스 : 본질적으로

public class CancerPanels extends CancerGUI { 

static String name; 
static JPanel cards; 
static CancerController _cons = new CancerController(); 
static String[] cancerData; 
static JScrollPane treatmentsScroller = new JScrollPane(txtTreatments, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 
static JScrollPane causesScroller = new JScrollPane(txtCauses, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 

static JScrollPane symptomsScroller = new JScrollPane(txtSymptoms, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); 

public static class aplPanel extends JPanel { 

    public JPanel aplReturn() { 
     treatmentsScroller.setViewportView(txtTreatments); 
     txtTreatments.setEditable(false); 
     causesScroller.setViewportView(txtCauses); 
     txtCauses.setEditable(false); 
     symptomsScroller.setViewportView(txtSymptoms); 
     txtSymptoms.setEditable(false); 
     cards = new JPanel(new GridLayout(6,1)); 
     cancerData = _cons.readCancer(0); 
     resultName.setText(cancerData[0]); 
     txtSymptoms.setText(cancerData[1]); 
     txtCauses.setText(cancerData[2]); 
     txtTreatments.setText(cancerData[3]); 
     resultRate.setText(cancerData[4]); 
     resultPrognosis.setText(cancerData[5]); 
     cards.add(resultName); 
     cards.add(symptomsScroller); 
     cards.add(causesScroller); 
     cards.add(treatmentsScroller); 
     cards.add(resultRate); 
     cards.add(resultPrognosis); 
     return cards; 
    } 
+1

더 나은 도움을 받으려면 [SSCCE] (http://sscce.org/)를 게시하십시오. * "CardLayout을 사용하는 JPanel에 배치 된 37 개의 JPanel이 있습니다."* SSCCE에서 2 개의 패널 만 사용하여 문제를 시연 할 수 있습니다. –

+0

CancerPanels가 CancerGUI를 확장하는 이유는 무엇입니까? 이것은 상속의 나쁜 사용법 인 것처럼 보이고 무엇이든지 두려운 일을 망칠뿐입니다. 또한 문제를 단순화하고 컴파일 할 수있는 코드를 게시하지 않았기 때문에 게시 된 코드는 문제를 이해할 수 없으므로 쓸모가 없습니다. 나는 강하게 두 번째 @ 앤드류 톰슨 (AndrewThompson)이 당신이 [sscce] (http://sscce.org)를 만들고 게시한다는 권고를 권장합니다. –

+0

안녕하세요? 너 거기 있니? –

답변

3
  • 무엇을 당신이하려고하는 것은 또 다른에서 하나 개의 클래스의 상태를 변경하는 것입니다.
  • Swing GUI로 수행되는 방법은 GUI가 아닌 프로그램에서 수행되는 방법과 다르지 않습니다. 하나의 클래스가 다른 클래스의 공용 메소드를 호출합니다.
  • 하나의 열쇠는 이것이 일어날 수 있도록 배선하는 것입니다. 즉, 하나의 클래스에 대한 참조가 다른 클래스에 사용 가능해야 적절한 참조가 적절한 방법으로 호출 될 수 있어야합니다. 그들이 말하는 악마는 세부 사항에 있습니다.
  • "1) How do I get the JPanels to switch using CardLayout?" - 따라서 CardLayout을 보유하는 클래스는 public 메서드 인 next(), previous() 및 아마도 show(SOME_STRING_CONSTANT) 또는 다른 swapView(...) 메서드를 가질 수 있습니다.
  • "2) How do I get the data to be displayed in the GUI in text fields when a user clicks an item from the JList?" - 청취자의 사용이 필요합니다. JTextFields를 보관 유지하는 클래스는 JList를 보관 유지하는 클래스로부터의 통지를 대기하고, 통지를 받으면리스트 표시 클래스로부터 필요한 정보를 취득합니다. PropertyChangeListener는 여기서 잘 동작합니다.

,

public class CancerSelectionListener implements ListSelectionListener { 
    private CardDisplayingView cardDisplayingView = null; 

    public CancerSelectionListener(CardDisplayingView cardDisplayingView) { 
     this.cardDisplayingView = cardDisplayingView; 
    } 

    @Override 
    public void valueChanged(ListSelectionEvent e) { 
     int selection = ((JList) e.getSource()).getSelectedIndex(); 
     if(selection == 0) { 
      if (cardDisplayingView != null) { 
      cardDisplayingView.swapView(...); 
      } 
     } 

    } 
} 
+0

나는 propertychangelistener를 찾았지만 어떻게 내 용도로 사용할 수 있는지 이해하지 못했습니다. 또한, ActionListeners 및 ListSelectionListeners보다 적합할까요? 아니면 어떻게 사용합니까? 내 코드에서 또 다른 패스를 만들었고 더 많은 작업을 수행 할 수 있지만 여전히 오류 메시지를 생성하지 않고 이상하게 작동합니다. 가장 최근의 시도를 답으로 게시했습니다. –

+0

새 코드를 질문으로 마이그레이션했습니다. – trashgod