🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: aus.computers.java
Article #394

Re: making listener talk to class??

#394
From: Paul Murray
Date: Sat, 02 Dec 2000 00:00
182 lines
6964 bytes
Hmm. So you dont want your listener class to know about the actual buttons.
Firstly, using a nested class really is the neatest way to do this kind of
thing.

However, if you want to decouple functionality from interface without them
...

An button has two things of interest associated with it - a label and an
action command. These don't need to be the same. You can make up some
constants to pass messages between the two classes.


public class HexCalculator implements ActionListener {

    /* These are public constants for the various "calculator buttons" that
I recognise.
        the text is arbitrary, but I will make it meaningful in case the GUI
coder wants to use it
        as button text.
        If you *really* want to isolate these contants, put them in a
separate interface.
    */

    public static String DIGIT_0 = "0";
    public static String DIGIT_1 = "1";
    public static String DIGIT_2 = "2";
    // etc
    public static String DIGIT_E = "E";
    public static String DIGIT_F = "F";
    public static String KEY_MUL = "*";
    public static String KEY_DIV = "/";
    public static String KEY_LSH = "<<";

    public void actionPerformed(ActionEvent e) {
        if(DIGIT_0.equals(e.getActionCommand()) we_got_a_0();
        else if(DIGIT_1.equals(e.getActionCommand()) we_got_a_1();
        // etc
        else if(KEY.LSH.equals(e.getActionCommand()) we_got_a_left_shift();
        // etc
        else
            throw new IllegalArgumentException("Unrecognised action: \"" +
ex.getActionCommand() + "\"");
    }

    void we_got_a_0() // manage a key press of '0'
    {
        // your code goes here
    }
}


class HexCalculatorPanel extends JPanel implements ActionListener {
    JButton key_0;
    JButton key_1;
    JButton key_lsh;

    HexCalculatorPanel() {
        key_0 = new JButton(new ImageIcon(getImage("key0.gif"));
        key_0.setActionCommand(HexCalculator.DIGIT_0);
        key_0.addActionListener(this);
        key_1 = new JButton(new ImageIcon(getImage("key1.gif"));
        key_1.setActionCommand(HexCalculator.DIGIT_1);
        key_1.addActionListener(this);
        key_lsh = new JButton(new ImageIcon(getImage("leftshiftkey.gif"));
        key_lsh.setActionCommand(HexCalculator.KEY_LSH);
        key_lsh.addActionListener(this);
    }


    // when I get a keystroke from one of my keys, handle it by re-firing it
out to all my actionListeners.

    public void actionPerformed(ActionEvent e) {
        fireActionEvent(e);
        // alternatively, you can hide the gui component that is the source
of the action my making a new action
        /*
            fireActionEvent(new ActionEvent(this, e.getId(),
e.getActionCommand(), e.getModifiers());
        */
    }

 // this boilerplate is copied from the javax.swing.ListenerList javadocs.
 // note that the listenerList instance variable is inherited from
 //JComponent. no need to create your own.

 public void addActionListener(ActionListener l) {
     listenerList.add(ActionListener.class, l);
 }

 public void removeActionListener(ActionListener l) {
     listenerList.remove(ActionListener.class, l);
 }

protected void fireActionEvent(ActionEvent e) {
     Object[] listeners = listenerList.getListenerList();
     for (int i = listeners.length-2; i>=0; i-=2) {
         if (listeners[i]==ActionListener.class) {
             ((ActionListener)listeners[i+1]).actionPerformed(e);
         }
     }
  }
}

Finally, you need to :

// make up a calculator
HexCalculator calc = new HexCalculator();

// make a calculator GUI
HexCalculatorPane pane = new HexCalculatorPane();

// hook the calculator to the gui
pane.addActionListener(calc)

// display the pane
JFrame f = new JFrame();
f.getContentPane().add(pane);
f.pack();
f.show();


So this makes a separate "thing that knows how to do hex conversions in
rsponse to keystrokes" and "thing that knows how to display an attractive
calculator display", without having to have the components built so as to be
aware of one another. The only compile-time dependencies is a set of public
constants for the key messages. You *could* use a set of well known keys
instead of constants, but this just makes the dependency implicit,
undocumented and harder to find, and meand that your code is studded with
magic numbers.

If you want to go further and make it really tidy, you would make a seperate
"HexCalculatorKey" event class and listener interface, and throw those
around instead of ActionEvent s. The hex calculator GUI object would listen
for action events on the keys (which it knows about because it owns them),
and in response build a HexCalculatorKeyEvent and fire() it to all the
HexCalculatorKeyListener s .

I leave it to you as an exercise <g>.


--------------------------------------------------------------
Repent! Quit your job! Slack off!
http://www.users.bigpond.com/pmurray
ICQ: 26066755
"gav" <astrogav@iprimus.com.au> wrote in message
news:3A25CFBB.DED49113@iprimus.com.au...
> I am creating a simple Binary,hex,decimal converter.
> It's classes are:
> - main Gui setup class
> - ActionLisenter class for when button is pressed to convert numbers
>
> I have it all working, exept that all my GUI components declared in the
> setup class are declared public.
>
> I want (simply for the exercise) to declare these private and add
> methods
> to the setup class, to allow communication for the seperate
> actionlistener.
>
> eg.. at the moment my ActionListener class consists of
>
>    public void actionPerformed(ActionEvent e)
>    {
>    ...
>    ....
>    if(e.getSource()==main.jbutton)  file://main is reference to gui setup
>        file://class that is passed when listener
>        file://is instantiated.
>    ...//does appropriate calculations and passes
>    ...//results back to main Gui using set methods.
>
> If none of this makes sence, all I'm trying to do is use a listener that
> is
> not a nested class. How do I make them communicate properly.  Anyone
> with
> source code to any program doing this would be a help.
>
> Thankyou
> Any responce appreciated.
> gavin.
>
Technical Details
Message-ID: <9i_V5.150448$e5.92887@newsfeeds.bigpond.com>
Path: arc1-ca.pugleaf.net!unknown!not-for-mail
References: <3A25CFBB.DED49113@iprimus.com.au>

Show Full Headers
Complete Article Headers
X-Google-Language: ENGLISH,ASCII-7-bit
X-Google-Thread: 10d6db,d4efa0db7e96a24c
X-Google-Attributes: gid10d6db,public
From: "Paul Murray" <pmurray@nospam.bigpond.com>
Subject: Re: making listener talk to class??
Date: 2000/12/02
Message-ID: <9i_V5.150448$e5.92887@newsfeeds.bigpond.com>
X-Deja-AN: 700177849
References: <3A25CFBB.DED49113@iprimus.com.au>
X-Priority: 3
X-MimeOLE: Produced By Microsoft MimeOLE V5.00.3018.1300
X-Trace: newsfeeds.bigpond.com 975728901 203.54.250.232 (Sat, 02 Dec 2000 14:48:21 EST)
Organization: Telstra BigPond Internet Services (http://www.bigpond.com)
X-MSMail-Priority: Normal
NNTP-Posting-Date: Sat, 02 Dec 2000 14:48:21 EST
Newsgroups: aus.computers.java