Passing of MouseEvents to other applications/windows in JavaFX-8 - java

i was wondering if it is possible to pass an MouseEvent, which occurs on a specific Stage to pass through the window of another program/application which to be fired there.
To be more specific, i want to program a HUD-like program for informational purposes, which should not interfere with the normal desktop usage (such as operating scrollbars/buttons which are underneath the "HUD").
One approach to accomplish such behaviour could be achieved using the Robot class in combination with an MouseListener.
Example:
scene.setOnMouseClicked(new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent event) {
stage.hide();
robot.mousePress(InputEvent.BUTTON1_MASK)
stage.show();
}
});
That should work (not yet tried), but feels kinda like a workaround, also this attempt should make problems if one tries to handle drag & drop. Are there any other possibilities to pass any kind of MouseEvents to other windows? Is it possible to make a Stage mouse transparent such as it is possible for Nodes ?

Related

Prevent JavaFx Scene from gaining focus - Onscreen Keyboard

I'm trying to build an onscreen keyboard in javafx. The only issue I am having is that when you select the javafx scene or click a button on the window, the focus is then redirected to the javafx scene and the button click doesn't actually type a letter on a browser, text document, etc.
Here is my code for the button click. I'm using the robot class.
private void handleButtonAction(ActionEvent event) throws AWTException {
Robot a = new Robot();
a.keyPress(KeyEvent.VK_Y);//testing keypress of "Y".
}
I've seen in Swing how you can set a focus property to false, but I'm set on using JavaFx. I've seen quite a few people attempt this same question, but no one has a correct answer.
I am afraid there is currently no way to achieve this purely with JavaFx.
Here is an example how you could achieve it by wrapping your JavaFx-App in a Swing-App. An architectural monstrosity ;).
Alternatively, I could imagine that using a native layer like JNI/JNA is possible in this scenario.
However, in this case I would question if Java is technically the right tool for the job. One might argue, that an OSK is by definition tightly coupled to the OS and as such more native toolkits are in order. This of course depends on the scope of your project. As a side project this might be fine, but as a product not.

Java Mouse Listener

This probably sounds simple and stupid, but for the life of me I cannot find a way to have a mouse listener which does mousePressed without having to be on a component. void mousePressed(){} doesn't seem to work the way I want it to.
Essentially I am making a java program which aims to work without graphics, and does things in the background. So if you click in chrome for example it still will effect the program.
What I was trying was this, which I realize is horribly incorrect.
class MKeyListener extends KeyAdapter {
#Override
public void keyPressed(KeyEvent e) {
moveMouse.playing = false;
}
}
As reccomended I tried the JNativeHook library, however it doesn't seem to work the way I think it should:
public class mousepresstest implements NativeMouseInputListener{
#Override
public void nativeMouseClicked(NativeMouseEvent e) {
System.out.println("worked");
}
}
It doesn't print the text on mouse pressed, am I missing something here?
Java Mouse listeners are only meant for swing/awt components and that too from the same running process.
If you want to listen for mouse/keyboard events from other apps use the JNativeHook
library.You can install a global keyboard hook and listen for keypress or a mousehook for mouse events.You do not need to use Swing or other GUI classes.
Internally JNativeHook uses JNI to provide these functionality.

How do JButtons in advanced applications work?

