I am currently developing a digital clock widget. I have designed it using a JPanel form and add it to a JDialog. Here is the code.
static JDialog jDialog = new JDialog();
public static void main(String[] args)
{
jDialog.setUndecorated(true);
jDialog.add(new QuickLauncher());
jDialog.pack();
jDialog.setBackground(new Color(0, 255, 0, 0));
jDialog.setLocationRelativeTo(null);
jDialog.setVisible(true);
}
The problem is when I run this program twice it opens two windows. So what I need is I need only one window to run and if I run the program again instead of running the program again, it needs to focus the application. I tried various examples and methods like isVisible() and isActive() but I can't figure it out how to fix this issue. I tried this also,
How to check if a jframe is opened?
Please anyone can help me? Thanks in advance.
There isn't a particularly clean way to do this. If you're able to use Java 9, you can use the new process API to get a list of all processes with ProcessHandle.allProcesses() and search for ones that match your program, but otherwise you'd need to resort to platform-dependent behavior.
An alternative method (not requiring Java 9) would be to use a FileLock. You would create a file in a known location, then lock it (see above link). When the JVM shuts down, the lock will be released. When your program starts, you can then check whether the file is locked to determine whether your program is already running.
Related
I am new to Java programming and I know basic syntax of Java and can write programs.
I want to make desktop application in java that never lets the system sleep. I want that application to run in background and should not disturb the user flow.
I figured out some keyboard keys can be pressed internally which does not affect the flow like F13 F14 not shown to user but can be used internally.
Also I came with this java program that moves the mouse to its same position after some seconds so that system does not sleep.
import java.awt.*;
import java.util.*;
public class Mal{
public static void main(String[] args) throws Exception{
Robot mal = new Robot();
while(true){
mal.delay(1000 * 60);
mal.mouseMove(mouseLoc.x, mouseLoc.y);
}
}
}
I am curious to know how to make desktop app for windows using Java.
Like when user clicks on the app it get activated and keep running in the background until close by the user and it should never let the PC sleep either my moving mouse or by clicking special keys.
Useful links, code and path for development is required.
Thank You!
You could try using java.awt.Robot: https://docs.oracle.com/javase/7/docs/api/java/awt/Robot.html
As the documentation notes, this will not work in all environments, because allowing user-space programs to emulate user input is a bit of a security issue.
This question already has an answer here:
How to stop Java from running the entire code with out waiting for Gui input from The user
(1 answer)
Closed 5 years ago.
I'm a rather basic programmer who has been assigned to make a GUI program without any prior experience with creating a GUI. Using NetBeans, I managed to design what I feel the GUI should look like, and what some of the buttons should do when pressed, but the main program doesn't wait for the user's input before continuing. My question is, how do I make this program wait for input?
public class UnoMain {
public static void main(String args[]) {
UnoGUI form = new UnoGUI(); // GUI class instance
// NetBeans allowed me to design some dialog boxes alongside the main JFrame, so
form.gameSetupDialog.setVisible(true); // This is how I'm trying to use a dialog box
/* Right around here is the first part of the problem.
* I don't know how to make the program wait for the dialog to complete.
* It should wait for a submission by a button named playerCountButton.
* After the dialog is complete it's supposed to hide too but it doesn't do that either. */
Uno Game = new Uno(form.Players); // Game instance is started
form.setVisible(true); // Main GUI made visible
boolean beingPlayed = true; // Variable dictating if player still wishes to play.
form.playerCountLabel.setText("Players: " + Game.Players.size()); // A GUI label reflects the number of players input by the user in the dialog box.
while (beingPlayed) {
if (!Game.getCompleted()) // While the game runs, two general functions are repeatedly called.
{
Player activePlayer = Game.Players.get(Game.getWhoseTurn());
// There are CPU players, which do their thing automatically...
Game.Turn(activePlayer);
// And human players which require input before continuing.
/* Second part of the problem:
* if activePlayer's strategy == manual/human
* wait for GUI input from either a button named
* playButton or a button named passButton */
Game.advanceTurn();
// GUI updating code //
}
}
}
}
I've spent about three days trying to figure out how to integrate my code and GUI, so I would be grateful if someone could show me how to make this one thing work. If you need any other information to help me, please ask.
EDIT: Basically, the professor assigned us to make a game of Uno with a GUI. There can be computer and human players, the numbers of which are determined by the user at the beginning of the game. I coded the entire thing console-based at first to get the core of the game to work, and have since tried to design a GUI; currently this GUI only displays information about the game while it's running, but I'm not sure how to allow the code to wait for and receive input from the GUI without the program charging on ahead. I've investigated other StackOverflow questions like this, this, this, or this, but I cannot comprehend how to apply the answers to my own code. If possible, I'd like an answer similar to the answers in the links (an answer with code I can examine and/or use). I apologize if I sound demanding or uneducated and confusing; I've been working diligently on this project for a couple weeks and it's now due tomorrow, and I've been stressing because I can't advance until I figure this out.
TL;DR - How do I get my main program to wait and listen for a button click event? Should I use modal dialog boxes, or is there some other way to do it? In either case, what code needs to be changed to do it?
Unlike console based programming, that typically has a well defined execution path, GUI apps operate within a event driven environment. Events come in from the outside and you react to them. There are many types of events that might occur, but typically, we're interested in those generate by the user, via mouse clicks and keyboard input.
This changes the way an GUI application works.
For example, you will need to get rid of your while loop, as this is a very dangerous thing to do in a GUI environment, as it will typically "freeze" the application, making it look like your application has hung (in essence it has).
Instead, you would provide a serious of listeners on your UI controls that respond to user input and update some kind of model, that may effect other controls on your UI.
So, to try and answer your question, you kind of don't (wait for user input), the application already is, but you capture that input via listeners and act upon them as required.
I am having trouble getting message boxes and to a degree dialog boxes to show/function properly in Mac (v10.9.5).
I just updated the JRE and JDK to the latest version (8u31). A "java -version" from a terminal window shows that I am indeed using 8u31. (I was previously using 8u20, which exhibited the same behavior.)
The code below works perfectly in Windows and a couple of different versions of Linux that I tested, no issues. I just have issues on a Mac. I streamlined my code, which is SWT based, but this example uses Swing, to the following:
package myTest;
import java.awt.Dimension;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
public class EntryCode
{
public static EntryCode oEntryCode;
public EntryCode()
{
// TODO Auto-generated constructor stub
}
public static void main(String[] args)
{
oEntryCode = new EntryCode();
oEntryCode.open();
}
public void open()
{
JPanel panel = new JPanel();
panel.setMinimumSize(new Dimension(200,200));
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
}
I see the first system out line, and the code hangs on the message box request. In the real code, I simply use a null as the first argument. The original version of this test code used a null too, just I was experimenting with specifying a component. I thought that might be the problem. It is not.
When displaying SWT dialog boxes, there is a tendency that clicking on a button will hang the interface. The hang is somewhere between the button being depressed and the event handler firing. The event handler never fires.
I did not include a dialog box here. I figure that since my confirmation/message box exhibits the same problem that solve one, get the other for free.
I did a search on Google for displaying java applications on a Mac, but nothing turned up.
I would think that updating the JRE/JDK to the latest version would solve any OS related issues.
I compile the code to a jar and use the following to run from a terminal window. I to press Ctrl+C to quite the hung app.
java -XstartOnFirstThread -jar myTest.jar
Thoughts?
UPDATE:
I deleted the original update but am leaving the original question, now that I understand the problem better.
The real problem is how to initiate a proper Mac OSX Cocoa restriction friendly SWT application, which uses dialog and message boxes. (To the best of my knowledge, the only way to display message boxes is to use JOptionPane.show*, which is a Swing thing, thereby sort of mixing Swing and SWT.
It is interesting to note that the problem always relates to buttons, be it on a dialog box (a purely SWT implementation) or message boxes. In the former, the issue is a hang calling the event handler and the latter displaying a message box (null first argument, as no Swing frame exists in a SWT application).
The problem may be that you are not starting the GUI in the EDT. Try this:
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
oEntryCode = new EntryCode();
oEntryCode.open();
}
});
}
More info: http://docs.oracle.com/javase/tutorial/uiswing/concurrency/initial.html
Another issue is using -XstartOnFirstThread with Swing. Swing does the equivalent of what -XstartOnFirstThread is doing, but in its own way. You should not use -XstartOnFirstThread with Swing, just as it's not a good idea to mix SWT and Swing.
If you add SwingUtilities.invokeLater() and remove -XstartOnFirstThread, your example should run normally.
Not quite sure if this might be the error since I can't test it on my Mac at the moment. But you never setting visibility of the JFrame to true. When you pass the frame as a parameter to the JOptionPane the pane tries to show the pane in the frame.
So try :
public void open()
{
JFrame frame = new JFrame("JOptionPane showMessageDialog component example");
System.out.println("open(): entry - With frame");
frame.setSize(300,300);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
JOptionPane.showConfirmDialog(frame, "Wow, works on the Mac!", "Inside open()", JOptionPane.YES_NO_OPTION);
System.out.println("Point 1");
System.exit(0);
}
Also why do you create the JPanel the panel is never used as far as I can see ?
Since the frame is not visible this could cause problems. Just a guess...
This would also explain why it looks like your application is "freezing". Its because it is waiting for you to make the selection in your JOptionPane but you can't make that selection because you can't see the JOptionPane.
I know you wrote you also tried with passing null as argument but I could think this could also cause problems when there is no other JFrame shown. As i said just a guess. Just try it out and come back here to provide further information.
EDIT
Just tested and looks like your code is fine. Your error has to lie in your mac or java setup.
EDIT 2
I think I found your answer. Looks like the startOnFirstThread is the problem here. I just tested via javac and java on command line. Have a look at this:
Swing stops working, because -XstartOnFirstThread implies that that
someone else (very likely the SWT) is going to come around, and start
pumping the event loop on thread 0 with CFRunLoop or the like
This could explain why your JOptionPane struggles to show up. (Taken from: here
Also a bit older but describes your problem:
The AWT problems generally come down to which thread the jvm was started on. When using the java launcher (as pde does) on Mac, java by default starts on the second thread (which is what AWT wants) unless you specify -XstartOnFirstThread (which is what SWT wants).
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=212617)
I'm trying to close my main application user interface, but leave code running in my main() function that launched the application. Right now the problem I have is on a Mac the program name remains in Mac's menu bar even though there are no windows shown.
So basically in the code that would exit the application I have:
private void exitMenuItemActionPerformed(java.awt.event.ActionEvent evt) {
//System.exit(0);
this.setVisible( false );
// Do something here to finish closing application.
}
The main function that starts the application looks like:
public static void main(String args[]) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
// NewApplication is a javax.swing.JFrame
new NewApplication().setVisible(true);
}
});
while (true) {
// Watch for user to relaunch UI and do lots of other tasks.
}
}
If I used System.exit(0) it would stop the entire JVM completely and stop running the stuff in the while loop. I cannot figure out how to exit the main application UI, stop from showing in the menu bar, but still run the while loop stuff.
The reason I'm trying to do this is I need something that will run continuously and sometimes the user will need to run a user interface that interacts with the stuff that is running. The stuff inside the while loop checks to see if they are trying to launch the user interface again (among other functions) and would reload it. One option is to make one program that runs continuously and use inter-process communication to talk between the user interface and a non-UI program, but I would need to pass lots of data back and forth so I don't like that option.
It appears there is not an easy way of doing this. For those that have the same problem here are a few options:
1) It looks like other programs I have do this by using Mac’s task bar (in the upper right corner of the screen). The only way you access the program is through a menu on the task bar. Even when you have UI’s shown you get to the UI through the task bar. The downside of doing this is that when the UI is shown you can’t use Cmd+Tab to get over to the window. This is non-intuitive for Mac users. If you want to use this option you can start the java jar file with the command line option “-Dapple.awt.UIElement="true”” and that will prevent the program from showing a menu ALWAYS, and then you'll want to create a task bar icon so the user can get to your program.
See How to hide the Java SWT program icon in the Dock when the application is in the tray
2) Have 2 programs that run, one with a UI and another without. They can communicate using interprocess communication (IPC) using files, sockets, etc. If you don’t have much data to pass between the processes, this is a good solution.
3) You could probably use JNI to remove the menu on the application after all the UI’s close. But you’ll need to dig into Mac’s Objective C language. I can't confirm you can actually do this though.
I have a game editor, in which it is possible to launch the game being edited in a separate window (but within the same VM). However, when the game is closed, I would like to close its gdx window, without bringing down the whole application (that is, the editor).
I am currently using the following code inside the JFrame that hosts the LwjglApplication:
public void windowClosing(WindowEvent e) {
System.err.println("Now closing app...");
Gdx.app.exit();
System.err.println("App now closed.");
}
This prints the goodbye, closes the GDX window, and proceeds to terminate my VM. Any suggestions?
In the desktop (lwjgl backend) Gdx.app.exit() posts a Runnable that causes the loop mainLoop to complete and control to fall out the bottom of that function (see the source). The mainLoop ends with:
if (graphics.config.forceExit) System.exit(-1);
The graphics.config is the LwjglApplicationConfiguration object passed in LwjglApplication constructor. So just set
config.exit = false
in the config object (you may need to create one and use a different constructor if you're not currently creating a config object). There are other handy things you can set in the config object, too.
(This code is from GIT, so things may be different in older version of GDX or with other backends.)