简体   繁体   English

如何从另一个子JPanel中的输入触发一个子JPanel中的动作(Java Swing)?

[英]How to trigger action in one child JPanel from input in another child JPanel (Java Swing)?

I am trying to implement a GUI in Java Swing (I am new to Swing). 我正在尝试在Java Swing中实现GUI(我是Swing的新手)。 I have a parent panel that holds 2 panels. 我有一个包含2个面板的父面板。 A left panel and a right panel. 左面板和右面板。 The left panel has a JComboBox dropdown menu. 左侧面板上有一个JComboBox下拉菜单。 The right panel is a CardLayout with 7 cards. 右侧面板是7张卡片的CardLayout。 I want to change the card displayed in the right panel based on the choice in the JComboBox in the left panel. 我想根据左侧面板中JComboBox中的选择更改右侧面板中显示的卡。 All 3 panels are separate classes: LeftPanel.java, RightPanel.java, and ParentPanel.java. 所有3个面板都是单独的类:LeftPanel.java,RightPanel.java和ParentPanel.java。 I am having a hard time finding a place to put the action listeners for this action. 我很难找到一个放置动作监听器的地方。 The LeftPanel can't see the CardLayout of the RightPanel and the ParentPanel isn't able to access the CardLayout of the child RightPanel either. LeftPanel无法看到RightPanel的CardLayout,并且ParentPanel也无法访问子级RightPanel的CardLayout。 I saw some posts about accessing CardLayout of another JPanel but none of the approaches have worked for me so far. 我看到了一些有关访问另一个JPanel的CardLayout的帖子,但是到目前为止,这些方法都没有对我有用。 Is there a flaw in my design? 我的设计有缺陷吗? Or is it possible to achieve this? 还是有可能实现这一目标?

EDIT Thanks for the advice so far. 编辑感谢到目前为止的建议。 Given below is my MCVE. 以下是我的MCVE。 Please note that each class is in its own (.java) file. 请注意,每个类都在其自己的(.java)文件中。 I did that instead of putting everything in the Frame class just for ease of maintenance. 我这样做不是为了方便维护而将所有内容都放在Frame类中。 I had everything in one class previously and it worked fine but it became one long file with 2000+ lines of code and 20+ panels. 我以前把所有内容都放在一个类中,并且运行良好,但是变成了一个长文件,包含2000多个代码行和20多个面板。

//Class MainFrame containing the Main method: //包含Main方法的MainFrame类:

package tempgui; 包tempgui; public class MainFrame extends JFrame{ 公共类MainFrame扩展了JFrame {

JFrame Frame1;

public static void main(String[] args){

    new MainFrame();
}

public MainFrame(){

    Frame1 = new JFrame();
    Frame1.setDefaultCloseOperation(EXIT_ON_CLOSE);

    Frame1.getContentPane().add(new ParentPanel(), BorderLayout.CENTER);        

    Frame1.setSize(800, 600);
    Frame1.setLocationRelativeTo(null);
    Frame1.pack();

    Frame1.setVisible(true);
}

} }

//Class ParentPanel: public class ParentPanel extends JPanel{ // // ParentPanel类:公共类ParentPanel扩展了JPanel {

private JPanel ParentPanel;
private LeftPanel LP;
private RightPanel RP;

public ParentPanel(){

    ParentPanel = new JPanel();
    LP = new LeftPanel();
    RP = new RightPanel();

    ParentPanel.setLayout(new GridLayout(1,2));

    ParentPanel.add(LP);
    ParentPanel.add(RP);

    add(ParentPanel);
}

} }

//Class LeftPanel: public class LeftPanel extends JPanel{ // // LeftPanel类:公共类LeftPanel扩展了JPanel {

private JPanel LeftPanel;
private JComboBox J1;

public LeftPanel(){

    LeftPanel = new JPanel();

    String[] Arr = {"RP1","RP2"};

    J1 = new JComboBox(Arr);

    LeftPanel.add(J1);

    add(LeftPanel);
}

} }