How do buttons in software written in Java work?
For example the above screenshot: when the user clicks different buttons, different algorithms are run on user-inputted data (it's a data analysis application) and the output is displayed. Just getting started writing Java GUI's though, it all seems like magic to me -- is there one ActionListener for every pane? Does it listen for different ActionCommands of the different buttons and execute the algorithm right within the actionPerformed() method (it seems a little nonintuitive to me to execute an algorithm in a method independent of data...i.e. the button doesn't know what data it's dealing with?). So far, all the action listener tutorials I've read online have merely printed something when the button is pressed...
What's the general structure for connecting button, actionlisteners, and actual actions performed in the background?
Thanks in advance.
The usual way is to have one action listener per button. The Statistics panel has access (via one of its fields), to the data it needs to read and modify). So, the handling of the first button in this panel could look like:
private void initButtonListeners() {
this.averageDegreeButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
computeAverageDegree();
}
}
// other buttons...
}
And the computeAverageDegree() method could look like
private void computeAverageDegree() {
double result = this.statistics.computeAverageDegree();
this.averageDegreeLabel.setText(formatDoubleToString(result));
}
My personal preference is to do almost nothing in the UI, but move it all to the model/controller side (not sure what the best name is as it is seldom pure MVC).
I think that everything you do in the UI should be doable through the API as well. Benefits are easier testing, redesign of the UI is possible without messing up your logic, easy to perform the heavy work on background threads, ... .
A good read describing this is the Humble Dialog article. Not really Swing specific, but applicable to all sort of UI's.
To answer your questions:
is there one ActionListener for every pane?
No, typically you have an Action (or ActionListener) for each button. I prefer to use Action instances as they are far more reusable then the typical anonymous ActionListener (and easier to test as well)
Does it listen for different ActionCommands of the different buttons and execute the algorithm right within the actionPerformed() method
Certainly not. Doing heavy calculations in that method will block the Swing UI thread (the Event Dispatch Thread), which results in a non-responsive UI while the calculations are ongoing. Showing progress becomes also impossible. Calculations are typically done on a worker thread, launched when your Action is triggered (for example using a SwingWorker). This is explained in the Concurrency in Swing tutorial.
it seems a little nonintuitive to me to execute an algorithm in a method independent of data...i.e. the button doesn't know what data it's dealing with?
The button should not know about the data. The data is typically stored in the model. The UI is only displaying it, but does not contain it (unless it is input just provided by the user). The button should just know what to call on the model. The model does whatever it has to do and fires an event. The UI picks up that event and updates itself.
At least, that is how Swing is designed (for example JTable and its TableModel). I so no good reason to not follow that model when making your own Swing UI's

ALWAYS on top window

I'm searching for a solution in order to keep a JFrame always on top and with always I really mean always.
setAlwaysOnTop( true );
This won't work when I'm starting a game in fullscreen mode. I know you normally don't want your windows to stay on top but in this case it's required.
This can't be done.
For example, the Windows Task Manager, even when set to Always on Top will get covered up by full-screen applications.
This is due to the fact that full-screen applications typically use a different graphics context and can't be overlayed.
Start another process to check if the window is on top,if not, set it on top.
This is a sample code that should be helpful
public class AllWaysOnTop extends JFrame implements WindowListener {
AllWaysOnTop() {
// Code to setup your frame
addWindowListener(this);
// Code to show your frame
}
// The window event handlers. We use WindowDeactivated to
// try and keep the splash screen on top. Usually only keeps
// the splash screen on top of our own java windows.
public void windowOpened(WindowEvent event){};
public void windowActivated(WindowEvent event){};
public void windowDeactivated(WindowEvent event){
toFront();
}
public void windowIconified(WindowEvent event){};
public void windowDeiconified(WindowEvent event){};
public void windowClosed(WindowEvent event){};
public void windowClosing(WindowEvent event) {};
}
Reference
This forum post
This sounds like the kind of question that Raymond Chen always has to answer over at Link. How can you really really forever and for true keep a window in the foreground? You can't. Because what happens if somebody ELSE's window uses the same trick to keep itself always always and forever in the foreground? Which one wins?
If you mean fullscreen as in DirectX/OpenGL/whatever, I'm not sure you can (or should) really pull it off. Most operating systems disable their native windowing during full screen to improve rendering performance. Swing works via the native windowing toolkit.
You could write something that uses a timer and in short intervals (e.g., 200ms) instructs your window to go to the top. Depending on your operating system this would be exactly what you need, or a horrible cause of performance trouble or flickering.
I'm not sure but i would bet that the Fullscreen window also has Always On Top set to true, and in that case you have stumbled into the realm of undefined behavior. In general when two windows are set to always on top there is no guarantee about ordering. I think in general though the order is just dependent on the order in which they were set to always on top. So in that case i would just wait until the app has gone fullscreen to set it to always on top and see if that works.
In other cases ive seen people start threads and then occasionally reset the fram to always on top.
All these solutions are ugly, so just use the one that lets you sleep at night.
I know this post is old, but I encountered this problem and I found a satisfying solution.
My program has some notifications that I wish to be always on top, but when a movie entered full-screen, they disappeared. Fortunate, my program updates these notifications every 5 seconds, and if I call setVisible(true) on these JWindows, at each update, they regain the top position, if they have lost it.
I was looking to do the same thing as OP, have my app running in the foreground while my game ran. It doesn't work in fullscreen but if you put the game into windowed mode and adjust the window settings to fit your tv it works. I only needed the frame.setAlwaysOnTop to make it work.

