Skip to Main Content

Java SE (Java Platform, Standard Edition)

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Current Thread not Owner error when using wait()

843806May 31 2007 — edited Jun 2 2007
i posted this at the end of my last post, but that was a different problem so I assumed it was ok to start a new topic.

If i minimize the error message, the program still works, except that i can't access the JMenu, and the error keeps writing in the window each time a key is pressed (wait() is for a keylistener). I have tried using synchronized(this) with wait(), and with both wait() and notify() or notifyAll(), no combination seems to work. When i used synchronized(this), the JFrame showing my arrow buttons appears blank. (it's a game, and the arrow buttons are used (or arrow keys) to move around the game board)
EDIT:
I moved the try catch to the original class, and added a synchronized (new Levels ()) (name of class keylistener is in)
{
wait();
}
The arrows appeared and the keylistener worked, but the error message still appeared.



Here's the error message, followed by a portion of my code, hopefully someone knows what to do. After waiting, the paint method in my original class is repainted.

java.lang.IllegalMonitorStateException: current thread not owner
at java.lang.Object.wait(Native Method)
at java.lang.Object.wait(Unknown Source)
at Levels.LevelOne(Levels.java:582)
at User_Interface.paint(User_Interface.java:182)
at javax.swing.JFrame.update(Unknown Source)
at sun.awt.RepaintArea.paint(Unknown Source)
at sun.awt.windows.WComponentPeer.handleEvent(Unknown Source)
at java.awt.Component.dispatchEventImpl(Unknown Source)
at java.awt.Container.dispatchEventImpl(Unknown Source)
at java.awt.Window.dispatchEventImpl(Unknown Source)
at java.awt.Component.dispatchEvent(Unknown Source)
at java.awt.EventQueue.dispatchEvent(Unknown Source)
at java.awt.EventDispatchThread.pumpOneEventForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEventsForHierarchy(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.pumpEvents(Unknown Source)
at java.awt.EventDispatchThread.run(Unknown Source)
//***Levels class in which the wait() command is executed, waiting for a key
//to be pressed
up = new JButton (new ImageIcon ("arrow_up.gif"));
        left = new JButton (new ImageIcon ("arrow_left.gif"));
        right = new JButton (new ImageIcon ("arrow_right.gif"));
        down = new JButton (new ImageIcon ("arrow_down.gif"));

        f.getContentPane ().setLayout (new BorderLayout ());
        f.getContentPane ().add (up, BorderLayout.NORTH);
        f.getContentPane ().add (left, BorderLayout.WEST);
        f.getContentPane ().add (right, BorderLayout.EAST);
        f.getContentPane ().add (down, BorderLayout.SOUTH);
        f.pack ();

        f.setLocation (600, 350);
        f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        f.setVisible (true);
        KeyHandler key = new KeyHandler ();
        up.addKeyListener (key);
        left.addKeyListener (key);
        right.addKeyListener (key);
        down.addKeyListener (key);








        up.addActionListener (new ActionListener ()
        {
            public void actionPerformed (ActionEvent e)
            {

                yCord -= 1;
                yLoc += 40;
                label = "LevelOne";
                ok = true;
                f.setVisible (false);
            }
        }
        );
        left.addActionListener (new ActionListener ()
        {
            public void actionPerformed (ActionEvent e)
            {

                xCord -= 1;
                xLoc += 40;
                label = "LevelOne";
                ok = true;
                f.setVisible (false);
            }
        }
        );
        right.addActionListener (new ActionListener ()
        {
            public void actionPerformed (ActionEvent e)
            {

                xCord += 1;
                xLoc -= 40;
                ok = true;
                label = "LevelOne";
                f.setVisible (false);
            }
        }
        );
        down.addActionListener (new ActionListener ()
        {
            public void actionPerformed (ActionEvent e)
            {

                yCord += 1;
                yLoc -= 40;
                label = "LevelOne";
                ok = true;
                f.setVisible (false);
            }
        }
        );

        while (!ok)
        {
            try
            {
                wait ();

            }
            catch (InterruptedException e)
            {
            }
        }
        ok = false;
    }
Message was edited by:
jacob2932

Comments

843806
What are you trying to achieve with the wait() call? What is the purpose? Since this is a GUI app, there's less of a need for wait. If so, look into the SwingWorker class (if you're using Java 6).