//Class RightPanel: public class RightPanel extends JPanel{ // // RightPanel类:公共类RightPanel扩展了JPanel {

private JPanel RightPanel;
private RP1Panel RP1;
private RP2Panel RP2;
private CardLayout C1;

public RightPanel(){

    RightPanel = new JPanel();
    RP1 = new RP1Panel();
    RP2 = new RP2Panel();

    C1 = new CardLayout();

    RightPanel.setLayout(C1);

    RightPanel.add(RP1, "RP1");
    RightPanel.add(RP2, "RP2");
    C1.show(RightPanel, "RP1");

    add(RightPanel);
}

} }

//Class RP1Panel: public class RP1Panel extends JPanel{ // // RP1Panel类:公共类RP1Panel扩展了JPanel {

private JPanel RP1;
private JLabel JRP1;

public RP1Panel(){

    RP1 = new JPanel();
    JRP1 = new JLabel("RP1 Panel");
    RP1.add(JRP1);
    add(RP1);
}

} }

//Class RP2Panel: public class RP2Panel extends JPanel{ // // RP2Panel类:公共类RP2Panel扩展了JPanel {

private JPanel RP2;
private JLabel JRP2;

public RP2Panel(){

    RP2 = new JPanel();
    JRP2 = new JLabel("RP2 Panel");
    RP2.add(JRP2);
    add(RP2);
}

} }

I would try to give my classes methods that allow other classes to extract " state " information from them, such as the state of the combobox, and allow other classes to mutate them, such as allowing listeners to be added to the combobox. 我将尝试给我的类方法允许其他类从它们中提取“ 状态 ”信息,例如组合框的状态,并允许其他类对其进行突变,例如允许将侦听器添加到组合框。 For instance: 例如:

// Class LeftPanel:
class LeftPanel extends JPanel {
    private JPanel leftPanel;
    private JComboBox<String> comboBox; //!!

    // !!
    public LeftPanel(String[] comboTexts) {
        leftPanel = new JPanel();
        comboBox = new JComboBox<>(comboTexts); // !!
        leftPanel.add(comboBox);
        add(leftPanel);
    }

    // !!
    public String getComboSelection() {
        return comboBox.getSelectedItem().toString();
    }

    // !!
    public void comboAddActionListener(ActionListener listener) {
        comboBox.addActionListener(listener);
    }
}

Then other classes can listen for changes to the combo box, and extract the selection when needed. 然后其他类可以侦听对组合框的更改,并在需要时提取选择。 The right panel would likewise have a method to allow change of the "card" JPanel that it displays. 右面板同样会具有允许更改其显示的“卡片” JPanel的方法。 Something like: 就像是:

// Class RightPanel:
class RightPanel extends JPanel {
    private JPanel rightPanel;
    private RP1Panel rightPanel1;
    private RP2Panel rightPanel2;
    private CardLayout cardLayout;

    public RightPanel() {
        rightPanel = new JPanel();
        rightPanel1 = new RP1Panel();
        rightPanel2 = new RP2Panel();
        cardLayout = new CardLayout();
        rightPanel.setLayout(cardLayout);
        rightPanel.add(rightPanel1, RP1Panel.NAME); //!!
        rightPanel.add(rightPanel2, RP2Panel.NAME);  // !!
        cardLayout.show(rightPanel, RP1Panel.NAME); // !!
        add(rightPanel);
    }

    // !! 
    public void showCard(String name) {
        cardLayout.show(rightPanel, name);
    }
}

And they could be tied together in the main: 它们可以在主要方面捆绑在一起:

// Class ParentPanel:
class ParentPanel extends JPanel {
    private JPanel ParentPanel;
    private LeftPanel leftPanel;
    private RightPanel rightPanel;

