How to kill a program with esc or a button Java - java

I want my program to run but once esc is pressed to quit the program. The only way I can think of doing this is by doing a scanner and looking for the next line but that pauses the whole program. Maybe a key listener but how do I make it be constantly checking? And it is a GUI. Any help would be great!
static Scanner sc = new Scanner(System.in);
stop = sc.nextLine();
if (stop.equals(a)){
running = false;
}
else{
do program
}

If u use a frame you can register the keys.
myFrame.getRootPane().getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(
KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "EXIT");
myFrame.getRootPane().getActionMap().put("EXIT", new AbstractAction(){
public void actionPerformed(ActionEvent e)
{
myFrame.dispose();
}
});

If this is a UI, you should not be maintaining any kind of loop that could block the Event Dispatching Thread.
The EDT will dispatch key events to your program and you can respond to them if you have registered for notifications.
I would avoid KeyListener as it requires the component it is registered to be focused and have keyboard focus before it will respond.
Instead, I would use the Key Bindings API.
You can register a Escape key to either the main application window (or sub component) or directly with the JButton you are using to close the application with.

Related

Allow user to redefine hotkeys for Swing during runtime Java

I have a Java application that contains a lot of features, and to make life easier for the user, I have set up numerous mnemonics and accelerators. For instance, I have a JMenuItem that allows the user to save the state of the application, witht he following code:
JMenuItem saveItem = new JMenuItem("Save");
saveItem.setMnemonic('S');
saveItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, InputEvent.CTRL_MASK));
This works as desired, but now I would like to give the user an option to change the hot keys. While CTRL + s would seem like a fairly obvious hot key to stick with, there are many features that use these short cuts, and simply picked Save as an example.
I have a JButton that I have arranged for testing purposes that allows the user to enter in a new shortcut when clicked. I was thinking that I would simply try and capture the keys that the user holds down (InputEvent) and presses (KeyEvent). I also though it might be smart to force the use of an InputMask to avoid complications in Text Fields and the like.
What I am wondering is: What is the best way to capture the new input that the user enters? I have looked up information regarding KeyBindings and they look right for the job, but the main issue I see is actually capturing the keys and saving them.
Sounds like you need to setup a KeyListener. When the user presses/releases a key, it triggers a KeyEvent from which you can retrieve the main key pressed (e.g. S) and the mask/modifiers (e.g. CTRL+SHIFT).
From there you can create a KeyStroke object and set this as the new accelerator of your menu.
public void keyReleased(KeyEvent e){
KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
menuItem.setAccelerator(ks);
}
The thing is you probably want this key listener to be removed right after the key released event, to avoid multiple keystrokes to be captured. So you could have this kind of logic:
JButton captureKeyButton = new JButton("Capture key");
JLabel captureText = new JLabel("");
KeyListener keyListener = new KeyAdapter(){
public void keyReleased(KeyEvent e){
KeyStroke ks = KeyStroke.getKeyStroke(e.getKeyCode(), e.getModifiers());
menuItem.setAccelerator(ks);
captureText.setText("Key captured: "+ks.toString());
captureKeyButton.removeKeyListener(this);
}
};
ActionListener buttonClicked = new ActionListener(){
public void actionPerformed(ActionEvent e){
captureKeyButton.addKeyListener(keyListener);
captureText.setText("Please type a menu shortcut");
}
};
captureKeyButton.addActionListener(buttonClicked);

Create java swing application to display GUI only when ctrl+c is pressed