Message was edited by:
petes1234
843806
I want the program to wait for the keylistener to be pressed before returning to the paint method where it is repainted (changed the game board to the new position after the key has been pushed) without the wait (), the program flashes like crazy, it works, but its slow and doesn't look nice. I'm fairly new to java, so if there's something else i should do could you please explain it to me?
843806
I want the program to wait for the keylistener to be
pressed before returning to the paint method where it
is repainted (changed the game board to the new
position after the key has been pushed) without the
wait (), the program flashes like crazy, it works,
but its slow and doesn't look nice. I'm fairly new
to java, so if there's something else i should do
could you please explain it to me?
I think that it may be a case of the blind leading the blind here, but something sounds amiss. There has to be a better way of doing what you want to do. It's generally frowned upon to muck with (override) the paint method when using Swing; rather you override paintcomponent (usually). And, again, I'm new to this, but I think that you don't want to step on or delay the app's calling of the paintcomponent method. You shouldn't call it yourself, but rather have swing call it. I think this is done by calling repaint

Can you show a Short, Self Contained, Correct (Compilable), Example of what it is you are after? If you need help on the concept of this, click on the link.

Good luck.
843806
Actually you were told about paint and paintcomponent previously. Are you trying to bite off more than you can chew here?

Here's some info on paintcomponent:
<a href="http://java.sun.com/products/jfc/tsc/articles/painting/index.html"></a>
843806
I've got it my class extending JFrame, which is why I can't used paintComponent. Here's a condensed version of my code: (2 classes needed to run it, original has 4) I've took out basically everything, so that when the program runs it goes right to the problem, and i've left one row of game board in to show you that pressing the arrow keys still works when the error message is up. (boundaries are taken off the row so it will keep going in any direction) One menuitem is still there because i need the menu to work at the same time as well.
//***Compile this program***
//Libraries
//
import java.awt.*;
import java.io.*;
import java.util.*;
import javax.swing.*;
import java.awt.event.*;
import javax.swing.text.*;

public class User_Interface extends JFrame
{

    static Levels l = new Levels ();
    private Container contentPane = getContentPane ();
    private JPanel main, levelOne;
    private String level;
    private boolean repeat = true;
    private CardLayout cc = new CardLayout ();
    private GridBagConstraints gbc = new GridBagConstraints ();
    private JPanel c = new JPanel ();

    public User_Interface ()
    {
        //Generates the User-Interface
        //
        super ("Trapped");

        main = new JPanel ();
        GridBagLayout gbl = new GridBagLayout ();
        main.setLayout (gbl);

        c.setLayout (cc);

        c.add (main, "Main Page");

        contentPane.add (c, BorderLayout.CENTER);

        cc.show (c, "Main Page");


        levelOne = new JPanel ();
        levelOne.setLayout (new GridBagLayout ());
        levelOne.setBackground (Color.black);
        c.add (levelOne, "LevelOne");

        JMenuBar menu = new JMenuBar ();

        JMenu file = new JMenu ("File");


        JMenuItem exit = new JMenuItem ("Exit");
        exit.addActionListener (
                new ActionListener ()
        {
            public void actionPerformed (ActionEvent event)
            {
                System.exit (0);
            }
        }

        );

        file.add (exit);

        menu.add (file);
        setJMenuBar (menu);

        //Sets the size of the container (columns by rows)
        //
        setSize (750, 550);

        //Sets the location of the container
        setLocation (10, 10);

        //Sets the background colour to a dark blue colour
        //
        main.setBackground (Color.black);

        //Makes the container visible
        //
        setVisible (true);
    }


    public void paint (Graphics g)
    {
        super.paint (g);
        g.setColor (Color.white);

        l.label = "LevelOne";





        if (l.label.equals ("LevelOne"))
        {
            l.LevelOne (g, levelOne);

            while (!l.ok)
            {
                try
                {
                    synchronized (new Levels ())
                    {

                        wait ();

                    }

                }
                catch (InterruptedException e)
                {
                }
            }
            l.ok = false;
        }


        if (l.label != "MainMenu")
            repaint ();
    }


    public static void main (String[] args)
    {
        // calls the program
        //
        User_Interface application = new User_Interface ();
        application.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);


    } //End of Main Method

}

//Libraries
//
import java.awt.*;
import java.io.*;
import javax.swing.*;
import java.awt.event.*;


public class Levels extends JFrame
{
    public Color bgcolor;
    public Color darkGray = new Color (60, 60, 60);