    public ParentPanel() {
        ParentPanel = new JPanel();
        leftPanel = new LeftPanel(new String[] {RP1Panel.NAME, RP2Panel.NAME});
        rightPanel = new RightPanel();
        ParentPanel.setLayout(new GridLayout(1, 2));
        ParentPanel.add(leftPanel);
        ParentPanel.add(rightPanel);
        add(ParentPanel);

        // !!
        leftPanel.comboAddActionListener(e -> {
            String selection = leftPanel.getComboSelection();
            rightPanel.showCard(selection);
        });
    }
}

The whole MCVE could look like: 整个MCVE可能看起来像:

import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.GridLayout;
import java.awt.event.ActionListener;

import javax.swing.*;

public class FooGui {
    public static void main(String[] args) {
        new MainFrame();
    }
}

class MainFrame extends JFrame {
    JFrame Frame1;

    public MainFrame() {
        Frame1 = new JFrame();
        Frame1.setDefaultCloseOperation(EXIT_ON_CLOSE);
        Frame1.getContentPane().add(new ParentPanel(), BorderLayout.CENTER);
        Frame1.setSize(800, 600);
        Frame1.setLocationRelativeTo(null);
        Frame1.pack();
        Frame1.setVisible(true);
    }
}

// Class ParentPanel:
class ParentPanel extends JPanel {
    private JPanel ParentPanel;
    private LeftPanel leftPanel;
    private RightPanel rightPanel;

    public ParentPanel() {
        ParentPanel = new JPanel();
        leftPanel = new LeftPanel(new String[] {RP1Panel.NAME, RP2Panel.NAME});
        rightPanel = new RightPanel();
        ParentPanel.setLayout(new GridLayout(1, 2));
        ParentPanel.add(leftPanel);
        ParentPanel.add(rightPanel);
        add(ParentPanel);

        // !!
        leftPanel.comboAddActionListener(e -> {
            String selection = leftPanel.getComboSelection();
            rightPanel.showCard(selection);
        });
    }
}

// Class LeftPanel:
class LeftPanel extends JPanel {
    private JPanel leftPanel;
    private JComboBox<String> comboBox; //!!

    // !!
    public LeftPanel(String[] comboTexts) {
        leftPanel = new JPanel();
        comboBox = new JComboBox<>(comboTexts); // !!
        leftPanel.add(comboBox);
        add(leftPanel);
    }

    // !!
    public String getComboSelection() {
        return comboBox.getSelectedItem().toString();
    }

    // !!
    public void comboAddActionListener(ActionListener listener) {
        comboBox.addActionListener(listener);
    }
}

// Class RightPanel:
class RightPanel extends JPanel {
    private JPanel rightPanel;
    private RP1Panel rightPanel1;
    private RP2Panel rightPanel2;
    private CardLayout cardLayout;

    public RightPanel() {
        rightPanel = new JPanel();
        rightPanel1 = new RP1Panel();
        rightPanel2 = new RP2Panel();
        cardLayout = new CardLayout();
        rightPanel.setLayout(cardLayout);
        rightPanel.add(rightPanel1, RP1Panel.NAME); //!!
        rightPanel.add(rightPanel2, RP2Panel.NAME);  // !!
        cardLayout.show(rightPanel, RP1Panel.NAME); // !!
        add(rightPanel);
    }

    // !! 
    public void showCard(String name) {
        cardLayout.show(rightPanel, name);
    }
}

// Class RP1Panel:
class RP1Panel extends JPanel {
    // !!
    public static final String NAME = "right panel 1";
    private JPanel RP1;
    private JLabel JRP1;

    public RP1Panel() {
        setName(NAME);
        RP1 = new JPanel();
        JRP1 = new JLabel("RP1 Panel");
        RP1.add(JRP1);
        add(RP1);
    }
}

// Class RP2Panel:
class RP2Panel extends JPanel {
    // !!
    public static final String NAME = "right panel 2";
    private JPanel RP2;
    private JLabel JRP2;

    public RP2Panel() {
        setName(NAME);
        RP2 = new JPanel();
        JRP2 = new JLabel("RP2 Panel");
        RP2.add(JRP2);
        add(RP2);
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM