0

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 ?

Gábor Bakos
  • 8,091
  • 51
  • 31
  • 48
sks
  • 11
  • 2
  • 1
    You might want to take a look at [key bindings](http://docs.oracle.com/javase/tutorial/uiswing/misc/keybinding.html). – TNT Jan 05 '15 at 19:47
  • 1
    @TNT You need a JComponent for that, which isn't available (yet). – Charlie Jan 05 '15 at 19:48
  • @Charlie Right... forgot that JFrame doesn't extend JComponent. – TNT Jan 05 '15 at 19:52
  • @TNT Even if it would, it wouldn't have any focus (As it is not visible), so it wouldn't register any keys. At sks, I think you would need [raw input](http://stackoverflow.com/questions/1066318/how-to-read-a-single-char-from-the-console-in-java-as-the-user-types-it) in a while loop to check for CTRL+C. – Charlie Jan 05 '15 at 19:54
  • Intent of my application is to run it as windows desktop application which will keep running as any other windows application and whenever user tries to copy any content using ctrl+c from other windows, my application should capture the event and display copied content in my application's GUI. – sks Jan 05 '15 at 20:14

2 Answers2

0

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.

pbespechnyi
  • 2,189
  • 1
  • 16
  • 28
0

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.

Community
  • 1
  • 1
Charlie
  • 928
  • 7
  • 24