1

I am having trouble designing GUI's in an object oriented manner. The following code will help me express my question more clearly:

import javax.swing;
import java.awt.*;
import java.awt.event.*;

public class QuoteOptionsPanel extends JPanel
{
    private JLabel quote;
    private JRadioButton comedy, philosophy, carpentry;
    private String comedyQuote, philosophyQuote, carpentryQuote;
    //-----------------------------------------------------------------
    // Sets up a panel with a label and a set of radio buttons
    // that control its text.
    //-----------------------------------------------------------------
    public QuoteOptionsPanel()
    {
        comedyQuote = "Take my wife, please.";
        philosophyQuote = "I think, therefore I am.";
        carpentryQuote = "Measure twice. Cut once.";

        quote = new JLabel (comedyQuote);
        quote.setFont (new Font ("Helvetica", Font.BOLD, 24));

        comedy = new JRadioButton ("Comedy", true);
        comedy.setBackground (Color.green);

        philosophy = new JRadioButton ("Philosophy");
        philosophy.setBackground (Color.green);

        carpentry = new JRadioButton ("Carpentry");
        carpentry.setBackground (Color.green);

        ButtonGroup group = new ButtonGroup();
        group.add (comedy);
        group.add (philosophy);
        group.add (carpentry);

        QuoteListener listener = new QuoteListener();
        comedy.addActionListener (listener);
        philosophy.addActionListener (listener);
        carpentry.addActionListener (listener);

        add (quote);
        add (comedy);
        add (philosophy);
        add (carpentry);

        setBackground (Color.green);
        setPreferredSize (new Dimension(300, 100));
    }
    //*****************************************************************
    // Represents the listener for all radio buttons.
    //*****************************************************************
    private class QuoteListener implements ActionListener
    {
        //--------------------------------------------------------------
        // Sets the text of the label depending on which radio
        // button was pressed.
        //--------------------------------------------------------------
        public void actionPerformed (ActionEvent event)
        {
            Object source = event.getSource();
            if (source == comedy)
                quote.setText (comedyQuote);
            else
                if (source == philosophy)
                    quote.setText (philosophyQuote);
                else
                    quote.setText (carpentryQuote);
        }
    }
}

The above code simply creates a panel with three radio buttons, each corresponding to a quote. It also creates a label which displays a quote. Whenever a button is selected, the text in the label is set to the corresponding quote. I understand this code just fine. I run into trouble trying to modify it. Let's say I want to create the same program, but with the radio buttons stacked vertically on top of one another. Let's also say that I decide to go about this by adding the radio buttons to a panel with a BoxLayout, which I define in its own BoxPanel class. (I would then add the BoxPanel to my QuoteOptionsPanel, which would still contain my quote JLabel.) So my BoxPanel code might look something like this:

import java.awt.*;
import javax.swing.*;

public class BoxPanel extends JPanel
{
    private JRadioButton comedy, philosophy, carpentry;
    public BoxPanel()
    {
        setLayout (new BoxLayout (this, BoxLayout.Y_AXIS));
        setBackground (Color.green);

        comedy = new JRadioButton ("Comedy", true);
    comedy.setBackground (Color.green);
    philosophy = new JRadioButton ("Philosophy");
    philosophy.setBackground (Color.green);
    carpentry = new JRadioButton ("Carpentry");
    carpentry.setBackground (Color.green);

    ButtonGroup group = new ButtonGroup();
    group.add (comedy);
    group.add (philosophy);
    group.add (carpentry);

    QuoteListener listener = new QuoteListener();
    comedy.addActionListener (listener);
    philosophy.addActionListener (listener);
    carpentry.addActionListener (listener);

    }
    //*****************************************************************
    // Represents the listener for all radio buttons.
    //*****************************************************************
    private class QuoteListener implements ActionListener
    {
        //--------------------------------------------------------------
        // Sets the text of the label depending on which radio
        // button was pressed.
        //--------------------------------------------------------------
        public void actionPerformed (ActionEvent event)
        {
            Object source = event.getSource();

            I do not know what to do here.
        }
    }
}

So as you can see, I did not know how to define my QuoteListener class. I want it to perform the same function as in the original program I posted, but am unsure of how to make it do so. The label which displays the quote is located in QuoteOptionsPanel, so I do not have access to it. In essence I am asking for the optimal way to change a label on one panel with an event listener belonging to a component on a different panel. I would be immensely grateful for any help you may be able to provide. Please let me know if I have not expressed my question clearly enough.

mKorbel
  • 109,525
  • 20
  • 134
  • 319

2 Answers2

4

There are several ways to solve this, but for most all the key is to get and use references. Say the class that holds the JLabel as a private field has a public method,

public void setQuoteLabelText(String text) {
  quoteLabel.setText(text);
}

Then you have to pass the reference to the visualized object of this class to your BoxPanel class, either through a constructor parameter or a setXXX(...) setter method. Then your ActionListener can call methods on the object of this class.

Hovercraft Full Of Eels
  • 283,665
  • 25
  • 256
  • 373
1

1. You can create an instance of the class whose private instance variable you need to access.

2. Follow the one of the many use of Encapsulation, that is to have private Instance variable and public getter-setter for that instance variable.

3. Now you can access the private member, by calling the public method on the instance of the class.

4. One more thing, try using the Group Layout created by NetBeans team in 2005. Use the Window Builder Pro, now free from google.

Kumar Vivek Mitra
  • 33,294
  • 6
  • 48
  • 75