I currently have a simple problem with LWJGL right now. If I were to run my game, it does actually run everything correctly and it appears to close out correctly, but when I look inside my Task Manager, I notice that my game is taking up 25% CPU after I close it (about 2-3% when it's actually running) and I'm thinking that I may have missed something when ending the application.
My main function code:
public static void main(String[] args){
try {
init();
}catch(LWJGLException e){
System.out.println("LWJGLException\n");
e.printStackTrace();
}
try{
gameLoop();
}catch(Exception ex){
ex.printStackTrace();
}finally{
cleanup();
}
}
cleanup:
public static void cleanup(){
System.out.println("Running cleanup code.");
Display.destroy();
System.exit(0);
}
It does actually manage to read "Running cleanup code." My problem is that I don't know if there is something else I need to do to clear out all of the processes. This game is also using a single thread.
There is nothing wrong with your code at all, I think. If your problem is what I think it is you wouldn't be able to immediately fix it.
Here are some basic questions you should ask your self. What OS are you using? What is your Java version and/or LWJGL version? (Updating them might help) Have you ever heard of/or played a game called Minecraft? If you are using Linux and seen this when closing Minecraft then that could be the problem you're having.
I have had the same problem on 64-bit windows. App haven't closed when Runtime Exception (or any other uncaught exception) occured. Probably reason was throwing an exception in an independent thread which effected in closing display window, but all other threads were still working. I came up with brute force solution: overriding Thread method.
Thread.setDefaultUncaughtExceptionHandler(new UncaughtExceptionHandler() {
#Override
public void uncaughtException (Thread thread, final Throwable ex) {
ex.printStackTrace();
Display.destroy();
System.exit(0);
}});
new LwjglApplication(new StartScreen(application), cfg);
Related
I'm making a small program in Java using the Robot class. The program takes over the mouse. while in the course of debugging if it starts acting in a way that I don't want it's hard to quit the program, since I can't move the mouse over to the terminate button in eclipse, and I can't use hotkeys to hit it because the mouse is constant clicking in another window, giving that window focus instead.
What I'd like to do is just hook up a keylistener so that when I hit q I can quit the program, but the only way I know how to do this involves making a window, and that window needs focus to capture the input. Is there a way to listen for keyboard or mouse input from anywhere, regardless of what has focus?
There is a library that does the hard work for you:
https://github.com/kwhat/jnativehook
This is not a trivial problem and Java doesn't give you a way to do it elegantly. You can use a solution like banjollity suggested but even that won't work all the time if your errant mouse clicks open another fullsized window currently open in your taskbar for example.
The fact is, Java by default gives developers very little control over the OS. This is due to 2 main reasons: security (as citied by java documentation) and the fact that different operating systems handle events completely differently and making one unified model to represent all of these would probably not make a whole lot of sense.
So to answer your question, I imagine what you want is some kind of behaviour for your program where it listens for keypresses globally, not just in your application. Something like this will require that you access the functionality offered by your OS of choice, and to access it in Java you are going to need to do it through a Java Native Interface (JNI) layer.
So what you want to do is:
Implement a program in C that will listen for global keypresses on your OS, if this OS is Windows than look for documentation on windows hooks which is well docuemented by Microsoft and MSDN on the web and other places. If your OS is Linux or Mac OS X then you will need to listen for global keypresses using the X11 development libraries. This can be done on an ubunutu linux distro according to a Howto that I wrote at http://ubuntuforums.org/showthread.php?t=864566
Hook up your C code to your Java code through JNI. This step is actually the easier step. Follow the procedure that I use in my tutorial at http://ubuntuforums.org/showthread.php?t=864566 under both windows and linux as the procedure for hooking up your C code to your Java code will be identical on both OSes.
The important thing to remember is that its much easier to get your JNI code working if you first code and debug your C/C++ code and make sure that it is working. Then integrating it with Java is easy.
Had same problem. In my case, robot just controlled a single Windows App, that was maximized. I placed these lines at top of main loop driving the robot:
Color iconCenterColor = new Color(255,0,0); // if program icon is red
if (iconCenterColor.equals(robot.getPixelColor(10,15)))
throw new IllegalStateException("robot not interacting with the right app.");
To cancel the robot, just alt-tab to another app. Works great for a simple one app driving robot.
Start the program from a command line in a terminal and use Ctrl-C to terminate it.
(As mentioned by #MasterID and shown on JNativeHook's documentation for native keyboard input detection {main GitHub project here}),
This code should be enough to listen to any key without app focus (press and/or release):
>>Remember to add the jnativehook library in your project to be able to use all its utilities.<<
public class yourClass implements NativeKeyListener {//<-- Remember to add the jnativehook library
public void nativeKeyPressed(NativeKeyEvent e) {
System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyReleased(NativeKeyEvent e) {
System.out.println("Key Released: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public void nativeKeyTyped(NativeKeyEvent e) {
System.out.println("Key Typed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
}
public static void main(String args[]){
//Just put this into your main:
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
GlobalScreen.addNativeKeyListener(new yourClass());
//Remember to include this^ ^- Your class
}
}
For this particular problem, use the nativeKeyPressed method like this:
public void nativeKeyPressed(NativeKeyEvent e) {
System.out.println("Key Pressed: " + NativeKeyEvent.getKeyText(e.getKeyCode()));
if (e.getKeyCode() == NativeKeyEvent.VC_Q){
System.exit(1);
}
}
Note that JNativeHook by default shows a lot of stuff in your console that you might not want, to change that, just add this right before the try-catch that you used in the main function as shown (this is also going to turn off warning and error messages, more info here):
//(From here)
Logger logger = Logger.getLogger(GlobalScreen.class.getPackage().getName());
logger.setLevel(Level.OFF);
logger.setUseParentHandlers(false);
//(To there-^)
try {
GlobalScreen.registerNativeHook();
}
catch (NativeHookException ex) {
System.err.println("There was a problem registering the native hook.");
System.err.println(ex.getMessage());
System.exit(1);
}
Disclaimer: I know this question was solved years ago, I just hope someone finds this a little easier to find/use.
Have your program open a second window which displays underneath your main window but is maximised, then your errant mouse clicks will all be received by the maximised window, and it can receive your keyboard input.
Here's a pure Java way to do it to solve the problem you've described (not the KeyListener problem... the quit test early when using robot problem):
Throughout your test, compare the mouse position with one that your test has recently set it to. If it doesn't match, quit the test. Note: the important part of this code is the testPosition method. Here's code that I used recently:
public void testSomething() throws Exception {
try {
// snip
// you can even extract this into a method "clickAndTest" or something
robot.mouseMove(x2, y2);
click();
testPosition(x2, y2);
// snip
} catch (ExitEarlyException e) {
// handle early exit
}
}
private static void click() throws InterruptedException {
r.mousePress(InputEvent.BUTTON1_DOWN_MASK);
Thread.sleep(30 + rand.nextInt(50));
r.mouseRelease(InputEvent.BUTTON1_DOWN_MASK);
Thread.sleep(30 + rand.nextInt(50));
}
private static void testPosition(int x2, int y2) throws ExitEarlyException {
Point p = MouseInfo.getPointerInfo().getLocation();
if(p.x != x2 || p.y != y2) throw new ExitEarlyException();
}
I have a simple console application which sometimes need to perform graphics operations, for those I'm using JavaFx framework (there are some functions that I need like the css styling for text )
I simply generate some shapes and text into an hidden scene then save those on file and that's all,
I know that to work with JavaFx I have to pass graphics operations to the JavaFx thread, but when everything is done and I have to close the application (after some hours) this JavaFx thread still remain open... and I really don't want to force exit with System.exit() because if something is blocked I may want to know/wait (ALSO I don't want to execute everything as an JavaFx application (as JavaFx components are less than 1% of my main application)
the code is very simple and googling around I've found only to use
Platform.exit();
which doesn't seems to work, I've also tried playing with Platform parameters like
Platform.setImplicitExit(false);
here is my test application which you can run :
import javafx.application.Platform;
import javafx.embed.swing.JFXPanel;
import javafx.geometry.Pos;
import javafx.scene.layout.VBox;
public class SOTestFX {
public static void main(String[] args) {
SOTestFX t = new SOTestFX();
t.runFxThread();
}
public void runFxThread(){
//Application.launch(args);
final JFXPanel jfxPanel = new JFXPanel();
Platform.runLater(new Runnable() {
#Override
public void run() {
System.err.println("CREATING IMAGE");
simpleFXoperations();
System.err.println("NOW CALL EXIT");
System.err.println("JAVA FX THREAD SHOULD BE EXITED NOW");
Platform.exit();
}
});
try {
Thread.sleep(3000); // just wait a bit if something should happen, let it happen..
} catch (InterruptedException e) {
e.printStackTrace();
}
//jfxPanel.removeNotify(); // return -> java.lang.NullPointerException
//Platform.exit(); // -> does nothing
System.err.println("i will never die!");
}
public void simpleFXoperations(){
VBox vbox1 = new VBox();
vbox1.setAlignment(Pos.BOTTOM_CENTER);
vbox1.setStyle("-fx-border-style: solid;"
+ "-fx-border-width: 1;"
+ "-fx-border-color: white");
System.err.println("simpleFXoperations() _DONE");
}
}
and this is the thread which never close
"Attach Listener" - Thread t#17 java.lang.Thread.State: RUNNABLE
Locked ownable synchronizers:
- None
"JavaFX Application Thread" - Thread t#13 java.lang.Thread.State:
RUNNABLE at com.sun.glass.ui.gtk.GtkApplication._runLoop(Native
Method) at
com.sun.glass.ui.gtk.GtkApplication$3$1.run(GtkApplication.java:82)
at java.lang.Thread.run(Thread.java:722)
Locked ownable synchronizers:
- None
Update: I'm using latest Oracle JDK 7u17 64bit on Linux Fedora 16 64bit.
Fix:
I was able to fix this problem by calling com.sun.javafx.application.PlatformImpl.tkExit() immediately before Platform.exit(). I don't really understand the JavaFX source that well, but it seems to be working; YMMV.
Update: Doing this in Java 8 will produce a warning, you can just turn the warning off with #SuppressWarnings("restriction"). It shouldn't be a problem.
Explanation:
I figured this out by digging through the source code; JFXPanel has this little snippet (this is from JavaFX 2.2.25)
finishListener = new PlatformImpl.FinishListener() {
public void idle(boolean paramAnonymousBoolean) {
if (!JFXPanel.firstPanelShown) {
return;
}
PlatformImpl.removeListener(JFXPanel.finishListener);
JFXPanel.access$102(null);
if (paramAnonymousBoolean)
Platform.exit();
}
public void exitCalled()
{
}
The problem is, if you are using only a little bit of JavaFX in your application, then the idle(boolean) method never does anything (because firstPanelShown == false), which prevents the listener from getting removed, which prevents the JavaFX Toolkit from shutting down... which means you have to shut it down manually.
Your main function does not belong to the JavaFx Application object and i think that your program never eneter application thread loop.
It seems you should do:
public class SOTestFX extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) throws Exception {
// Do stuff here to show your stage or whatever you want;
// This will be called on the JavaFX thread
}
}
That's a slippery situation, as (to my understanding) the purpose of the JavaFX thread is to take advantage of various hardware pipelines transparently. Might I suggest placing your JavaFX requests in a separate, referenced, project; and keep everything else, including your main method, in another? That's always worked for me.
Basically, business logic and model go in one project, and view and control (generally JavaFX-based) go in the other. This allows for independent termination of the JavaFX thread. Hopefully that is applicable to what you are trying to do.
I tried a lot of things on this as none of the above answers worked for me.
Best thing for me was to just shutdown the whole JVM using
System.exit(1);
as my whole Application is just that one JavaFX application and therefor can be shut down, when closing the Stage.
The 1 in my case is just a random int.
How do you close a java application from the code?
You call System.exit:
System.exit(0);
I believe that by most standards, System.exit() is a not very OOP way of closing applications, I've always been told that the proper way is to return from main. This is somewhat a bit of a pain and requires a good design but I do believe its the "proper" way to exit
If you're terminating a Swing app, I would do an EXIT_ON_CLOSE
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
before System.exit(0). This is better since you can write a Window Listener to make some cleaning operations before actually leaving the app.
That window listener allows you to exit the app from the code:
public void windowClosing(WindowEvent e) {
displayMessage("WindowListener method called: windowClosing.");
//A pause so user can see the message before
//the window actually closes.
ActionListener task = new ActionListener() {
boolean alreadyDisposed = false;
public void actionPerformed(ActionEvent e) {
if (frame.isDisplayable()) {
alreadyDisposed = true;
frame.dispose();
}
}
};
Timer timer = new Timer(500, task); //fire every half second
timer.setInitialDelay(2000); //first delay 2 seconds
timer.setRepeats(false);
timer.start();
}
public void windowClosed(WindowEvent e) {
//This will only be seen on standard output.
displayMessage("WindowListener method called: windowClosed.");
}
If you're running an application, System.exit will work.
System.exit(int);
In an applet, however, you'll have to do something along the lines of applet.getAppletContext().showDocument("landingpage.html"); because of browser permissions. It won't just let you close the browser window.
You use System.exit(int), where a value of 0 means the application closed successfully and any other value typically means something was wrong. Usually you just see a return value of 1 along with a message printed to sysout or syserr if the application did not close successfully.
Everything is fine, application shut down correctly:
System.exit(0)
Something went wrong, application did not shut down correctly:
System.err.println("some meaningful message"); System.exit(1)
I developed one swing application but each time you run application new window is opened.
I want that if one window is already opened other not allow to open.
Here is an example of a Java Single Application Instance:
A single instance application is one that only allows for 1 of the application to run no matter how many times the user tries to launch.
See also: A shorter example that does not notify the running instance.
The application tries to open a Socket on a specific port. In case another instance of your application is already running, opening the Socket fails.
This should already be sufficient for you, so you would not have to use the part of the code used to register new applications to the first one started.
Using a Socket has one great advantage compared to writing some sort of flag to the filesystem/registry/whatever:
It is removed even if your application crashes.
It actually sounds like you only want one application open at a time. In which case why not take out a file lock or similar when the application runs, and check that on start up. The headache (of course) is clearing up that lock in the event that your program doesn't exit cleanly.
My preferred solution is, as Peter Lang linked to, to use Sockets. When your app starts you can start a server socket listening for incoming connections on localhost (plus port of your choice). Before this happens in your code though you can try and make a connection to the server socket and if it is successful you know there is another instance already open, so you can quit the current instance with an appropriate message.
In your server socket implementation you can also add functionality that on receiving an incoming connection you actually force the current instance of the app to the foreground.
Do you mean run the GUI like a Singleton?, I have done this in the past by making a Static private "view manager" such that it is null and not created or visible until the first time the gui is created, after that just as with a classic singleton, the GUI is set to visible when the app is run again... I have a couple of Frameworks that follow this design--In these frameworks the GUI is not "primary" there are also command line and the like interfaces so the GUI is summoned via the command line...
public class Samp {
JFrame f=new JFrame();
File ff=new File("D:\\a.txt");
FileWriter fw;
public Samp() {
f.setBounds(0, 0, 200, 200);
try {
Scanner sc=new Scanner(ff);
if(!sc.hasNext()) {
fw=new FileWriter(ff);
fw.write("Running");
fw.close();
} else {
System.exit(0);
}
} catch(Exception e) {
System.out.println(e.getMessage());
}
WindowListener wndCloser = new WindowAdapter() {
public void windowClosing(WindowEvent e) {
try {
Scanner sc = new Scanner(ff);
if(sc.hasNext()) {
fw=new FileWriter(ff);
fw.write("");
fw.close();
}
} catch (Exception ex) { }
}
};
f.setVisible(true);
f.addWindowListener(wndCloser);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String args[]) {
new Samp();
}
}
Use Singletone Pattern as shown in the example!
I'm new to Java Applets. I have a problem while reloading the applet. When I resize the applet window or open some other application and then come back to the applet, the contents on the screen is redrawn. Basically my paint method is getting called. I want the contents of the paint method to be called only once. How can I accomplish this? Can anyone please help me with this?
Thanks in advance.
You are misunderstanding how paint works - you have no real control over how many times it is called. What are you doing in the paint method that makes you think you only want to do it once and why is it a problem that it gets called again?
If you're worrying about flickering, then you might like to look at painting into a buffer. Code not directly related to painting should not be in the paint method. You can put other initialization logic in the applet's start method
If you're putting initialization code into the paint method, you might think about putting it into the init or start methods instead.
The phrase you'd be looking for is applet lifecycle.
I am new to java applet design and when running it i get one problem that says "no main"
here is my code:
import java.applet.*;
import java.awt.*;
public class abhidev extends Applet {
/** Initializes the applet abhidev */
public void init() {
try {
setBackground(Color.cyan);
}
catch(Exception e){
e.printStackTrace();
}
}
public void paint(Graphics g){
try{
g.drawString("this ais an applet window",10,30);
showStatus("this is astatus window");
}
catch (Exception ex) {
ex.printStackTrace();
}
}
}
The applet class name is: abhidev.java.