-1

ファイルからデータを読み取り、JList と JButton を持つ GUI に表示するプログラムを作成しています。JListからアイテムが選択されたとき、またはJButtonがクリックされたときに適切なJPanelを表示できるように、CardLayoutで記述しようとしています(つまり、次、前、最初、最後)。ファイルから正常に読み取り、データを GUI に表示できます。私は2つの問題に遭遇し、オンラインで回答を検索しようとしましたが、それを理解できないようです: 1) CardLayoutを使用してJPanelsを切り替えるにはどうすればよいですか? 2) ユーザーが JList から項目をクリックしたときに、GUI のテキスト フィールドに表示されるデータを取得するにはどうすればよいですか? JList が表示され、ListSelectionListener が機能しているのは、特定の項目をクリックすると (テストとして) コンソールに出力されるためです。

1つを除いてすべての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 が正しく表示されません (実際、最後のボタンをクリックするたびに、そのボタンが機能する理由がわからない場合を除いて、何も表示されません)。JComboBox に ItemListener を配置することに成功しましたが、最終的には CardLayout を機能させたいと考えています。インストラクターが使用するサンプル コードを提供してくれましたが、試してみると、JPanels が切り替わりません (または切り替えた場合、理由はわかりません)。

私のリスナーはそれぞれ、CancerGUI クラス全体の public 内部クラスです。

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 に追加される前に JPanels が作成される別のクラス:

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 以外のプログラムで行う方法と同じです。あるクラスが別のクラスの public メソッドを呼び出します。
  • 重要な点の 1 つは、これを可能にするための配線を用意することです。つまり、適切な参照で適切なメソッドを呼び出せるように、あるクラスの参照を他のクラスで使用できるようにする必要があります。彼らが言うように、悪魔は細部に宿ります。
  • "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 に答える