I'm using JavaApplicationBundle to set icon for my jar file, and now I am trying to remove my program from Dock.
I've set LSUIElement to 1, but that didn't worked until I added StartOnMainThread directive in Java section of Info.plist.
But - then problem appeared - GUI was locked up - just like the program is executing infinite loop or something. I've changed main() to be like this:
public static void main(String[] args) {
Thread queryThread = new Thread() {
public void run() {
new MainWindow();
}
};
queryThread.start();
}
but I can't see the JDialog - it won't appear even if the JavaApplicationBundle process is running (as this is background application now - could there be some step that I am missing to bring up the dialog?)
What can cause this problem? Does anybody have simple app bundle where java program is running without sitting in Dock - I've searched internet, but nothing appeared in my search results?
Thanks
Edit
After reading comments, I've tried what I already tried, but I forgot about it:
public static void main(String[] args) {
javax.swing.SwingUtilities.invokeLater(new Runnable(){
public void run() {
new MainWindow();
}
});
}
In this case, application is running - but no GUI is shown. When I check Console Messages I see few of these:
*** -[NSConditionLock unlock]: lock (<NSCOnditionLock: 0x1347a0> '(null)') unlocked when not locked
*** Break on _NSLockError() to debug.
Related
This question already has answers here:
Create threads in java to run in background
(4 answers)
Closed 5 years ago.
This is my main method where I start my application. The JFrame loads successfully. When I add the WHILE-Loop part to do some background work where I work with some data to show on my JFrame my JFrame doesn't load correctly (see image below).
public static void main(String[] args) throws IOException {
if (Config.checkIfConfigExists() == true) {
/*
* Starten der Anwendung
*/
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
Main window = new Main();
window.frmServicenowHelper.invalidate();
window.frmServicenowHelper.validate();
window.frmServicenowHelper.repaint();
window.frmServicenowHelper.setVisible(true);
while (true) {
// the part that makes it error
}
} catch (Exception e) {
e.printStackTrace();
}
}
});
} else {
Notifications.alertMSGConfig("Config not found. Create one?");
}
}
As you can see the JFrame freezes and shows its background.
I found out it has something to do with Threads and correct processing (I think I am using something at the wrong point) but I am unable to fix it myself.
Background knowledge:
I want to get a JSON-String from a URL (the methods for that are working - I want to call & show the results on the frame) every 5 minutes (therefore the while-loop).
EDIT:
I tried this which loads the frame correctly but makes the loop (which I need) useless:
while (true) {
Main window = new Main();
window.frmServicenowHelper.invalidate();
window.frmServicenowHelper.validate();
window.frmServicenowHelper.repaint();
window.frmServicenowHelper.setVisible(true);
break;
}
I found the solution:
I simply created a new Thread (background processing) using:
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
runYourBackgroundTaskHere();
}
};
new Thread(r).start();
//this line will execute immediately, not waiting for your task to complete
}
Source: Create threads in java to run in background
Let's assume that I have the following program:
public class TestGUI {
public static void main(String[] args) {
System.out.println("Syso 1");
GUITest gtest = new GUITest ();
gtest.openWindow(); //basically the main method, contains setModal(true) and setVisible(true)
System.out.println("Syso 2");
}
}
This works perfectly fine. It prints "Syso 1" then opens the JDialog and after closing / confirming it, it prints "Syso 2" and this is exactly what I want.
I intend to run this exact code in my main program, which is going to be an Eclipse plugin and therefore opens another Eclipse when I'm debugging it.
However, if I run this as a plugin, the code goes until setVisible(true) and then nothing happens afterwards. I don't see a JDialog or anything like that.
I've read something about using something like:
SwingUtilities.invokeLater(
new Runnable() {
#Override public void run() {
gtest.setVisible(true);
}
}
);
This "unfreezes" my Eclipse and the program continues running afterwards, however, an JDialog is not opened. I want to decide what do to next based on the user input and then proceed normally in the code after the users confirmation.
Edit:
For some reason, it just started working on it's own. Regardless, here is what I was doing:
public Object execute(ExecutionEvent event) throws ExecutionException {
IWorkbenchWindow window = HandlerUtil.getActiveWorkbenchWindowChecked(event);
MessageDialog.openInformation(
window.getShell(),
"Test",
"Hello, Eclipse world");
System.out.println("Syso 1");
GUITest gtest = new GUITest ();
gtest.openWindow();
System.out.println("Syso 2");
}
Edit 2:
Well, maybe it's not working as intended. It works on some occasions but not on others. Someone on SO mentioned things that things like that are related to thread safety. Any ideas?
Previously I faced an issue with Modal window’s in my project. And I have resolved the issue by implementing Multi-Thread concept. i.e., I have created a new thread before clicking to any element, which will evoke a modal window.
In the run(), I have wrote set code which will select a value from the modal window. And modal window will get closed automatically after clicking any value from the list.
code snippet
public class MyProj implements Runnable {
static WebDriver driver = new FirefoxDriver();
Thread t;
MyProj() {
// Code to create a Thread
}
public void run() {
// Code to select a option from the Modal window
}
public static void main(String[] args) throws AWTException, FindFailed, InterruptedException {
driver.get(...);
// Code .........
new MyProj(); //Calling Constructor to create a new thread
driver.findElement(...).click(); // click to open modal window
System.out.println(driver.getTitle()); // Getting error at this point
After the successful execution of method run , when I tried to execute driver.getTitle(), to know where the control is now ,getting an error as
“Window not found. The browser window may have been closed”.
How to overcome from this error?? Kindly help !
Use the following code to start a Thread.Give it a try ! I tried in my system it is working fine.Let me know if you face any issue.
MyProj() {
t = new Thread(this);
t.start();
}
I'm trying to write a Swing application in Java that also runs the Google AppEngine Dev-Server (see Developing a Java Application that uses an AppEngine database) and am running into a strange problem with the Swing Eventloop.
I have the following two classes:
A debug-window, which will eventually receive log messages, etc:
public class DebugWindow {
private static JFrame debugWindow = null;
private static JTextArea debugContent = null;
public static void show() {
debugWindow = new JFrame("Debug");
debugWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
debugContent = new JTextArea("Debug messages go here!");
debugWindow.add(debugContent, BorderLayout.CENTER);
debugWindow.pack();
debugWindow.setVisible(true);
}
}
A helper-class that loads the Google AppEngine Dev-Server:
// other imports
import com.google.appengine.tools.development.DevAppServerMain;
public class DevServer {
public static void launch(final String[] args, boolean waitFor) {
Logger logger = Logger.getLogger("");
logger.info("Launching AppEngine server...");
Thread server = new Thread() {
#Override
public void run() {
try {
DevAppServerMain.main(args); // run DevAppServer
} catch (Exception e) { e.printStackTrace(); }
}
};
server.setDaemon(true); // shut down server when rest of app completes
server.start(); // run server in separate thread
if (!waitFor) return; // done if we don't want to wait for server
URLConnection cxn;
try {
cxn = new URL("http://localhost:8888").openConnection();
} catch (IOException e) { return; } // should never happen
boolean running = false;
while (!running) {
try {
cxn.connect(); // try to connect to server
running = true;
} catch (Exception e) {}
}
logger.info("Server running.");
}
}
My main(...) method looks like this:
public static void main(final String[] args) throws Exception {
DevServer.launch(args, true); // launch and wait for AppEngine dev server
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
DebugWindow.show(); // create and show debug window
}
});
}
With this I'm getting some very strange behavior regarding the Swing Eventloop:
First, the way Swing should work: If I comment out the line DevServer.launch(...) in main(...), the application launches, shows the debug window, keeps running, and when I close the debug window, it shuts down.
If I add DevServer.launch(...) back in, it launches the server as expected, and then quits immediately (it probably also showed the debug window briefly, but it's too quick to see).
If I move DevServer.launch(...) line after SwingUtilities.invokeLater(...), it shows the debug window, then launches the server, and when the server is up, it quits immediately.
Now it get's really weird: If I change the line to DevServer.launch(args, false), i.e. I don't wait for the server to actually launch, but simply let my main(...) method complete immediately, the debug window shows, the server loads correctly, the application keeps running, but doesn't quit if I close the debug window?!
If I then also change JFrame.DISPOSE_ON_CLOSE to JFrame.EXIT_ON_CLOSE, the debug window shows, the server loads correctly, the application keeps running, and it quits correctly if I close the debug window.
Any idea what is going on with the Swing event loop here? I'm stumped... Are there things that will cause the Swing event loop to terminate early (scenario 2 and 3)? Do multi-threaded applications prevent Swing from detecting the last disposed window (scenario 4)?
For reference, here is the source of the Google AppEngine Dev Server.
Items #4 and #5 are actually expected behavior. A Java/Swing application doesn't stop when the last Swing window is disposed, but when the last thread stops executing. These two conditions are equivalent for single-threaded applications, but not for multi-threaded ones.
As for #1, #2 and #3: looking through the AppEngine Dev Server code, I noticed a fair amount of System.exit(int) calls in there. One of these is probably the culprit. If the code you're showing is all that's relevant, then the offending System.exit is likely called in response to the connection established after if (!waitFor) return; (due to #4)
I have an application that in the back-end deploys a lightweight HTTP server (Jetty).
The servlets basically update a MySQL database.
I have wired everything using Spring.
So far ok.
I have a UI that I want to use to interact with the server.
If the UI runs locally I want it to display in a JTree the currently logged-in users.
So I decided to start the server i.e. start Spring when launching the main frame.
On top of that, in order to update the UI's JTree to show all the logged-in users I thought to use the Observer-Observable and have the code that accepts connections be an Observable.
A ConnectionListener would be notified of incoming connections storing them in an ArrayBlockingQueue and background thread (having a reference to the DefaultMutableTreeNode root) of the Jtree would update it -in the EDT thread of course via SwingUtilities.
My problem is the following:
If I do:
public class AdminFrame extends JFrame {
public static ClassPathXmlApplicationContext ctx = new ClassPathXmlApplicationContext("myBeans");
public static void main(String[] args){
EventQueue.invokeLater(new Runnable() {
public void run() {
//Show GUI
}
}
}
The GUI is not drawn but I can understand that since once Spring start and the server starts the thread does not return.
So I start Spring in a back-end thread as follows:
public class ServerThread extends Thread {
#Override
public void run() {
ClassPathXmlApplicationContext ctx = ApplicationCtx.getApplicationCtx();
}
}
and
public class ApplicationCtx {
private static ClassPathXmlApplicationContext ctx;
private ApplicationCtx(){}
public static synchronized ClassPathXmlApplicationContext getApplicationCtx(){
if(ctx == null){
ctx = new ClassPathXmlApplicationContext("myBeans.xml");
}
return ctx;
}
}
The GUI now shows up and seems ok BUT I am missing the notification.
PROBLEM:
It is not possible to get notification for the new connections:
1) If I register for notification as follows:
public class AdminFrame extends JFrame {
public static void main(String[] args) {
ServerThread lightweightServer = new ServerThread();
lightweightServer.start();
Thread.sleep(9000);//Temporary solution to make sure the server is started up before GUI
ConnectHandler connectHandler = (ConnectHandler) ApplicationContext.getApplicationCtx().getBean("connectHandler");
connectHandler.addObserver(new ConnectionListener());
EventQueue.invokeLater(new Runnable() {
public void run() {
//SHOW GUI
}
}
The GUI never shows up. If I remove the line:
ConnectHandler connectHandler = (ConnectHandler) ApplicationContext.getApplicationCtx().getBean("connectHandler");
The GUI shows up.
2) If I register inside the EDT i.e. inside the constructor of AdminFrame the GUI does not show up either.
I.e.
public class AdminFrame extends JFrame {
public static void main(String[] args) {
ServerThread lightweightServer = new ServerThread();
lightweightServer.start();
Thread.sleep(9000);//Temporary solution to make sure the server is started up before
EventQueue.invokeLater(new Runnable() {
public void run() {
AdminFrame frame = new AdminFrame();
//Other code
}
Again if I remove the following line the GUI shows up but this way I can not register to get notifications:
ConnectHandler connectHandler = (ConnectHandler) ApplicationContext.getApplicationCtx().getBean("connectHandler");
This must be a thread issue but I can not understand what is the problem.
Why is the second call to Spring application context to get the ConnectHandler make the thread not return?
What am I doing wrong here?
UPDATE:
The problem is solved if I add in the Spring configuration file the attribute lazy-init="true" to the bean that starts the Jetty server.
But I can not understand why it solves it or what is the problem.
Thanks
Serializable or Observate required wraping GUI rellated code into (in most cases) invokeAndWait()
output from SwingWorker (since is guaranteed but I saw some cases that not works as I expecting) or Runnable#Thread required raping GUI rellated code into invokeLater()
you can prepare your GUI (then there EDT exists) before, and visibility
.
JFrame#pack();
JFrame#setVisible(true);
.
for this Container you have to invoke inside invokeXxx(); or best would be from javax.swing.Action()
If setting up lazy-init to true solve your problem, i think its not solved completely.
By default, all beans initialized at startup so you get the problem in starting if any of the bean is not initialized correctly.
If you set it to false, bean will not be invoked and you will not face any isssue. So the problem is not solved but deferred.