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

问题描述:

我想在Java Swing中实现一个GUI(我是Swing的新手)。我有一个拥有2个面板的父面板。左侧面板和右侧面板。左侧面板有一个JComboBox下拉菜单。右侧面板是带有7张卡片的CardLayout。我想根据左侧面板中JComboBox的选择更改显示在右侧面板中的卡。所有3个面板都是独立的类:LeftPanel.java,RightPanel.java和ParentPanel.java。我很难找到一个放置这个动作的动作侦听器的地方。 LeftPanel无法看到RightPanel的CardLayout,并且ParentPanel也无法访问子RightPanel的CardLayout。我看到一些关于访问另一个JPanel的CardLayout的文章,但到目前为止,还没有任何方法可以用于我。我的设计有缺陷吗?或者有可能实现这一目标?如何触发一个孩子JPanel从另一个孩子JPanel(Java Swing)输入中的操作?

编辑 感谢您的建议,到目前为止。下面给出的是我的MCVE。请注意,每个类都在它自己的(.java)文件中。我这样做并不是为了便于维护而将所有内容都放在Frame类中。我以前在一个类中拥有所有的东西,并且它运行良好,但它成为一个包含2000多行代码和20多个面板的长文件。

//包含main方法级的主机:

包tempgui; 公共级的主机延伸的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); 
} 

}

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

}

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

}

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

}

//类RP1Panel: 公共类RP1Panel扩展JPanel {

private JPanel RP1; 
private JLabel JRP1; 

public RP1Panel(){ 

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

}

//类RP2Panel: 公共类RP2Panel扩展JPanel {

private JPanel RP2; 
private JLabel JRP2; 

public RP2Panel(){ 

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

}

+2

'“或者是有可能实现这一目标? “” - 是的,绝对是。 ''我的设计中是否有缺陷?'' - 没有相关的代码,最好是有效的[mcve],不可能说出问题出在哪里。再次,考虑创建并发布MCVE,一个小程序,足够小,可以作为代码格式的文本发布到您的问题中,编译和运行的文本,并向我们展示您的问题。这不是你的整个计划,它没有全部的功能,但它又一次为我们运行,并且它证明了我们的问题。 –

+1

*“所有3个面板都是独立的类”*步骤1到这个难题可能是“不要不必要地扩展组件类”。你能解释一下扩展面板的情况吗? –

我会尽量给我的类的方法,允许其他类提取物 “状态” 信息从他们,如组合框的状态,并允许其他类来突变它们,例如允许侦听器添加到组合框。例如:

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

然后其他类可以侦听对组合框的更改,并在需要时提取选择。右面板同样会有一个方法来允许更改显示的“卡”JPanel。喜欢的东西:

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

整个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); 
    } 
} 
+0

非常感谢!这对我的情况非常合适。我想我可以使用类似的方法在一个JPanel上实现Back,Next按钮来控制在另一个JPanel上的卡片之间来回翻转。类似于创建向导对话框。 – nmokc