all.
i want to minimize my jframe with setExtendedState(JFrame.ICONIFIED), in most case, it works properly, but when it does not work when i lock my os(windows XP) screen with WIN+L.My wimple code are as follows:
import javax.swing.JDialog;
import javax.swing.JFrame;
public class FrameTest extends JFrame {
public static FrameTest ft = new FrameTest();
public static void main(String[] args)
{
FrameTest.ft.setVisible(true);
FrameTest.ft.setLocation(300, 300);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
JDialog dlg = new JDialog( ft, "xxx", true );
ft.setExtendedState(JFrame.ICONIFIED);
dlg.setVisible(true);//if not have this line, it works also in screen lock case
}
}
Any help will be appreciated.
It could me that you are manipulating Swing components from the main thread instead of the Event Dispatch Thread. Try wrapping the contents of main in:
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Rennable() {
#Override
void run() {
FrameTest.ft.setVisible(true);
FrameTest.ft.setLocation(300, 300);
}
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
SwingUtilities.invokeLater(new Rennable() {
#Override
void run() {
JDialog dlg = new JDialog( ft, "xxx", true );
ft.setExtendedState(JFrame.ICONIFIED);
dlg.setVisible(true);case
}
}
If that doesn't help, try splitting the second invokeLater block into:
SwingUtilities.invokeLater(new Rennable() {
#Override
void run() {
ft.setExtendedState(JFrame.ICONIFIED);
}
SwingUtilities.invokeLater(new Rennable() {
#Override
void run() {
JDialog dlg = new JDialog( ft, "xxx", true );
dlg.setVisible(true);case
}
That gives Swing a chance to respond to the iconification before handing off control to the dialog.
Related
When I call the JFrame from another class to test, the JFrame works, but when I insert it into my Selenium test, the JFrame and the browser open so quickly that there's no time to input anything and the test appears like passed.
Sample of the elements that I mention:
#Test
public void Run() throws InterruptedException{
Keys.loginFrame(); //This method is static in another class named 'Keys'
...
}
Is there any way to say to Selenium the following?:
Execute first ONLY Keys.loginFrame();, then wait till the JFrame is closed. Finally execute the rest of the test code.
Thank you for your answers!
remake your loginFrame() method to return JFrame object
add this method:
public static void startFrameThread(JFrame frame) {
Thread thread = new Thread() {
public void run() {
while (frame.isVisible()) {
try {
Thread.sleep(1000);
}
catch (InterruptedException e) {
}
}
}
};
thread.start();
frame.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent arg0) {
frame.setVisible(false);
}
});
try {
thread.join();
} catch (InterruptedException e) {
}
}
apply new usage:
JFrame loginFrame = Keys.loginFrame();
loginFrame.setVisible(true); // if not setting visible in loginFrame() method
startFrameThread(loginFrame);
I have a process that shows confirm messages from JOptionPane. This process is called from SwingUtilities.invokeLater(runnable) that is inside an Actionlistener for a JMenuItem. The code for the runnable is this:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
MyClass c=new MyClass(file)
try {
c.start();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
this.finalize();
} catch (Throwable e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
});
In MyClass there's this method:
private boolean userInput(){
String message="yes or no?";
JCheckBox checkbox = new JCheckBox("Do this for all.");
Object[] params={message,checkbox};
int n=JOptionPane.showConfirmDialog(null,params,"message",JOptionPane.YES_NO_OPTION);
boolean answer=(n==JOptionPane.YES_OPTION)?true:false;
if(checkbox.isSelected()){
nextQ=false;
nextA=answer;
}
return answer;
}
which is called many times. When a JOptionPane message is displayed, I click its button(yes/no), but the message won't disappear until the next message is displayed. What might be the problem? Does this has to do with the method invokeLater ?
I found the way to solve this. I had to create a new Thread inside the SwingUrtilities.invokeLater method. This is the new code:
SwingUtilities.invokeLater(new Runnable(){
public void run(){
Thread t=new Thread(new Runnable(){
MyClass c=new MyClass(file)
public void run(){
c.start();
}
});
t.start();
}
});
[enter link description here][1]I tried an application to display a GIF file. But my application is not showing any error instead GIf ( splash screen ) is not visible.
I have given a code in manifest file :
Manifest-Version: 1.0
X-COMMENT: Main-Class will be added automatically by build SplashScreen-Image:C:\Users\Admin\Documents\NetBeansProjects\splash\src\splash\try5.gif
-splash:src\splash\try5.gif
the above code in VM options.
In my main class i used this code
public static void main(String[] args) {
sleepThread();
java.awt.EventQueue.invokeLater(new Runnable(){
#Override
public void run()
{
new welcome().setVisible(true);
}
});
}
private static void sleepThread() {
try
{
Thread.sleep(5000);
}
catch (InterruptedException ex)
{
// Do something, if there is a exception
System.out.println(ex.toString());
}
}
// TODO code application logic here
}
But when i tried running my application it doesnot display my Splashscreen. Is there any specification for the size of the Splashscreen GIf because my file is 2.63 MB and its dimensions are 640 * 360. Kindly help me.
EDIT : I USED THE SAME CODING BUT TRIED A JPG IMAGE AS A SPLASH SCREEN IT WORKED WELL. THEN AGAIN I CHANGED IT TO .GIF FILE THE SPLASH SCREEN DID NOT APPEAR AND ALSO AGAIN I CHANGED MY FILE WITH JPG FILE THIS TIME THIS JPG FILE ALSO DID NOT WORK.
EDIT : [1]: http://giphy.com/gifs/thank-you-cute-a3IWyhkEC0p32
Here is the link i have given for a sample gif file. But please note that my gif file size is 2.53 MB.
EDIT : Now this Gif file works perfectly. But after dis splash screen stops my Jframe should open. how do i map it so dat it if i run my program it First displays my Splashscreen den my Frame.
Oops!
I didn't notice. It is better to use SwingUtilities for forms and swing objects to work with. // Change the sleep to 5000, it is 2000 now.
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class test {
public static void main(String[] args) {
final JDialog frame = new JDialog(new JFrame());
frame.setSize(320, 240);
frame.setContentPane(new JLabel(new ImageIcon("H:\\walk.gif")));
frame.setUndecorated(true);
frame.setResizable(false);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JDialog.DO_NOTHING_ON_CLOSE);
new Thread(new Runnable() {
#Override
public void run() {
sleepThread();
CloseDialog(frame);
System.exit(0);
}
}).start();
ShowDialog(frame);
}
private static void sleepThread() {
try {
Thread.sleep(2000);
} catch (InterruptedException ex) {
// Do something, if there is a exception
System.out.println(ex.toString());
}
}
private static void ShowDialog(final JDialog dialog) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
dialog.setVisible(true);
}
});
}
private static void CloseDialog(final JDialog dialog) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
dialog.setVisible(false);
}
});
}
}
swap commands, and you will be fine. Show the window, then sleep. That is how splash screen work, I think :)
public static void main(String[] args) {
new welcome().setVisible(true);
java.awt.EventQueue.invokeLater(new Runnable(){
#Override
public void run()
{
sleepThread();
}
});
}
private static void sleepThread() {
try
{
Thread.sleep(5000);
}
catch (InterruptedException ex)
{
// Do something, if there is a exception
System.out.println(ex.toString());
}
}
// TODO code application logic here
}
I'm trying to figure out why the text field isn't updating. I'm aware that using SwingWorker will probably fix this problem, but I can't understand why it doesn't work in the first place.
public class waitExample {
private JFrame frame;
private JTextField txtLeadingText;
private String one = "update string 1";
private String two = "update string 2";
private String three = "update string 3";
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
waitExample window = new waitExample();
window.frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
public waitExample() {
initialize();
}
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
txtLeadingText = new JTextField();
txtLeadingText.setHorizontalAlignment(SwingConstants.CENTER);
txtLeadingText.setText("leading text");
frame.getContentPane().add(txtLeadingText, BorderLayout.SOUTH);
txtLeadingText.setColumns(10);
JButton btnClickMeTo = new JButton("CLICK ME TO UPDATE TEXT");
btnClickMeTo.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent arg0) {
try {
updateOne();
Thread.sleep(1000);
updateTwo();
Thread.sleep(1000);
updateThree();
Thread.sleep(1000);
updateLast();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
frame.getContentPane().add(btnClickMeTo, BorderLayout.CENTER);
}
private void updateOne() {
txtLeadingText.setText(one);
}
private void updateTwo() {
txtLeadingText.setText(two);
}
private void updateThree() {
txtLeadingText.setText(three);
}
private void updateLast() {
txtLeadingText.setText("default text");
}
}
From what I understand, the default Thread will prevent any GUI updates. That shouldn't matter because I am setting the textField BEFORE the Thread.sleep.
Why doesn't the text field update? Shouldn't the text be set, then the Thread wait?
EDIT: As per the answers, the above code has been updated.
You are invoking Thread.sleep(1000); on EDT. This means that when your method will end - only then the repaint() will fire (at some point in time later).
Until then your GUI is freezed.
Consider that this is going on one thread (so processing is straightforward):
txtLeadingText.setText(one);
Thread.sleep(1000);
txtLeadingText.setText(two);
Thread.sleep(1000);
txtLeadingText.setText(three);
Thread.sleep(1000);
...
<returning from updateText()>
<processing other events on button click>
...
// some time later
<Swing finds out that GUI needs repaint: calls rapaint()>
This is what you should do (I didn't compile or test it):
public class MyRunnable implements Runnable {
private List<String> strsToSet;
public MyRunnable(List<String> strsToSet) {
this.strsToSet = strsToSet;
}
#Override
public void run() {
try {
if(strsToSet.size() > 0) {
final String str = strsToSet.get(0);
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
txtLeadingText.setText(str);
}
});
Thread.sleep(1000);
List<String> newList = new LinkedList<String>(strsToSet);
newList.remove(0);
new Thread(new MyRunnable(newList)).start();
}
}
catch(InterruptedException e) {
e.printStackTrace();
}
}
}
new Thread(new MyRunnable(Arrays.asList(one, two, three))).start();
It is hard to do in Swing but in contrast in dynamically languages (like Groovy) it would go as simple as that (you'll get a better grasp of what is going on):
edt {
textField.setText(one)
doOutside {
Thread.sleep(1000);
edt {
textField.setText(two)
doOutside {
Thread.sleep(1000);
edt {
textField.setText(three)
}
}
}
}
}
The GUI event loop updates the screen, but it can't update the screen until you return.
I suggest you avoid doing any blocking operations in the GUI event thread.
I'm designing a simple JavaFX form.
First, I load the JavaFX environment (and wait for it to finish), with something like this :
final CountDownLatch latch_l = new CountDownLatch(1);
try {
// init the JavaFX environment
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new JFXPanel(); // init JavaFX
latch_l.countDown();
}
});
latch_l.await();
}
This works fine. (the reason why I need to first load the JavaFX this way, is because it's mainly a Swing application, with some JavaFX components inside, but they are loaded later)
Now, I'd like to add a splash-screen on launch, and displays it while the JavaFX environment loads (and in fact put in on-screen for like 5 seconds, because there are logo, trademark etc.. of the application I need to show)
So I came up with a SplashScreen class, which just displays a JWindow on-screen, like that :
public class SplashScreen {
protected JWindow splashScreen_m = new JWindow();
protected Integer splashScreenDuration_m = 5000;
public void show() {
// fill the splash-screen with informations
...
// display the splash-screen
splashScreen_m.validate();
splashScreen_m.pack();
splashScreen_m.setLocationRelativeTo(null);
splashScreen_m.setVisible(true);
}
public void unload() {
// unload the splash-screen
splashScreen_m.setVisible(false);
splashScreen_m.dispose();
}
}
Now, I want for the splash-screen to load and display itself 5 seconds.
Meanwhile, I want the JavaFX environment to load, too.
So I updated the CountDownLatch like this :
final CountDownLatch latch_l = new CountDownLatch(2); // now countdown is set to 2
final SplashScreen splash_l = new SplashScreen();
try {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// show splash-screen
splash_l.show();
latch_l.countDown();
// init the JavaFX environment
new JFXPanel(); // init JavaFX
latch_l.countDown();
}
});
latch_l.await();
splash_l.unload();
}
So, it's working, but the splash only stays for the JavaFX environment to load, so basically it unloads very quickly (which is normal, given the code I wrote).
How to display the splash-screen for 5 seconds minimum (if the JavaFX loads faster) without freezing the EDT ?
Thanks.
The most significant issue is you're blocking the Event Dispatching Thread, meaning that it can't display/update anything while it's blocked. The same problem applies to JavaFX.
You should, also, never update either from anything other then they respective event queues.
Now, there are any number of ways you might be able to go about this, but SwingWorker is probably the simplest for the time been.
I apologise, this is the entire exposure to JavaFX I've had...
public class TestJavaFXLoader extends JApplet {
public static void main(String[] args) {
new TestJavaFXLoader();
}
public TestJavaFXLoader() throws HeadlessException {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
Loader loader = new Loader();
loader.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("state") && evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
System.out.println("Load main app here :D");
}
}
});
loader.load();
}
});
}
public class Loader extends SwingWorker<Object, String> {
private JWindow splash;
private JLabel subMessage;
public Loader() {
}
protected void loadSplashScreen() {
try {
splash = new JWindow();
JLabel content = new JLabel(new ImageIcon(ImageIO.read(...))));
content.setLayout(new GridBagLayout());
splash.setContentPane(content);
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
subMessage = createLabel("");
splash.add(createLabel("Loading, please wait"), gbc);
splash.add(subMessage, gbc);
splash.pack();
splash.setLocationRelativeTo(null);
splash.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
protected JLabel createLabel(String msg) {
JLabel message = new JLabel("Loading, please wait");
message.setForeground(Color.CYAN);
Font font = message.getFont();
message.setFont(font.deriveFont(Font.BOLD, 24));
return message;
}
public void load() {
if (!EventQueue.isDispatchThread()) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
#Override
public void run() {
loadSplashScreen();
}
});
} catch (Exception exp) {
exp.printStackTrace();
}
} else {
loadSplashScreen();
}
execute();
}
#Override
protected void done() {
splash.dispose();
}
#Override
protected void process(List<String> chunks) {
subMessage.setText(chunks.get(chunks.size() - 1));
}
#Override
protected Object doInBackground() throws Exception {
publish("Preparing to load application");
try {
Thread.sleep(2500);
} catch (InterruptedException interruptedException) {
}
publish("Loading JavaFX...");
runAndWait(new Runnable() {
#Override
public void run() {
new JFXPanel();
}
});
try {
Thread.sleep(2500);
} catch (InterruptedException interruptedException) {
}
return null;
}
public void runAndWait(final Runnable run)
throws InterruptedException, ExecutionException {
if (Platform.isFxApplicationThread()) {
try {
run.run();
} catch (Exception e) {
throw new ExecutionException(e);
}
} else {
final Lock lock = new ReentrantLock();
final Condition condition = lock.newCondition();
lock.lock();
try {
Platform.runLater(new Runnable() {
#Override
public void run() {
lock.lock();
try {
run.run();
} catch (Throwable e) {
e.printStackTrace();
} finally {
try {
condition.signal();
} finally {
lock.unlock();
}
}
}
});
condition.await();
// if (throwableWrapper.t != null) {
// throw new ExecutionException(throwableWrapper.t);
// }
} finally {
lock.unlock();
}
}
}
}
}
I found the runAndWait code here