Skip to main content

Locking a UI does not work sometimes when using JXLayer.

6 replies [Last post]
navinkjha
Offline
Joined: 2004-12-28

Locking a UI does not work sometimes when using JXLayer. I have provided the test case below.

package testdisable;

import org.jdesktop.jxlayer.plaf.ext.LockableUI;
import org.jdesktop.jxlayer.JXLayer;

import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class TestDisabler {

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
final JFrame f = new JFrame();
JPanel panel = new JPanel(new GridLayout(1, 1));
JButton button = new JButton("test");
panel.add(button);
final JButton lockUnlockButton = new JButton("lock");
final LockableUI ui = new LockableUI() {
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (isLocked()) {
g.setColor(new Color(128, 128, 128, 128));
g.fillRect(0, 0, c.getWidth(), c.getHeight());
}
}
};
JXLayer layer
= new JXLayer(button, ui);
f.add(layer);
final Timer timer = new Timer(5000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
ui.setLocked(true);
lockUnlockButton.setText("Locked Now!");
}
});

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(lockUnlockButton, BorderLayout.SOUTH);

f.pack();

// comment this and uncomment the add action listener and it works
timer.start();
/*
lockUnlockButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
timer.start();
}
});*/
f.setVisible(true);
}
});
}
}

Reply viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.
pietblok
Offline
Joined: 2003-07-17

Hi navinkjha,

I tested your example code but I see nothing wrong with it. In both cases the test button becomes locked after 5 seconds.

Case one: the timer is started in the initial code. 5 seconds after program start, the test button is locked.

Case two: the timer is started when the lock button is pressed. 5 seconds after press, the test button is locked.

Am I missing something?

Piet

navinkjha
Offline
Joined: 2004-12-28

Sorry I should have given a little more detail. Once you start the application you have to switch to another application quickly. Also make sure the other application does not overlap with this one. Now you will find out unless you click on the window it will not appear locked.

pietblok
Offline
Joined: 2003-07-17

Ah, now I see what you mean. When some other application has focus, I can see the "lock" button changing its text to "Locked Now!", but the test button is not greyed out. As soon as the mouse is over your the "test" button it does grey out.

And indeed, the two cases behave differently for a similar scenario. Sorry, I have no clue.

Piet

pietblok
Offline
Joined: 2003-07-17

Hi navinkjha,

Did some more tests to see if can find the cause, but I'm only getting very bizarre results.

I found three other ways that each independently seem to resolve the problem. I embedded that in your code, marked with "PB".

1) Just before invoking [b]ui.setLocked(true)[/b] invoke [b]layer.setUI(ui)[/b] (layer should be declared final). Yes quite bizarre, because the ui has been set previously by the layer's constructor.

2) Just after invoking [b]ui.setLocked(true)[/b] invoke[b] f.invalidate(), f.validate()[/b] and [b]f.repaint()[/b]

3) Create a second frame and have it visible. It doesn't matter when it looses focus to another application. This one doesn't make any sense at all (as far as I'm concerned), but for some mysterious reason it seems to work.

Maybe Alex can shed some light on this mystery?

[code]
import org.jdesktop.jxlayer.plaf.ext.LockableUI;
import org.jdesktop.jxlayer.JXLayer;

import java.awt.*;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.*;

public class TestDisabler {

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@SuppressWarnings("unchecked")
public void run() {
final JFrame f = new JFrame();
JPanel panel = new JPanel(new GridLayout(1, 1));
JButton button = new JButton("test");
panel.add(button);
final JButton lockUnlockButton = new JButton("lock");
final LockableUI ui = new LockableUI() {
@Override
public void paint(Graphics g, JComponent c) {
super.paint(g, c);
if (isLocked()) {
g.setColor(new Color(128, 128, 128, 128));
g.fillRect(0, 0, c.getWidth(), c.getHeight());
}
}
};
final JXLayer layer = new JXLayer(button, ui); // PB made final
f.add(layer);
final Timer timer = new Timer(5000, new ActionListener() {
public void actionPerformed(ActionEvent e) {
/*
* PB This "solves" the problem
*/
// layer.setUI(ui);
ui.setLocked(true);
lockUnlockButton.setText("Locked Now!");
/*
* PB This also "solves" the problem
*/
// f.invalidate();
// f.validate();
// f.repaint();
}
});

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.add(lockUnlockButton, BorderLayout.SOUTH);

f.pack();

// comment this and uncomment the add action listener and it
// works
timer.start();

// lockUnlockButton.addActionListener(new ActionListener() {
// public void actionPerformed(ActionEvent e) {
// timer.start();
// }
// });

f.setVisible(true);

/*
* PB This also "solves" the problem, even if the focus frame
* looses focus
*/
JFrame focusFrame = new JFrame("Focus frame");
focusFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
focusFrame.add(new JLabel(
"Please set focus on any other application"));
focusFrame.pack();
focusFrame.setLocationRelativeTo(null);
focusFrame.setVisible(true);
}
});
}
}\[/code]

Piet

alexfromsun
Offline
Joined: 2005-09-05

Hello Navin
Hello Piet

Thanks to Navin I found very subtle bug in the LockableUI,
actually there is only one way to update it - call setDirty(true)
and it is called when the layer gains the focus

when an application is not focused,
the layer can't make itself focused and that caused the problem,
I added additional check to handle this situation

The updated jxlayer.jar is available on project's site
version 3.0.3 will soon be published on the Maven rep

Thanks
alexp

navinkjha
Offline
Joined: 2004-12-28

Alex,
Thank you so much.
Piet,
Thanks you too.
-Navin