Atlantis
Atlantis

Reputation: 592

my JPanel refuses to be focused

jf is a JFrame I'm trying to move a pixel in every 200 milliseconds. I created this method so I ciould pause the software for 200 milliseconds before cntinuing. millis and millisn are static longs.

public static void waitsec() {

        millis =System.currentTimeMillis();
        millisn =System.currentTimeMillis();
            while (millisn<(millis+200)){
                millisn=System.currentTimeMillis();
            }
                }

the following part is the part where I'm trying to make my JPanel (jp) to move slowly 50 pixels when a button is being pressed:

public void actionPerformed(ActionEvent h){
if (h.getSource() == button){
    for (int i = 0; i <50; ++i){
        waitsec();
        out.println ("" + i);//I'm checkinf if the waitsec() is working OK
        x +=1;
        jp.setLocation(x, 0);
        totalGUI.repaint();
        jp.setVisible(true);//setting visible so I could focus on it
        jp.requestFocusInWindow (); //suspicious part
        jp.requestFocus ();  
}}
}

The results of running this program are: The numbers appear in the console one after another with 200 mmillis between them as expected. The JPanel is not moving all the way once the numbers stop appearing (the program is done running). and if I try to minimize and maximize the window it doesn't show up till the program is done running as if the program has no focus at all... why doesn't it focus although I had set it visible and focused it?

Upvotes: 0

Views: 51

Answers (1)

MadProgrammer
MadProgrammer

Reputation: 347332

A number of things...

Firstly, you are blocking the Event Dispatching Thread, preventing it from processing any new events, including repaint events. This will make your application appear as it has hung, because essentially, it has.

Secondly, instead of rolling your waitSec method, you should be taking advantage of the available API functionality, for example, instead of trying to loop until a time period has passed, which while consume CPU cycles, you should use Thread.sleep instead.

Having said that though, you should NEVER sleep within the context of the EDT.

Instead, you should use something like a javax.swing.Timer which can be configured to raise an event on a regular bases. The benefit of this is it raises the event within the context of the EDT, making it safe to update the UI from within (unlike making your own Thread for example)

Take a look at Concurrency in Swing and How to use Swing Timers for more details

Thirdly, JPanel is not focusable by default, so calling requestFocusInWindow is not likely to have any effect

Fourthly, by default, Swing makes use of layout managers, so you may actually be struggling against this as well

Upvotes: 2

Related Questions