-1

我正在创建一个从文件中读取数据的程序,并将其显示在具有 JList 和 JButtons 的 GUI 上。我正在尝试使用 CardLayout 编写它,以便在从 JList 中选择项目或单击 JButton 时(即下一个、上一个、第一个和最后一个)可以显示适当的 JPanel。我能够成功地从文件中读取数据并将数据显示到 GUI。我遇到了 2 个问题,我尝试在网上搜索答案,但似乎无法弄清楚: 1) 如何让 JPanel 使用 CardLayout 进行切换?2) 当用户单击 JList 中的项目时,如何让数据显示在 GUI 中的文本字段中?JList 确实出现并且我的 ListSelectionListener 正在工作,因为当我单击特定项目时,它将打印到控制台(作为测试)。

如果我注释掉除 1 之外的所有 JPanel,则它会正确显示,但是当我放置所有 JPanel 时,它不会切换。

到目前为止,我的 ListSelectionListener 有这个(作为内部类):

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

每个 JPanel 的数据由 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(实际上它不显示任何内容,除非我单击最后一个按钮,我不知道为什么该按钮有效)。我成功地将 ItemListener 放置在 JComboBox 上,但最终,我希望 CardLayout 能够正常工作。我们的讲师为我们提供了示例代码供我们使用,但是当我尝试时,JPanels 不会切换(或者如果他们这样做了,它们会被隐藏,不知道为什么)。

我的每个听众都是整个 CancerGUI 类中的公共内部类。

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

在添加到 CardLayout 之前制作 JPanel 的单独类:

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

1 回答 1

3
  • 本质上,您要做的是改变一个类的状态。
  • Swing GUI 的实现方式与非 GUI 程序的实现方式没有什么不同:一个类调用另一个类的公共方法。
  • 一个关键是进行布线以允许这种情况发生,这意味着一个类的引用需要对另一个类可用,以便可以在适当的引用上调用适当的方法。正如他们所说,魔鬼在细节中。
  • "1) How do I get the JPanels to switch using CardLayout?"-- 所以持有 CardLayout 的类可以有公共方法,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(...);
           }
       }

    }   
}
于 2013-04-19T03:22:53.157 回答