I am interacting with a third party application using it's API, and would like to move it to the front of focus (so that it is on top of all other open windows) when a user performs a certain action. While I can move my application up and down in the hierarchy pretty easily, there doesn't appear to be a way to interact with other windows. Is it possible to move another program's window to front with Java?
You can't do it in pure Java code, but you could using JNI. See In Java Swing how do you get a Win32 window handle (hwnd) reference to a window? for how to get a handle to the window. Then you could do something like http://msdn.microsoft.com/en-us/library/ms633545 to move it to the front.
Caveat: This is for windows only
It's not possible in pure Java and on certain OSes it's not even possible to cleanly get the other windows position (for example good luck doing that under OS X 10.4: OS X 10.4 does not have any documented mean to registered for other windows' events... There are "hacks", but they're really hackish, like requiring the user to turn on the "Allow Assistive Device" preferences, which requires the OS X admin passord).
I was looking for a solution to a very similar problem.
Until now I have found one - very fragile! - solution.
It works for my case, because my case involves running entire sessions using java.awt.Robot without user interaction, so it may - or may not - work for your case.
The solution is using java.awt.Robot to send the key strokes like Alt+Tab to bring the desired Window to the front.
This is fragile of course, due to multiple reasons:
The Robot cannot know how often Alt+Tab needs to be send to get the desired window to front. The window is one in many. This solution only works if it's already known which window in terms of Alt-Tab-count it is.
Depending on the OS, the required keystrokes might actually be something else.
In case the OS and the window sequence are known, i.e. the program can know upfront how many Alt-Tab keystrokes would be required, this could sometimes be a solution.
The following Java program demonstrates how to do this. If called without arguments, it generates exactly one Alt+Tab keystroke. If called with arguments, the program assumes the first argument is a number and it will generate as many Alt+Tab keystrokes as specified by that number.
You may want to play around a bit with the timing values given in robot.delay() and robot.setAutoDelay() in order to deliver the best experience on your machine. Hint: at least on Linux, robot.setAutoDelay() should certainly be less than the keyboard repeat delay, otherwise the OS would generate multiple Alt-Tab keystrokes in the system's event queue because of key repetition.
import java.awt.AWTException;
import java.awt.Robot;
import static java.awt.event.KeyEvent.VK_ALT;
import static java.awt.event.KeyEvent.VK_TAB;
import static java.lang.Integer.parseInt;
public class WindowSwitcher {
public static void main(final String... args) throws AWTException {
final int repeat = args.length != 0 ? parseInt(args[0]) : 1;
final Robot robot = createRobot();
robot.keyPress(VK_ALT);
for (int i = 0; i < repeat; i++) {
robot.keyPress(VK_TAB);
robot.keyRelease(VK_TAB);
robot.delay(500);
}
robot.keyRelease(VK_ALT);
}
public static Robot createRobot() throws AWTException {
final Robot robot = new Robot();
robot.setAutoWaitForIdle(true);
robot.setAutoDelay(10);
return robot;
}
}
Related
I want to take screenshots of rendered scenes without displaying the game itself. The procedure I want to follow is:
createScene();
for(i = 0; i < num_screenshots; i++)
{
moveCameraRandomly();
saveScreenshot();
}
Basically, I want to randomly reposition the camera in the scene for each screenshot I take. However, I need to call this as a function, so I don't want to display the game itself (but I'm fine with it running in the background). Ideally, I would like to have two projects, one which creates screenshots and one which creates the game, where the first one calls the second one. Is there a way to do this?
Applications can be started in headless mode.
Application app = new Main();
app.start(JmeContext.Type.Headless);
http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:headless_server
The ScreenshotAppState can take screenshots:
http://wiki.jmonkeyengine.org/doku.php/jme3:advanced:screenshots
Now you need to develop a combination of both, which is automatically taking screenshots. I recommend that you read the source code of ScreenshotAppState. A already did a similar thing and can tell it is possible.
Let's say I wrote simple Python application that can assign macros to any standard keyboard press. For example, it can make the "z" key input "hello" into (and because I'm asking specifically about a java app) a java app. Or another example, Windows MouseKeys. MouseKeys (at least superficially) categorically changes the + sign on the num pad into a left mouse click. The Java app will then only receive a left mouse click on a num pad + press and not, additionally, the + keystroke, right? In anticipation of a succinct "it depends" response, an explanation at the very least specifically on the mechanics of MouseKeys and gaming mice software that can emulate any key via a button that isn't by default recognized itself by Windows.
I'm looking to make about 10 textboxes for the user to type into then store that value as a variable. Is there anyway to make a textbox function with the parameters being the position?
Yes, that’s possible using the library controlP5.
import controlP5.*;
ControlP5 cp5;
String[] textfieldNames = {"tf1", "tf2", "tf3", "tf4", "tf5"};
void setup() {
size(700,400);
PFont font = createFont("arial",20);
cp5 = new ControlP5(this);
int y = 20;
int spacing = 60;
for(String name: textfieldNames){
cp5.addTextfield(name)
.setPosition(20,y)
.setSize(100,40)
.setFont(font)
.setFocus(true)
.setColor(color(255,0,0))
;
y += spacing;
}
textFont(font);
}
void draw() {
background(0);
}
void controlEvent(ControlEvent theEvent) {
if(theEvent.isAssignableFrom(Textfield.class)) {
println("controlEvent: accessing a string from controller '"
+theEvent.getName()+"': "
+theEvent.getStringValue()
);
}
}
If you're a proficient Java programmer, you may consider using the Swing Library, the primary Java GUI widget toolkit. However, you'd also find yourself messing around with the Processing core code. Don't do that.
The main rule when using Java code [in a Processing sketch]: you cannot use most of the AWT or
Swing (which is built on the AWT), because it will interfere with the
graphics model. If you want to add scroll bars and buttons to your
projects, you should make them using Processing code, or embed your
Processing applet inside another Swing or AWT application.
Even if they appear to work, such sketches will usually break when you
try to run on other operating systems or other versions of Java. – Processing FAQ
If you're not a Java programmer, stick with Processing libraries or make your own text field class.
The popular ControlP5 GUI library has built-in classes for text fields and text areas. As of yet, This version has been tested with processing 2.0b7 and it may not work with the latest 2.0 release.
You may also use the G4P library and its text area implementation.
If it's the first time you're using external libraries, open Processing and add contributed libraries by selecting "Add Library..." from the "Import Library..." submenu within the upper bar menu.
EDIT: I've never tried it, but Interfascia (alpha release) has a text field class too. The documentation seems easy to read and the code easy to use.
I'm currently attempting to use the openoffice API to display a powerpoint presentation from Java - I've got a fair way in that I've managed to open a presentation and display it. However, there's a couple of things that I'd like to be able to do I can't figure out with the API as it stands:
I don't want the main Impress window to appear, just the presentation window. Now, I can start it minimized no problem with a property, but then the actual presentation window is minimised as well, which I don't want. I can also grab the window and call setVisible(false) on it, but it's still visible for a second or so while it's loading.
I want to be able to control the monitor which the presentation appears on (I'm using it in a multi-monitor setup.) I thought I might be able to grab the Window of the presentation and move it around that way as I need to, but I can't see how - for the main window I can do something like:
XModel xModel = UnoRuntime.queryInterface(XModel.class, xDrawDoc);
xModel.getCurrentController().getFrame().getContainerWindow().blah();
...but I haven't yet found a way to get the presentation Window. I'd like to be able to set the bounds of the window directly (x, y, width, height) rather than just being constrained by positioning on a single monitor.
I can live with the first point, the critical one I need to solve for my use case is the second.
Any ideas on the above? I'm an experienced Java programmer but new to UNO.
Seems the second point can be solved, ish, with the display property:
public void start() {
try {
xPresentation.setPropertyValue("Display", 1);
}
catch (Exception ex) {
ex.printStackTrace();
}
xPresentation.start();
}
Note however a few of things - firstly the display index is base 1, not 0. Secondly, trying to set the properties in an array and passing them to xPresentation on creation didn't seem to have any effect - it only worked for me setting the property later as above. Thirdly, it doesn't allow fine grained control over the window as I wanted, just control of the display the presentation appears on.
I'm currently trying to create a little remote-app for Android to control a MediaPlayer (like Rythmbox) on my PC.
Most media-players understand the special keys on my keyboard (like "play/pause" or "next/previous"). My idea is that the Android App sends a command (like "pause") to the PC. On the PC runs a normal Java-Application which receives this commands and simulates a key-press of this special button.
The advantage would be that you can use this App on all platforms for every player which supports this special keys (and they are on almost every new USB-Keyboard).
I searched the JavaDocs for a constant in the KeyEvent-class, but I can't find any. Does anyone know how to simulate a press of one of those buttons and if this is even possible with Java?
Additional library's are okay with me, too, as long as there is no other solution.
Also, I know i should use a Robot to simulate the key-press and this works for all normal keys on my keyboard. I simply can't find any way to simulate a key press on those special keys.
So, I think it's not possible to do this with pure Java. I tried something else to find out which key-code the special keys have, but this small program only returns 0 for those keys (it works for "normal" keys):
public class GetKeycode implements KeyListener{
private JFrame f;
private JLabel feld;
public GetKeycode(){
f = new JFrame("GetKeycode");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.addKeyListener(this);
feld = new JLabel();
f.add(feld);
f.pack();
f.setVisible(true);
}
#Override
public void keyReleased(KeyEvent e) {
feld.setText(e.getKeyCode()+"");
}
public static void main(String[] args) {
new GetKeycode();
}
// Unused:
#Override public void keyPressed(KeyEvent e) {}
#Override public void keyTyped(KeyEvent arg0) {}
}
I hope this will be implemented in future versions of the JRE. But at the moment, there seems to be no solution for this.
Thanks for all the answers anyways.
Have you already tried to send the OS dependent key codes to the Robot? The multimedia keys are unfortunately not directly supported in Java yet, not even in Java 1.7 but most of the keycode definitions in java.awt.event.KeyCode have the same value as their native Windows pendants. The Robot doesn't filter unknown key codes directly in Java but lets its native back end decide what to do with them. So there is a chance that it might work at least on certain platforms.
The MUTE key code would be 0xAD. Here is a list of the Windows Key Codes.
VK_MEDIA_PLAY_PAUSE
VK_VOLUME_MUTE
VK_VOLUME_DOWN
VK_MEDIA_NEXT_TRACK
VK_MEDIA_PREV_TRACK
Control a Windows apps using Java
To temporarily solve your problem just google "rhythmbox android remote." There are some great projects already.