    public int xLoc = 140;
    public int yLoc = 140;

    public int counter = -80;
    public int counter2 = 200;
    public String label = "MainMenu";

    //static final String newline = System.getProperty ("line.separator");
    public JButton up, down, left, right;
    public JTextArea ta;
    public Container c;
    public JFrame f = new JFrame ();
    public boolean perform;
    public JPanel one = new JPanel ();
    public boolean found = false;
    public boolean ok = false;
    public Graphics g;
    public GridBagConstraints gbc = new GridBagConstraints ();
    private JFrame frame = new JFrame ();
    {
        //Sets location, size, and visiblity to the frame where the JOptionPane
        //will be placed
        //
        frame.setLocation (600, 600);
        frame.setSize (1, 1);
        frame.setVisible (false);
    }


    JButton button1;
    public int xCord = 2;
    public int yCord = 2;

    public void LevelOne (Graphics g, JPanel one)
    {
        //**********************************************************
        //ROW SIX
        //**********************************************************
        //
        counter = -80;
        counter2 = 200;
        for (int a = 1 ; a <= 7 ; ++a)
        {

            if (xCord < a)
            {
                if (a == 1 || a == 4)
                    g.setColor (darkGray);
                else
                    g.setColor (Color.gray);

                g.fillRect (xLoc + counter, yLoc + 120, 40, 40);
                g.setColor (Color.black);
                g.drawRect (xLoc + counter, yLoc + 120, 40, 40);

               

            }

            if (xCord > a - 1)
            {
                if (a != 6)
                    g.setColor (darkGray);
                else
                    g.setColor (Color.gray);
                g.fillRect (xLoc + counter2, yLoc + 120, 40, 40);
                g.setColor (Color.black);
                g.drawRect (xLoc + counter2, yLoc + 120, 40, 40);
            }

            counter += 40;
            counter2 += 40;

        }


        up = new JButton ("UP");
        left = new JButton ("LEFT");
        right = new JButton (new ImageIcon ("RIGHT"));
        down = new JButton (new ImageIcon ("DOWN"));

        f.getContentPane ().setLayout (new BorderLayout ());
        f.getContentPane ().add (up, BorderLayout.NORTH);
        f.getContentPane ().add (left, BorderLayout.WEST);
        f.getContentPane ().add (right, BorderLayout.EAST);
        f.getContentPane ().add (down, BorderLayout.SOUTH);
        f.pack ();

        f.setLocation (600, 350);
        f.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
        f.setVisible (true);
        KeyHandler key = new KeyHandler ();
        up.addKeyListener (key);
        left.addKeyListener (key);
        right.addKeyListener (key);
        down.addKeyListener (key);

    }


    private class KeyHandler implements KeyListener
    {

        public void keyPressed (KeyEvent ke)
        {
            if (ke.getKeyCode () == 37)
            {
                xCord -= 1;
                xLoc += 40;
                label = "LevelOne";
                f.setVisible (false);
                ok = true;
            }
            else if (ke.getKeyCode () == 38)
            {

                yCord -= 1;
                yLoc += 40;
                label = "LevelOne";
                f.setVisible (false);
                ok = true;

            }
            else if (ke.getKeyCode () == 39)
            {
                xCord += 1;
                xLoc -= 40;
                ok = true;
                label = "LevelOne";
                f.setVisible (false);
            }
            else if (ke.getKeyCode () == 40)
            {

                yCord += 1;
                yLoc -= 40;
                label = "LevelOne";
                f.setVisible (false);
                ok = true;

            }
            else
            {
                label = "LevelOne";
            }

        }

        public void keyReleased (KeyEvent ke)
        {
        }

        public void keyTyped (KeyEvent ke)
        {
        }
    }
   
}
i hope that's concise enough, i took out a few hundred lines of code, at least 3/4 of it.

