aspose file tools*
The moose likes Beginning Java and the fly likes Can't simultaneously run two threads? Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login
JavaRanch » Java Forums » Java » Beginning Java
Bookmark "Can Watch "Can New topic
Author

Can't simultaneously run two threads?

Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

Hey Guys,

I am creating a program which creates two balls (each with their own runnables which control them). This is the important code from the file:

The ControlBallRunnable is here:



To explain this: when the runnable is created, it creates a timer which changes the colour of the ball (using method ball.animate() ) every 1000ms i.e. every second.

Now my problem is this code partially works, it successfully creates one ball (the first time addBall() is called).
It refuses to create more than one ball.

This is the output from the command line:


Now both instances of the thread are being created and finishing, but only one instance of the Ball can be seen.

Now, ive researched this problem for the last couple of days and cant seem to find a solution. Please help me. If you need any clarifications, extra code etc, i will provide it.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

What type of component is BallFrame? Is it actually a Frame or JFrame? If so, don't J/Frames only allow one content (the ContentPane)? Shouldn't you be adding the balls to J/Panel and use that Panel as the Frame's content pane?

And if that is not the problem, then I think you will need to post a runnable solution which shows the problem a SSCCE


Steve
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

BallsFrame is a JFrame (essentially a helper frame) which i feed into a viewer called BallsViewer like this:



I swear you could add components directly to the frame? Because thats what i have done with this BallComponent. One of them does work. It displays fine, its just the other one doesnt show.

Both threads start execution, i have tested that using a println before and after the thread.start() method.

Still dont know why it doesnt show?
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

You can add components to the JFrame - it goes to the default content pane, whose layout is a BorderLayout. A BorderLayout can only have one content per area (with the default area being the center). So when you are adding two balls to the frame you are adding one, then adding the second into the same area, removing the first.

You should use a JPanel as an intermediate. Add the JPanel to the content pane, then add your balls to the JPanel.
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

And it has nothing to do with threads. Tracing down threads and what not is a red-herring. If you don't believe me try adding two buttons to a JFrame the same way you add those balls.
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

Ok i will definitely try it out now. Just before i do, if the second component removes the first surely the position should change since the second has completely different coordinates to the first instance ?
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Shady Sback wrote:Ok i will definitely try it out now. Just before i do, if the second component removes the first surely the position should change since the second has completely different coordinates to the first instance ?

No, LayoutManagers (some anyway) completely ignore the positions you give components - it is the LayoutManager's job to position and layout components, not yours. So when you want to control a component's position you should remove the LayoutManager or use one that allows absolute positioning.
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

OHHHH!!! I get it now! Just had my eureka moment

Thank you so much for helping me.
If i insert a new JPanel and change the layout to, lets suppose, a FlowLayout, will it allow me to do absolute positioning?
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

I don't remember... I think the default layout for a JPanel is FlowLayout. You will definitely see two balls, but they will either be next to each other (horizontal flow) or one on top of the other (vertical flow). I think the best way to get absolute positioning is to pass null as the LayoutManager. But it has been a while since I played with GUI stuff.
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

Steve Luke wrote:I don't remember... I think the default layout for a JPanel is FlowLayout. You will definitely see two balls, but they will either be next to each other (horizontal flow) or one on top of the other (vertical flow). I think the best way to get absolute positioning is to pass null as the LayoutManager. But it has been a while since I played with GUI stuff.


This will keep me busy for the next half hour, i will post here if i encounter any problems. Thanks a bunch!
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19784
    
  20

One word of advice - drop the Thread and Runnable. All it does is start a Swing timer which already does what you want.


SCJP 1.4 - SCJP 6 - SCWCD 5 - OCEEJBD 6
How To Ask Questions How To Answer Questions
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2404
    
  50
I think the best way to get absolute positioning is to pass null as the LayoutManager.

Yes, if you call setLayout(null) it removes any existing LayoutManager and it's then entirely up to you to control the size and location of all child components. Remember you will no longer have auto-handling of scenarios such as the component's size changing so you may want/need to add a listener to handle cases such as this.
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

Tony Docherty wrote:
I think the best way to get absolute positioning is to pass null as the LayoutManager.

Yes, if you call setLayout(null) it removes any existing LayoutManager and it's then entirely up to you to control the size and location of all child components. Remember you will no longer have auto-handling of scenarios such as the component's size changing so you may want/need to add a listener to handle cases such as this.


I tried to use setLayout(null) but no components showed on the frame despite passing parameters x,y using addBall(x, y);
Or do i need to set explicitly set the coordinates for the component while adding it to the panel, something along the lines of



?
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

Rob Spoor wrote:One word of advice - drop the Thread and Runnable. All it does is start a Swing timer which already does what you want.


Appreciate it but this is simply a learning exercise for me as my actual program needs to make hundreds of bouncing balls each controlled by their own runnables. This is just a simpler version of it !!
Steve Luke
Bartender

Joined: Jan 28, 2003
Posts: 4181
    
  21

Did you define the size of the component as well (another function normally influenced by the layout manager)?
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

Steve Luke wrote:Did you define the size of the component as well (another function normally influenced by the layout manager)?

i used a setBounds(x,y, FRAME_WIDTH, FRAME_HEIGHT) if thats what you meant? And that didnt solve it either
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2404
    
  50
I tried to use setLayout(null) but no components showed on the frame

You shouldn't be setting a null layout on the frame, set it on the panel that you are adding your Ball components.

My comments on setLayout() were in response to Steve Luke's post and I hadn't read the rest of the thread.
I've just had a quick look and I'm not sure what your Ball class is. I assume it extends JPanel or JComponent, is this correct?

You need to call setLocation() and setSize() on the Ball object to set it's location and size within the component that it has been added to. Then you override paintComponent() to draw your shape. Don't try and draw it at whatever the x, y location is as your component is already at that position so within your Ball object you draw at 0, 0.
Rob Spoor
Sheriff

Joined: Oct 27, 2005
Posts: 19784
    
  20

Stevie Shorey wrote:
Rob Spoor wrote:One word of advice - drop the Thread and Runnable. All it does is start a Swing timer which already does what you want.


Appreciate it but this is simply a learning exercise for me as my actual program needs to make hundreds of bouncing balls each controlled by their own runnables. This is just a simpler version of it !!

Even with thousands of balls, you shouldn't use threads in Swing. Read Concurrency in Swing for more details.
Stevie Shorey
Ranch Hand

Joined: Dec 10, 2012
Posts: 45

By Overriding the paintcomponent do you simply mean i should call the repaint() method ?
Tony Docherty
Bartender

Joined: Aug 07, 2007
Posts: 2404
    
  50
By Overriding the paintcomponent do you simply mean i should call the repaint() method ?

No, calling repaint() causes a series of actions to occur, one of which is to call a component's paintComponent() method whose task it is to paint the visible component. In, for instance, a JButton the paintComponent() method paints a rectangular button shape at the required size and draws the text on the button. So you have to provide an implementation of paintComponent() in your Ball class to draw your ball.

I suggest you check out the following Java tutorials

http://docs.oracle.com/javase/tutorial/uiswing/components/jcomponent.html
http://docs.oracle.com/javase/tutorial/uiswing/painting/index.html
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: Can't simultaneously run two threads?