2008-11-26 8 views
2

J'ai un JFrame qui contient un "affichage" JPanel avec JTextField et un "contrôle" JPanel avec des boutons qui doivent accéder au contenu de l'affichage JPanel. Je pense que mon problème est lié à la façon d'utiliser le modèle d'observateur, que je comprends en principe. Vous devez placer des écouteurs et mettre à jour des messages, mais je n'ai pas la moindre idée de l'endroit où les mettre, comment accéder d'un panneau à l'autre et peut-être si nécessaire d'introduire une classe "datamodel". Par exemple, je veux accéder au contenu du JTextField à partir du panneau de commande et j'utiliser un écouteur d'action anonyme comme suit:Comment accéder à plusieurs JPanels dans JFrame?

JButton openfile = new JButton("Convert file"); 
openfile.addActionListener(new ActionListener() { 
    public void actionPerformed(ActionEvent e) { 
     openButtonPressed(); 
    }   
}); 

Répondre

1

Vous devez réduire le couplage entre ces objets.

Vous pouvez avoir un objet maître, qui possède tous les champs de texte et le bouton (les panneaux ne sont pas pertinents)

Ensuite, un ActionListener separete dans cet objet maître (je l'appelle médiateur voir schéma de médiateur)

Cet écouteur d'actions exécute une méthode sur le médiateur qui, à son tour, prend les valeurs des champs de texte et crée peut-être un objet de transfert.

De cette façon, vous réduisez le couplage entre les panneaux, les champs de texte, etc. et laissez le contrôle à un endroit (le médiateur) qui est, vous ne les laissez pas se connaître.

Vous pouvez jeter un oeil au code dans cette question: https://stackoverflow.com/questions/324554/#324559

Il montre ces concepts dans le code en cours d'exécution.Par ailleurs, le modèle d'observateur est déjà implémenté dans JTextField, JButton, ActionListener, etc. Vous avez juste besoin d'ajouter les crochets.

J'espère que cela aide.

EDIT Joint deux réponses en une seule.

Ceci est le code.

class App { // this is the mediator 

    // GUI components. 
    private JFrame frame; 
    private JTextField name; 
    private JTextField count; 
    private JTextField date; 
    // Result is displayed here. 
    private JTextArea textArea; 

    // Fired by this button. 
    private JButton go; 

    private ActionListener actionListener; 


    public App(){ 
     actionListener = new ActionListener(){ 
      public void actionPerformed(ActionEvent e){ 
       okButtonPressed(); 
      } 
     }; 
    } 

    private void okButtonPressed(){ 
     // template is an object irrelevant to this code. 
     template.setData(getData()); 
     textArea.setText(template.getTransformedData()); 
    } 


    public void initialize(){ 

     frame  = new JFrame("Code challenge v0.1"); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 

     name  = new JTextField(); 
     count = new JTextField(); 
     date  = new JTextField(); 
     textArea = new JTextArea(); 
     go  = new JButton("Go"); 
     go.addActionListener(actionListener); // prepare the button. 

     layoutComponents(); // a lot of panels are created here. Irrelevant. 
    } 
} 

code complet et en cours d'exécution peut être récupéré here:

Il est important de favoriser la composition de l'héritage lorsque cela est possible.

1

Cela fait le nettoyeur de code si vous créez des modèles dans une couche et ajouter un couche ou deux ci-dessus pour créer les composants et la mise en page. Certainement ne pas étendre les goûts de JFrame et JPanel.

Ne vous sentez pas obligé de faire en sorte que la hiérarchie de composition de la couche de modèle corresponde exactement à l'affichage. Ensuite, il suffit de prendre le texte du Document et d'effectuer l'opération correspondante.

D'accord, perhpas pas si simple. Les modèles Swing sont un peu brouillon. En particulier ButtonModel est endommagé par le cerveau, et la zone de contrôleur du code peut ne pas être entièrement pure.

0

Nous avons ce qu'on appelle des constructeurs, qui vont construire le panneau parent sur les enfants. Dans ce générateur, vous aurez accès à tous les sous-composants à écouter et pourrez ainsi implémenter n'importe quelle logique.

Enfin, le constructeur retournera le panneau parent avec la logique complète. Une fois que vous avez le panneau parent, c'est vraiment un désordre d'arriver aux composants enfants et de les faire faire n'importe quoi.

0

merci. J'ai ajouté une couche datamodel qui gère en quelque sorte la communication entre les panneaux.

J'ai aussi trouvé ce lien sur le Listeners JTextField UTILE:

link text

Questions connexes