Message was edited by:
jacob2932
843806
I've got it my class extending JFrame, which is why I
can't used paintComponent.
This statement means you still don't understand this very basic concept. Please study the links provided to you. Understand the concepts before you code. Otherwise you will frustrate yourself (and us) to no end.
843806
I've gone through some of you code, and again I'm no expert, but there is too much wrong for me to even begin to fix. Perhaps someone here more intelligent than I can help you, but to my eye, it looks like you're trying to do differential equations without mastering trigonometry first. My main recommendation is to start from scratch, but only after reading, coding, and understanding the basic Java Swing and graphics tutorials. I'm outta here. Good luck!
843806
I've got my class extending JPanel now, and changed paint to paintComponent and super.paint (g) to super.paintComponent (g), but now my container won't work. I have Container contentPane = new Container (); (was = getContentPane(), doesn't work with JPanel, so i can't figure out what do to, i haven't read anything on converting from JFrame to JPanel yet)
843806
So is the error message popping up because I'm overriding the paint method? I just need to fix this problem and I can handle the rest myself.
843806
So is the error message popping up because I'm
overriding the paint method? I just need to fix this
problem and I can handle the rest myself.
I didn't even see that you were overriding a paint method. You were painting willy-nilly in some method called "LevelOne". AFAIK, this is not right. You need to put your painting in the paintcomponent method (and just the painting, not the program logic) and then have swing repaint your panel by calling repaint or something like that (I'm probably wrong on these specifics). The key is, that you don't tell swing when to paint, you give swing a callback method, the overridden paintcomponent method, that only tells it how to paint.

Again, it's all about learning the basics. I know that I myself am not even close to being able to create a type of program similar to the one that you are trying to create. I hope that in a few months with study I'll have the ability, but I'm not there yet. Pace yourself.
843806
Yeah, I'm only in Grade 12 high school computer science, so you think this is too much for me? Although it may not be technically "right", if that error message goes away I can get the game to work.
843806
Yeah, I'm only in Grade 12 high school computer
science, so you think this is too much for me?
Although it may not be technically "right", if that
error message goes away I can get the game to work.
I've probably said all that I can say given my limitations. Hopefully one of the true Swing gurus, someone who really knows how swing graphics work, will weigh in here and give you what you need to know.
843806
alright, well thanks for your help, sorry for being so stubborn on my whole paint issue. Hopefully someone else knows a simple fix, it that's possible.
843806
A few other problems w/ your code:

class Levels:
1. You have a ton of public class fields. You should have private fields with getters and setters if you need to manipulate them.
2. Shouldn't Levels have a constructor?
3. Level extends a JFrame and yet you never use it as a JFrame. You call other JFrames and use them incorrectly.
4. Method LevelOne uses a Graphics object and calls methods that should probably be called in a paintComponent override method. It also combines painting and program logic into a strange mixture.

class User_Interface
1. You use a GridBagLayout, but I don't see a good reason to use one of the more difficult layout managers, especially when you don't set any of its constraints.
2. Your overriding paint for a JFrame. Again, you need to subclass a JPanel and override it's paintComponent method. You can then add that jpanel to the jframe's content pane.
3. You have program logic within the paint method. Any method if this ilk needs to tell Swing how to Paint and nothing else. It can be called 1, 10, 100, 1000 times, as many times as Swing wants or needs to call it.
4. You're trying to put a wait() call into a paint routine? one word -- don't
5. You're calling repaint() from within a paint routine? again -- don't

This will take much much more than just patching a few errors. Trust me, you have far to go. Again, stop doing any more coding until you have mastered the tutorials. You are way off the mark.
843806
thanks for your input, ill go back and look at everything later on when i have some more time, i realize i have a lot to do, i guess i just dont want to, but i will.
also, class Levels extends Objects, its superclass i made, but i took it out for simplicity. so how do i paint things when i need them if i cant call them from a paint method?

Message was edited by:
jacob2932
843806
so how do i
paint things when i need them if i cant call them
from a paint method?
C'mon now! Are you dense??? You should know by now that this can't be answered in a sentence or two. This is getting very frustrating for me to say again, but for one last time I will: You need to read, study, and understand the tutorials. Period. End of story.

Start here. And you shouldn't come back until you understand this stuff.
843806
Problem fixed. Read up on multithreading, rewrote my program, worked like a charm. Thanks for your help, my program no longer has any logic in the the paint method, doesn't use a gridbaglayout, doesn't call repaint inside the paint method, doesn't even contain wait anymore, no more painting a JFrame, all fields needed to be private are private...basically everything you said was wrong has been fixed. Thanks alot for your help, everything is running smoothly now.
843806
Problem fixed. Read up on multithreading, ....
.........
.........
.... everything is running smoothly now.
Glad to hear this. Sorry for the venting.
1 - 18
Locked Post
New comments cannot be posted to this locked post.

Post Details

Locked on Jun 30 2007
Added on May 31 2007
18 comments
338 views