I want to create a Java swing application which loads GUI only when Ctrl+C is pressed.
When I start the application, it should monitor keyboard events such that when Ctrl+C is pressed, GUI (JFrame) is displayed. I don't want to display any part of GUI till Ctrl+C is pressed.
I am unable to find how to associate keyboard event before any GUI component is realized. Is it possible to show JFrame i.e. frame.setVisible(true) conditionally on keyboard capture ?
On Linux/Unix
With a bit of help from this page:
// Setting console to raw mode
String[] cmd = {"/bin/sh", "-c", "stty raw </dev/tty"};
Runtime.getRuntime().exec(cmd).waitFor();
// Getting input stream
Console console = System.console();
Reader reader = console.reader();
// Checking if input is ^C
char c=0;
while(c!=3) { // 3 = ^C
c=(char)reader.read();
}
// ^C is entered
// Reset console to normal mode
cmd = new String[] {"/bin/sh", "-c", "stty sane </dev/tty"};
Runtime.getRuntime().exec(cmd).waitFor();
// Initialize frame
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(3);
frame.setSize(400,200);
frame.setLocationRelativeTo(null);
frame.setTitle("Why are you leaving me ?");
frame.setVisible(true);
On Windows/Macintosh
It doesn't seem to be possible with Java's own libraries. JLine could work as described here with this code:
ConsoleReader reader = new ConsoleReader();
char c=0;
while(c!=3) {
c=(char)reader.readVirtualKey();
}
// Frame stuff here
I think the comments explain everything you need. If not, let me know!
Sidenote: If you run this in Eclipse you'll get an NPE at Reader reader=console.reader(), because that's the way Eclipse runs its programs; without a console.
You can use Runtime.addShutdownHook(Thread hook).
Ctrl + C initiates SIGINT, this will cause JVM to shutdown, and then your hook will be invoked. Then you can add some loop with condition (to finalize JVM shutdown when it's needed) and Thread.sleep().
As another option, you can use Sun's Signal class from sun.misc package.
SignalHandler handler = (_) -> {
JFrame jFrame = new JFrame("Title");
jFrame.setVisible(true);
};
Signal.handle(new Signal("INT"), handler);
EDIT
To catch key combinations across the system, you can use jkeymaster lib.

Can I make an automated java application ignore JOptionPanes?

There is a java swing application that I need to automate one of the functions of. It's quite simple - the user clicks a button in the swing application and starts an action.
I made a small java application that includes the java swing application as a .jar and calls the action behind the button (read).
The problem is - in case of an exception, the swing .jar shows JOptionPane, which halts the automated execution. Is it possible to somehow override this behavior without altering the original jar?
Application structure:
Main.java
import com.swingapp.ui
public static void main(String[] args){
Swingapp.read();
}
Then the read() function in the Swingapp library:
public void read(){
try{
//do a bunch of stuff...
} catch (Exception ex){
JOptionPane.showMessageDialog(null, ex.getMessage()); // In case of an exception, the swing application will show a message dialog. This halts the automated execution of my java task, I'd like to just skip this
}
When exception happens in above application, user is expected to click "OK". But running this as automated task, nobody there to click okay
Since a JOptionPane gains focus as soon as it opens (I think the most right button gets the focus, but it does not matter in your case) you can do the following:
Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
#Override
public void eventDispatched(AWTEvent arg0) {
Component c = KeyboardFocusManager.getCurrentKeyboardFocusManager().getFocusOwner();
while(c != null) {
if (c instanceof JOptionPane) {
try {
new Robot().keyPress(KeyEvent.VK_ENTER);
} catch (AWTException e) {
e.printStackTrace();
break;
}
}
c = c.getParent();
}
}
}, AWTEvent.FOCUS_EVENT_MASK);
It will traverse up to see if anything in the current hierarchy is an instance of JOptionPane. If so -> simulate that the user pressed Enter (Return) which will close the dialog even if the focus is in an input field.
I have following solution for you. You need to registrate a listener to monitor all window events. Use Toolkit.getDefaultToolkit().addAWTEventListener(). If you get a window opened event, try to check whether the window is a JDialog and whether the dialog's contentPane contains an instance of JOptionPane. If yes you need traverse the component tree, find the first button and click it.

How do I close a java application from the code

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)

How to listen to press more buttons on the keyboard?

I on the keyboard a lot more buttons, and I really need to listen to push the buttons (multimedia play, stop ..).
How do it?
And I would like to catch the event, even when the window is minimized.
Use this jintellitype to catch key events outside your app in Windows.
Here is for linux JXGrabKey
Update: to use multimedia buttons, you need to know it's codes. Add this listener to your app's frame to find out codes:
class MyKeyListener extends KeyAdapter {
public void keyPressed(KeyEvent evt) {
System.out.println("Key code: " + evt.getKeyCode());
}
}
If you will know the code, just check if evt.getKeyCode() is what you need and make some actions.

Categories

Resources