dustinkredmond / FXTrayIcon

Tray Icon implementation for JavaFX applications. Say goodbye to using AWT's SystemTray icon, instead use a JavaFX Tray Icon.
MIT License
324 stars 25 forks source link

[Feature Request] Disable default hide/show behavior #30

Closed TornadoStorm closed 2 years ago

TornadoStorm commented 2 years ago

It would be very useful to be able to manually manage all action events relating to the FXTrayIcon, at least relating to how left clicking the icon works.

In my current project I am trying to have a behavior that shows a small popup window when the tray icon is single-clicked, but when double-clicked, the main window should show up. Currently, I only know of being able to use the setOnAction method for this, but it does not seem to override the default behavior of clicking on the FXTrayIcon.

If anyone knows of a workaround to this, I found greatly appreciate it. Otherwise I would like to recommend some kind of system to make such actions easier to manage.

NexRX commented 2 years ago

At the moment, I'm extending FXTrayIcon and getting the TrayIcon itself. Trying to listen to the Action Events and stuff from AWT. It's annoying of course because we like to use JavaFX. But it is doable. If I ever finish my own logic there. I can always bring forward how I did it :)

EasyG0ing1 commented 2 years ago

@TornadoStorm - Yeah the biggest issue with even having a tray icon in JavaFX is that JavaFX has no means of providing one, so it has to be brought in from AWT and the results are ... "klunky" to say the least. Thus far, we simply have to live with the way it behaves now until such a time that SOMEONE creates a native JavaFX tray icon but until then ... we limp along with what we got. Though I am interested in seeing how @Nex-Coder fares in his endeavors to that end ... or rather ... to that goal of making the tray icon bend to our every whim without resistance ... if he pulls that off, we at least owe him a donut ... lol

TornadoStorm commented 2 years ago

Thanks for the info! 😊

I feel like this feature might not be too difficult to implement, as the setOnAction already can handle a lot of things on its own, we just need to be able to disable how it acts by default when it is clicked somehow and put in our own code through that event. Maybe I will have a deeper look at it the next time I can.

EasyG0ing1 commented 2 years ago

@TornadoStorm - something else that is worthy of note ... I'm not sure which OS you're using, but in MacOS, the tray icon does indeed behave differently based on a single left click or a double button click - where you click on it with both the left and right mouse buttons at the same time... if you're in a Mac world, have a look at that as it relates to FXTray Icons setOnAction methods ... I can't remember EXACTLY how the different clicks manifest while the code is running but I do remember that there are two distinctly different things happen in the tray icon - depending on whether you left-click it or you dual button click it.

When I first found FXTray Icon, the main thing I wanted to do, was be able to click on it, and instead of a menu popping up (or popping down in the case of MacOS), was to have a JavaFX scene pop down from the icon in a manner that made it seem that it was attached to the icon. And Dustin and I spent some time trying to figure out how to do that, but we came up with no answers ... but that does not mean that it can't be done ... it just means that we couldn't figure out how to do it. If I know anything about my knowledge in Java, is that what I don't know is FAR GREATER than what I do know ... so don't assume that it's not possible just because we couldn't find a way to do it... ;-)

What I did end up doing, by the way, was configure FXTI with a minimal menu and the top menuitem instantly drops down that narrow scene that I created and it actually works exactly like I wanted it to and is how I envisioned it, only it requires ONE additional click ... which I didn't want, but I've gotten used to it and it doesn't bother me anymore.

Here are a couple of screenshots ... the scene is a scroll pane and in between each divider is a VBox where the data is updated every 30 seconds.

Screen Shot 2021-12-11 at 2 34 45 AM Screen Shot 2021-12-11 at 2 36 41 AM
EasyG0ing1 commented 2 years ago

@TornadoStorm - Also, the way I was able to make it appear like the scene is attached to the icon ... I record the x and y coordinates of the mouse the first time that icon is clicked after the program starts. I then use that point as a reference every time the scene is called up so that it doesn't jump around having different source points each time the icon is clicked .... but using that source point, I subtract half the width of the scene then set the starting point for the scene in terms of where it's X and Y top-left pixel will be planted. I want to say that I set the Y coordinate to be the top edge of the screen minus some number of pixels that I found through trial and error that define the height of the system tray ... the result is more than acceptable ... for this application anyways.

TornadoStorm commented 2 years ago

@EasyG0ing1 That's an interesting implementation! However, the functionality I am trying to investigate more involves double-clicking with the left mouse button, rather than clicking with both the right and the left at the same time. I think the only way I can really work with this is to somehow disable the default behavior when left-clicking the taskbar icon, while leaving all other behavior as normal (right-clicking, clicking with left and right mouse button at the same time etc.). By double-click I mean pressing twice with the left mouse 🙂

EasyG0ing1 commented 2 years ago

@TornadoStorm - yeah ... I do mouse click counting all the time with JavaFX controls ... but when it comes to AWT, I'm in a foreign country. I never once learned nor used AWT. I started learning Java when FX was already the well-established gold standard for Java UIs. If you ever do figure it out, please let us know how you did it?

TornadoStorm commented 2 years ago

@EasyG0ing1 Definitely will! Currently occupied with other tasks at the moment, but I'll definitely look back at the taskbar icon eventually

EasyG0ing1 commented 2 years ago

@TornadoStorm - I was reading the Oracle discussion on AWT TrayIcon, and found this to be of some interest:

The TrayIcon class functionality goes beyond the icon that is displayed in the tray. It also includes a text tooltip, a popup menu, balloon messages, and a set of listeners associated with it. A TrayIcon object generates various mouse events and supports the addition of corresponding listeners to receive notification of these events. The TrayIcon class processes some of the events itself. For example, by default, when a right-click is performed on the tray icon, it displays the specified pop-up menu. When a double-click is performed, the TrayIcon object generates an ActionEvent to launch an application. When the mouse pointer hovers over the tray icon, the tooltip is displayed. The icon image is automatically resized to fit the space allocated for the image on the tray.

However, they also discuss some limitations which might explain some of the frustration we've experienced:

Unfortunately, the current implementation of the TrayIcon class provides limited support of the Swing pop-up menu (the JPopupMenu class) and does not enable an application to use all of the capabilities of the javax.swing package. The workaround proposal for this issue is described in the Bug Database, see Bug ID 6285881.

dustinkredmond commented 2 years ago

Leaving open for now if anyone wants to contribute a fix. It will need to work on (at least) Windows 10/11 and the latest MacOS releases.

I originally shot for this in the initial development, but it appears that the behavior is not consistent across the two operating systems, thus, I didn't want to create methods like setOnLeftClick or setOnRightClick in case these didn't work as intended across OS platforms.

dustinkredmond commented 2 years ago

Gonna close for now, if you have anything further, please open a PR. Thanks!