2017-03-04 2 views
0

J'essaie de mettre en œuvre une interface graphique en Java Swing (je suis nouveau à Swing). J'ai un panel parent qui contient 2 panneaux. Un panneau de gauche et un panneau de droite. Le panneau de gauche a un menu déroulant JComboBox. Le panneau de droite est un CardLayout avec 7 cartes. Je veux changer la carte affichée dans le panneau de droite en fonction du choix dans JComboBox dans le panneau de gauche. Les trois panneaux sont des classes séparées: LeftPanel.java, RightPanel.java et ParentPanel.java. J'ai du mal à trouver un endroit pour mettre les auditeurs d'action pour cette action. LeftPanel ne peut pas voir le CardLayout du RightPanel et le ParentPanel n'est pas capable d'accéder au CardLayout du RightPanel enfant non plus. J'ai vu quelques articles sur l'accès à CardLayout d'un autre JPanel mais aucune des approches n'a fonctionné pour moi jusqu'ici. Y a-t-il un défaut dans mon design? Ou est-ce possible d'y parvenir?Comment déclencher l'action dans un enfant JPanel d'entrée dans un autre enfant JPanel (Java Swing)?

EDIT Merci pour le conseil jusqu'à présent. Étant donné ci-dessous est mon MCVE. Veuillez noter que chaque classe est dans son propre fichier (.java). Je l'ai fait au lieu de tout mettre dans la classe Frame juste pour faciliter la maintenance. J'avais tout dans une classe auparavant et cela a bien fonctionné, mais il est devenu un fichier long avec plus de 2000 lignes de code et plus de 20 panneaux.

// classe MainFrame contenant la méthode principale:

paquet tempgui; MainFrame public class extends 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); 
} 

}

// Classe ParentPanel: ParentPanel public class étend 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); 
} 

}

// Classe LeftPanel: publique classe LeftPanel extends 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); 
} 

}

// Classe RightPanel: RightPanel public class étend 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); 
} 

}

// Classe RP1Panel: RP1Panel public class étend JPanel {

private JPanel RP1; 
private JLabel JRP1; 

public RP1Panel(){ 

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

}

// Classe RP2Panel: RP2Panel public class étend JPanel {

private JPanel RP2; 
private JLabel JRP2; 

public RP2Panel(){ 

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

}

+2

'" Ou est-il possible d'y parvenir? "- oui, très certainement. "" Y a-t-il une faille dans mon design? "- Sans code pertinent, de préférence valide, il est impossible de dire où est votre problème. Encore une fois, pensez à créer et poster un MCVE, un petit programme, assez petit pour être posté dans votre question sous forme de texte au format texte, qui compile et fonctionne, et qui démontre votre problème pour nous. Ce n'est pas tout votre programme, il n'a pas toutes ses fonctionnalités, mais encore une fois il fonctionne pour nous, et il démontre le problème pour nous. –

+1

* "Les 3 panneaux sont des classes séparées" * L'étape 1 de cette énigme serait probablement "ne pas étendre inutilement les classes de composants". Pouvez-vous expliquer pourquoi il faut étendre les panels ici? –

Répondre

1

Je voudrais essayer de donner mes classes des méthodes qui permettent aux autres classes d'extraire "état" informations à partir d'eux, tels que l'état de la liste déroulante, et permettre à d'autres classes de les muter, comme permettre aux auditeurs d'être ajoutés à la liste déroulante.Par exemple:

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

Puis d'autres classes peuvent écouter les modifications apportées à la zone de liste déroulante et extraire la sélection si nécessaire. Le panneau de droite aurait également une méthode pour permettre le changement de la "carte" JPanel qu'il affiche. Quelque chose comme:

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

Et ils pourraient être liés ensemble dans la principale:

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

L'ensemble MCVE pourrait ressembler à:

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

Merci beaucoup! Cela a fonctionné parfaitement pour mon cas. Je suppose que je peux utiliser une approche similaire pour implémenter les boutons Précédent, Suivant sur un JPanel pour contrôler le basculement entre les cartes sur un autre JPanel. Similaire à la création d'une boîte de dialogue Wizard. – nmokc