Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

Nested and External Class Question 1

Status
Not open for further replies.

jisoo22

Programmer
Apr 30, 2001
277
US
Hello all =)

Well I'm continuing my trek through the wonderful world of java and have run into another question. Currently I'm learning the concepts between the use of nested and external classes. Basically what I have right now is a working java file (it's an applet) that when run, will show a little happy face bouncing around the applet. There is a method that listens for a mouse click on the applet to stop the face from running around and again to start it back up. What I'm trying to do is take that nested method (called ReboundMouseListener) and turn it into an external class to be called upon by the original file. I think I almost have it figured out, but the driver file seems to run into a couple errors while compiling (one of them having to do with trying to import the external class). Can anyone take a look and tell me what exactly I'm doing wrong? Links to the code follows below.

Thanks!
Jisoo22

Original program:
Happy Face GIF:
New program:
External Class:
 
Don't know if this is what you mean but:

In the code that you have you are trying to make a direct call to the mouseClicked method with no arguments. This doesn't match the pattern of the method that takes a MouseEvent instance. You can pass (Null) for test purposes.

Also because you are trying to use the timer in the external class you need to pass this in the constructor. What you would need to do is to add something like :

..
public ReboundMouseListener(Timer timer) {
super();
this.timer = timer;
}
..

to the external class. This will mean that you can use the timer in the external class (p.s. need to add those moveX etc to this class too). You then change the order and parameters of the following lines in the main class to something like :

..
timer = new Timer (DELAY, new ReboundActionListener());
super.addMouseListener (new ReboundMouseListener(timer));
..

This should pass the created timer to the external class.

Hope that makes sence.

Kev

[afro2]
 
jisoo22,

Why do you need <<ReboundMouseListener>> to be a public class? Is it to be used by other applications?

If so it needs to be in a package. If it is in a package then other classes can import it.

import com.jisoo22.ReboundMouseListener;

If it is only used in <<ReboundGUI2>> then it does not need to be in a seperate file and does not need to be public.

Hope this helps
-pete
 
Hi Quinnie,

I appreciate the help, pretty much the point of this exercise is to learn the concepts of implementing external classes as oppose to nesting them inside the program themselves. Really all I'm trying to do is to make the program work exactly the same with an externally called class and method as with nested ones. I tried doing what you suggested and I get less errors but when I compile the ReboundMouseListener file, it gives me 2 errors that are the following:

Code:
D:\USER\Lab Documents\ReboundMouseListener.java:8: '{' expected
public class ReboundMouseListener (Timer timer) implements MouseListener
                                  ^
D:\USER\Lab Documents\ReboundMouseListener.java:38: '}' expected
} //ReboundMouseListener (inner class)
                                      ^

It looks like a syntax error to me, but I can't see any. Suggestions? (Updated code has been uploaded to my website URLs).

Also to palbano, thanks for the input about importing as a package, but I'm confused on the syntax for importing it as such. In the statement &quot;import com.jisoo22.ReboundMouseListener;&quot; does jisoo22 correspond to a folder name? I realize that the class ReboundMouseListener does not need to be in a separate file, but that's what the lesson book asks for. Beats me hehe. Question, if the ReboundMouseListener is only used externally by the ReboundGUI file, can it be a private class? Or does that shut it off from any outside access attempts?

Thanks for all the help,
Jisoo22
 
>> does jisoo22 correspond to a folder name?

The whole path does com.jisoo22.MyClass would look like this:

<<currentdir>>\com\jisoo22\MyClass.class

but you should not have to do that, just take out the import statement and if both .class files are in the same folder it should work.

-pete



 
Hi jisoo22,

The first error you are getting is because I wasn't clear about defining a constructor. A constructor is not defined in the class definition (first line)...but is another method so your code will be something like this :

..
import javax.swing.*;