java Swing debugging headaches with Wacom pen tablet

I've been running up against a problem with Java Swing + my Wacom Graphire tablet for a few years in several Java applications and have now encountered it in my own.
I use a pen tablet to get around wrist issues while clicking a mouse, and it works fine under Windows except when I'm using Java applications. In Java applications, the single-click of the pen doesn't work correctly. (Usually the problem only occurs with file-selection dialog boxes or tree controls.) The pen tablet also comes with a wireless mouse that works with the same tablet, and its single-click does work correctly.
I don't know whether the problem is in the WACOM driver or in the Java Swing runtime for Windows or both. Has anyone encountered this before? I'd like to file a bug report with WACOM but I have no idea what to tell them.
I have been able to reproduce this in my own application that has a JEditorPane with an HTML document that I've added a HyperlinkListener to. I get HyperlinkEvent.ACTIVATED events on every single click with the mouse, but I do NOT get HyperlinkEvent.ACTIVATED events on every single click with the pen.
One big difference between a pen and a mouse is that when you click a button on a mouse, it's really easy to cause the button-click without mouse movement. On the pen tablet it is very hard to do this, and that seems to correlate with the lack of HyperlinkEvent.ACTIVATED events -- if I am very careful not to move the pen position when I tap the tablet, I think I can get ACTIVATED events.
Any suggestions for things to try so I can give WACOM some good information on this bug? It's really frustrating to not be able to use my pen with Java apps, especially since the pen works fine with "regular" Windows (non-Java) applications.
Normally I wouldn't ask this question here but I'd like to find out from a programmer's standpoint what might be going on so I can file a good bug report.
What you should do is add a mouseListener and see when it registers a mouseClicked(), mousePressed(), mouseReleased() event. I'm not sure if the swing reads the tablet pen as a mouse though. However, it should give you some insight into what's actually going on.
I tried dr.manhattan's suggestion and it works like a charm. I get mousePressed/mouseReleased events correctly; mouseClicked events happen always with the pen tablet mouse, but mouseClicked events do not happen with the pen unless I manage to keep the pen very still. Even a 1-pixel movement is enough to make it fail. I guess I should blame Java for this one: there's no way to specify a "click radius" for acceptible movement.
package com.example.bugs;
import java.awt.Dimension;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JFrame;
public class WacomMouseClickBug {
public static void main(String[] args) {
JFrame jframe = new JFrame();
jframe.addMouseListener(new MouseListener(){
#Override public void mouseClicked(MouseEvent event) {
System.out.println("mouseClicked: "+event);
}
#Override public void mouseEntered(MouseEvent event) {}
#Override public void mouseExited(MouseEvent event) {}
#Override public void mousePressed(MouseEvent event) {
System.out.println("mousePressed: "+event);
}
#Override public void mouseReleased(MouseEvent event) {
System.out.println("mouseReleased: "+event);
}
});
jframe.setPreferredSize(new Dimension(400,400));
jframe.pack();
jframe.setLocationRelativeTo(null);
jframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jframe.setVisible(true);
}
}
I think you already got the answer yourself: Moving the pen results in some other event than a simple click, perhaps maybe a Drag and drop like event.
I'm not sure whether it's a Java/Swing or a Wacom problem, it could be that the tablet doesn't register the clicks as such but as drag events, or it could be that swing interprets the events incorrectly.
I reported this bug many years ago to Sun. It still is not fixed. Any decent ui framework will allow some movement between a press and release to generate a click event. A maximum movement of 1 pixel on a high dpi display is just ridiculous. It is not only an issue with wacom tablets, ie older people also have difficulties to keep the mouse still when clicking.

Categories

Resources