ListSelectionListener and CardLayout

独自空忆成欢 提交于 2019-12-13 07:47:09

问题


I'm creating a program that reads data from a file, displays it on a GUI that has a JList and JButtons. I am trying to write it with CardLayout so the appropriate JPanel can be displayed when an item is selected from the JList or a JButton is clicked (i.e. next, previous, first and last). I am able to successfully read from the file and display data to the GUI. I've run into 2 problems and I've tried searching online for answers but cant seem to figure it out: 1) How do I get the JPanels to switch using CardLayout? 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? The JList does appear and my ListSelectionListener is working because when I click on a particular item, it will print to the console (as a test).

If I comment out all of the JPanels except for 1, then it is correctly displayed but when I place all of them, then it does not switch.

So far, I have this for my ListSelectionListener (as an inner class):

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

The data for each JPanel is populated from static inner classes in the CancerPanels class (only showing 1 as each is very long!)

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;
    }
}

Edit:

Here is my most recent attempt. I can scroll through the JList but it doesn't properly display the correct corresponding JPanel (in fact it doesn't display anything, except whenever I click the last button, I don't know why that button works). I successfully managed to place an ItemListener on a JComboBox but ultimately, I want the CardLayout to work. Our instructor provided us with sample code to use but when I try it, the JPanels do not switch (or if they do they're hidden, not sure why).

Each of my listeners are public inner classes in the overall CancerGUI class.

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);
        }
    }
}        

Seperate class where the JPanels are made before being added to CardLayout:

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:


  • In essence what you are trying to do is to change the state of one class from another.
  • How this is done with Swing GUI's is no different for how it is done for non-GUI programs: one class calls the public methods of another class.
  • One key is to have wiring to allow this to occur which means references for one class needs to be available to the other class so that appropriate methods can be called on appropriate references. The devil as they say is in the details.
  • "1) How do I get the JPanels to switch using CardLayout?" -- So the class that holds the CardLayout could for instance have the public methods, next(), previous(), and perhaps show(SOME_STRING_CONSTANT) or some other swapView(...) method.
  • "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?" -- This will involve the use of listeners -- the class holding the JTextFields will listen for notification from the class that holds the JList, and when notified gets the necessary information from the list-displaying class. A PropertyChangeListener could work well here.

e.g.,

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(...);
           }
       }

    }   
}


来源:https://stackoverflow.com/questions/16096672/listselectionlistener-and-cardlayout

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!