public class ReboundMouseListener implements MouseListener
{
private Timer timer;
..

public ReboundMouseListener(Timer timer) {
super();
this.timer = timer;
}

..
public void mouseClicked (MouseEvent event){

If you repost what you have I will update and send back if you like.

Kev

[afro2]
 
Hello again,

Thanks to both of you for clarifying some of these things, it is much appreciated. I have one more question to ask, it deals with the same subject but a different way of doing it. After staring at the code for a bit, do you think it is possible for me to do the following:

1. Create two new methods in the ReboundGUI2 program, one that starts movement of the happy face, and one that stops it (called startTimer, stopTimer respectively)

2. Create an instance of the ReboundGUI2 class in the ReboundMouseListener class and call those new methods locally.

It seems to be a safer way of doing things in terms of the Timer method, which would have to be public if I did it the other way. If this is feasible, can either of you give me an idea of the proper syntax? I would imagine that it would be something like this:

Code:
public class ReboundMouseListener () implements MouseListener
{
   ReboundGUI2 _reb;

   public void storeRebound
   {
      ReboundGUI2 reb = _reb;
   }

   public void mouseClicked (MouseEvent event)
   {
      if (reb.init.isRunning(timer))
         reb.stopTimer();
      else
         reb.startTimer();
   }
}

I think I'm creating a global variable this way? If you need to see any additional code, you can check out the newly updated ReboundMouseListener file url:

and the ReboundGUI2 program

Thanks!
Jisoo22
 
I would not use a timer I would use a thread.

&quot;But, that's just my opinion... I could be wrong&quot;.
-pete
 
Someone told me about the possibility of using threads but unfortunately I'm not allowed to make significant changes like that to the code. =(

 
Hi Jisoo22,

If you do want to this sort of thing I would avoid making the GUI class a member of the Listner class for logical reasons. The Listner is used inside the GUI rather than the other way around so wouldn't make sence to create the GUI inside the Listner. You could pass a reference to the GUI which would be something like this :

public class ReboundMouseListener () implements MouseListener {
...
private ReboundGUI2 reb;

public void storeRebound(ReboundGUI2 reb) {
this.reb = reb;
}

public void mouseClicked (MouseEvent event) {
if (reb.isRunning())
reb.stopTimer();
else
reb.startTimer();
}
..

then in GUI2

...
private boolean timerRunning=false;
...

public void init() {
super.setContentPane(panel);
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ReboundMouseListener listner = new ReboundMouseListener();
listner.storeRebound(this);
super.addMouseListener (listner);

timer = new Timer (DELAY, new ReboundActionListener());
timer.start();
timerRunning = true;

x = 0;
y = 40;
moveX = 3;
moveY = 3;

image = new ImageIcon(&quot;happyface.gif&quot;);

super.setBackground (Color.black);
super.setSize (GUI_WIDTH, GUI_HEIGHT);
}

public boolean isRunning() {
return timerRunning;
}

public void startTimer() {
timer.start();
timerRunning = true;
}
public void stopTimer(){
timer.stop();
timerRunning = false;
}

...

Hope this helps.

Keep going mate... you'll get there.

Kev
[afro2]
 
Hi Quinnie,

Thank you for all your help, I'm learning a lot on how to implement these concepts while looking at examples like this! There is a single error message though, exactly the same as the previous error message. You said it was some sort of error related to improper constructor definition so I think this must be the same. The error looks like this:

Code:
C:\WINDOWS\Desktop\ReboundMouselistener.java:8: '{' expected 
public class ReboundMouseListener () implements MouseListener

C:\WINDOWS\Desktop\ReboundMouseListener.java:37: '}' expected
} //ReboundMouseListener (inner class)
 ^

I tried to compare the correction you had given to me before but I don't really see any differences unless it's an error that has to do with the GUI2 program (but I don't think so). Should the statement in line 10 be &quot;private ReboundGUI2 _reb = new ReboundGUI2;&quot;?

Thanks,
Jisoo22
 
Just to let you know, I tried renaming the &quot;storeRebound&quot; method to &quot;ReboundMouseListener&quot; hoping to resolve the constructor issue but still got the same error. Programming can be very tedious sometimes.

Thanks,
Jisoo22
&quot;7 hours straight and loving it&quot;
 
It is now posted both at the URL and here:

Code:
public class ReboundMouseListener () implements MouseListener
{
	private ReboundGUI2 _reb = new ReboundGUI2;

	public void ReboundMouseListener ( ReboundGUI2 _reb )
	{
		this.reb = _reb;
	}

   //--------------------------------------------------------------
   //  Stops or starts the timer (and therefore the animation)
   //  when the mouse button is clicked.
   //--------------------------------------------------------------
   public void mouseClicked (MouseEvent event)
   {
      if (reb.isRunning())  //note that var timer is not local to
         reb.stopTimer();        //this object! Why is access legal?
      else
         reb.startTimer();
   }

   //--------------------------------------------------------------
   //  Provide empty definitions for unused event methods.
   //--------------------------------------------------------------
   public void mouseEntered (MouseEvent event) {}
   public void mouseExited (MouseEvent event) {}
   public void mousePressed (MouseEvent event) {}
   public void mouseReleased (MouseEvent event) {}

} //ReboundMouseListener (inner class)

[/code}

Thanks!
 
Before the code...just give a couple of pointers (hope it helps).

Although constructers obviously return something they sound not have anything between public and functionName. This is a special case that only applies to constructors.

If you define a property to have a &quot;_&quot; at the start...carry this naming through the rest of the file. This is unlike some languages but necessary in Java.

Best to put classes into packages to group them (similar to directories). It means that you can organise them and keep different bits of code together. (see first line of each file).

If you want to use a external class you need to import it (see the last import line in each list).

The rest looks great...Your going great guns. Here's one that compiles for you, just cut and past over your files:

ReboundMouseListener.java
<START CUT HERE>

package com.jasoo2.rebound;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.jasoo2.rebound.ReboundGUI2;

//*****************************************************************
// Represents the mouse listener for the gui.
//*****************************************************************


public class ReboundMouseListener implements MouseListener
{
private ReboundGUI2 _reb = new ReboundGUI2();

public ReboundMouseListener ( ReboundGUI2 _reb )
{
this._reb = _reb;
}

//--------------------------------------------------------------
// Stops or starts the timer (and therefore the animation)
// when the mouse button is clicked.
//--------------------------------------------------------------
public void mouseClicked (MouseEvent event)
{
if (_reb.isRunning()) //note that var timer is not local to
_reb.stopTimer(); //this object! Why is access legal?
else
_reb.startTimer();
}

//--------------------------------------------------------------
// Provide empty definitions for unused event methods.
//--------------------------------------------------------------
public void mouseEntered (MouseEvent event) {}
public void mouseExited (MouseEvent event) {}
public void mousePressed (MouseEvent event) {}
public void mouseReleased (MouseEvent event) {}

} //ReboundMouseListener (inner class)

<STOP CUT HERE>


ReboundGUI2
<START CUT HERE>

package com.jasoo2.rebound;

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import com.jasoo2.rebound.ReboundMouseListener;

public class ReboundGUI2 extends JFrame
{

private final int GUI_WIDTH = 300;
private final int GUI_HEIGHT = 200;

private final int IMAGE_SIZE = 35;
private final int DELAY = 20;

private Timer timer;
private boolean timerRunning = false;
private ImageIcon image;
private int x, y, moveX, moveY;

private JPanel panel = new JPanel();

public static void main(String[] args) {
ReboundGUI2 r = new ReboundGUI2();
r.init();
r.setVisible(true);

} //main



//-----------------------------------------------------------------
// Sets up the gui, including the timer for the animation.
//-----------------------------------------------------------------
public void init()
{
super.setContentPane(panel);
super.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
ReboundMouseListener a = new ReboundMouseListener(this);
super.addMouseListener (a);

timer = new Timer (DELAY, new ReboundActionListener());
timer.start();
timerRunning = true;

x = 0;
y = 40;
moveX = 3;
moveY = 3;

image = new ImageIcon(&quot;happyface.gif&quot;);

super.setBackground (Color.black);
super.setSize (GUI_WIDTH, GUI_HEIGHT);
}

public boolean isRunning()
{
return timerRunning;
}

public void startTimer()
{
timer.start();
timerRunning = true;
}
public void stopTimer()
{
timer.stop();
timerRunning = false;
}

//-----------------------------------------------------------------
// Draws the image in the current location.
//-----------------------------------------------------------------
public void paint (Graphics page)
{
page.clearRect(0, 0, GUI_WIDTH, GUI_HEIGHT);
page.drawImage (image.getImage(), x, y, this);
}

//*****************************************************************
// Represents the action listener for the timer.
//*****************************************************************
private class ReboundActionListener implements ActionListener
{
//--------------------------------------------------------------
// Updates the position of the image and possibly the direction
// of movement whenever the timer fires an action event.
//--------------------------------------------------------------
public void actionPerformed (ActionEvent event)
{
x += moveX;
y += moveY;

if (x <= 0 || x >= GUI_WIDTH-IMAGE_SIZE)
moveX = moveX * -1;

if (y <= 22 || y >= GUI_HEIGHT-IMAGE_SIZE)
moveY = moveY * -1;

repaint();

} //action Performed

} //ReboundActionListener (inner class)

} //ReboundGUI



<STOP CUT HERE>

Hope that helped.

Kev
[afro2]

 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top