taggart
taggart

Reputation: 3

Communication between JFrame and JPanel

I have created JFrame using JFrame Form in NetBeans. In this JFrame I have JPanel with second JPanel nested. Then I have separate JPanel class (I've extended JPanel).

I want to use this separate JPanel as the nested one in the JFrame. When I click on a JButton I want to notify the JFrame, that the button was clicked.

So far I've managet to get the separate JPanel to the JFrame using the following in the initComponents() of the JFrame:

nestedPanel = new separateJPanel

But now I have no idea how to send information that the button has been clicked.

Any tips how I can achieve this?

Upvotes: 0

Views: 1719

Answers (2)

Malik Brahimi
Malik Brahimi

Reputation: 16711

You can give the frame a panel attribute and the panel a frame attribute to bind them together in memory. In this way, you can easily pass data through instance fields to one another.

public MyPanel extends JPanel {

    MyFrame frame;

    MyPanel(MyFrame frame) {
        this.panel = panel;
    }
}

Upvotes: 4

Hovercraft Full Of Eels
Hovercraft Full Of Eels

Reputation: 285405

One simple way is to give your JPanel class a delegation method that allows other classes to add ActionListeners to the button of interest. For example:

public void addButton1ActionListener(ActionListener listener) {
   button1.addActionListener(listener);
}

This way, if the JFrame holds an instance of the JPanel, it can call this method to pass a listener into the JButton. For example:

import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.*;

public class Foo {
   private static void createAndShowGui() {
      Frame1 frame = new Frame1();
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

// I almost never extend JFrame
class Frame1 extends JFrame {
   private Panel1 panel1 = new Panel1();
   private JLabel label = new JLabel(" ", SwingConstants.CENTER);

   public Frame1() {
      super("Foo");
      setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
      add(panel1, BorderLayout.CENTER);
      add(label, BorderLayout.SOUTH);
      pack();
      setLocationByPlatform(true);

      panel1.addButton1ActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            label.setText("Button pressed");
         }
      });
   }
}

class Panel1 extends JPanel {
   private JButton button1 = new JButton("Button");

   public Panel1() {
      add(button1);
   }

   public void addButton1ActionListener(ActionListener listener) {
      button1.addActionListener(listener);
   }
}

Note that this solution is fine for simple toy programs, but if your idea is to create a true large-scale application, this will not scale well as it increases your code's coupling and decreases cohesion. Much better in this situation would be to strive to create a program that uses a more Model-View-Control or MCV architecture.

Upvotes: 3

Related Questions