JavaFX - Keeping Focus on a "Default" Component - javafx

I'm looking for the most concise way to deal with focus in an application which renders a map in a canvas component. You can pan the map location using arrow keys or ASWD keys. So far, I've been giving the canvas focus at startup and handling key pressed events via canvas.setOnKeyPressed().
This works fine, but I've always known that a problem was on the horizon when other components enter the picture. Once you interact with another component, it gains focus, and you're unable to scroll around the canvas map. I can prevent this from happening with some components like Hyperlinks or Buttons (I don't need tab-navigation) with something like this for those components:
sidePanel.getChildren().forEach(node -> node.setFocusTraversable(false));
But, when we get to things like TextArea or TextField, those do need to hold focus while they're being edited. And I'll need some way to return focus back (or at least unfocus those components) without being an annoyance to the user. (I don't want to have to click the canvas for it to regain focus.)
The options I see for returning focus back to the canvas after the user is done with those fields seem to be:
Add a key handler (ex. ESC or ENTER keypress) on EACH of these components which returns focus back to the canvas.
Maybe not so concise, and a bit of a pain... also feels a bit fragile; if I miss something and the canvas loses focus, it would fail - I need a 100% reliable solution.
Extend each of these components and add similar code to return focus back to Canvas
Even nastier and requires using custom components in Scene Builder, which
is not ideal.
Add a global event handler on the Scene and transmit events to the controller which owns the canvas
I believe an event filter would accomplish this - but on the other hand if the user is simply using arrow keys to move around a TextArea, I wouldn't want the Canvas map to move!
To solve the above problem, possibly the global event handler could ignore ASWD and arrow keypresses if the focus is on certain types of components? Is this worth trying, or am I neglecting a problem this would create?
Are there any other simple options out there that I've missed - and what would you suggest as the best option here? I'd like an automatic solution that doesn't require remembering to add some workaround code every time a UI component is added.

Related

JavaFX ComboBox border is wrong if the drop-down drops-"up"

I am using "javafx.scene.control.ComboBox" on Java 8 and I noticed that whenever the combobox does not have room below and instead pops up, the bordering styling of the elements switches as if it still pops down.
How can I access the styling for that to fix it?
Managed to fix this by actually extending the ComboBoxListViewSkin. In there, I've stuck a method that updates the styling, and does that by calling super.getPopup(), gets the AnchorY of that and compares it with the combo-box Y. After determining if the popup is below or above the combo, I set the correct styling on super.getListView...
Also, that method I've added, has to be called from the "ON_SHOWN" event of the combo-box.
I've tried several other variants but the damn thing just yields unstable behavior.

Google VR Reticle Click on UI Button

So I am having this issue with using Google VR reticle where I cannot click a button. I have an image attached showing the heirarchy and the PlayButton is what I am trying to click. The Canvas has a Graphic Raycaster, the button has an Event Trigger that calls the method to navigate to the next scene. The UpScrollPanel, and DownScrollPanel work just fine. The EventSystem has the Gaze Input Module, as well as Event System, and Touch Input Module.
Any ideas on how to get this working? I have watched a few videos from NurFACEGAMES and while they helped a little, I haven't gotten the click to work yet.
Oh, and I am using Unity 5.3.4f
Sometimes things can get in the way of the button, make sure that no other UI elements overlap it, for example text borders (which are actually larger than they appear). You can also fix this by moving the button up the hierarchy among its siblings, I believe the first child is top.
Also try moving the button up the hierarchy if possible, sometimes UI having certain parents makes them not work
The canvas object should have a graphic raycaster
I found the issue to be unrelated to anything I thought it was. The menu I was using is a prefab I also use in another view that isn't VR. The scrollrect was loading that prefab, instead of the modified one I was using in the VR menu, and therefore the triggers I had added to the button were no being used when the app loaded.

QGraphicsScene: How to prevent keyboard events from reaching the main window while dragging items, for example?

I'm implementing a basic shape drawing tool using a custom subclass of Qt's QGraphicsScene and several QGraphicsItem. Now there are several situations where I don't want any "global" actions to be executed:
For example, while dragging items around, the user should not be allowed to create a new file or to undo the last action (by pressing Ctrl-Z for example) since this would lead to several problems that would have to be handled separately (if the user is currently drawing an edge between two nodes, what should happen if he presses Ctrl-Z with the last recorded action being the creation of the first node?)
I noticed that several commercial applications like Microsoft Word and Adobe Photoshop just seem to ignore any usual keyboard shortcuts while being in such an "intermediate" state. Furthermore, when dragging items out of the viewport, these tools display a "forbidden" cursor and do not allow any mouse press events to reach the outer window (like a right click on the toolbar, for example).
How should I implement this in my case, when using QGraphicsScene? I already tried to add the following override:
void MyGraphicsScene::keyPressEvent(QKeyEvent* keyEvent)
{
keyEvent->accept();
}
But any pressed keys were still delivered to the main window. In addition to that, I'm not sure if filtering just keyboard events is safe enough, since there might be other input events that could trigger forbidden actions.
Is there any generic approach to this problem that I could use in my software?

Should I use Button or TextBlock?

I have two options. I need 48 of a certain type control; it needs to respond to clicks and taps (for touch devices).
I could use Buttons, using the TextButtonStyle, and the Click event. Or I could use TextBlock, with the Tapped event.
I reckon buttons may be more "expensive" to create. OTOH, although I believe "Tapped" is also called when the user clicks the component, this makes me a little nervous due to its nomenclature, I guess.
Another difference is that a button takes up only the width necessary, whereas a TextBlock takes everything; and I want the underlying Grid to be tappable, so the TextBlock is kind of a problem that way. Is there a property that will make it more modest like the button?
There is design guidance for Windows Store apps on when and how to use buttons at http://msdn.microsoft.com/en-US/library/windows/apps/hh465470. Based on your description and this guidance, it sounds like buttons are the way to go. Responding to click events is what they were made for, and TextBlocks add the extra issues that you describe.

Best way to do loaders in a flex application?

What is the best way to do a loader in a flex application? I have an animated .gif that is to be used as our loader (whenever I need to wait for an action to complete), and I am not sure the best way to do it.
This is how I am thinking:
Have the loader be a custom component.
On the parent application, add an event listener for my custom event AceEvent.SHOW_LOADER.
In the event listener, use the PopUpManager to show the loader.
Listen for AceEvent.HIDE_LOADER.
Get rid fo the loader via PopUpManager.
What do you think about this? Is there a better way to do it?
Thanks!
Andrew
Well, last I checked, animated gifs don't work in Flex unless you have a workaround. Still, I wouldn't use an animated gif to create an animation because of their low quality. I would just recreate it using Flash.
The way I would do the loader however would be very different. personally, I don't believe in 'system loaders' unless it's your application's preloader. The reason for this is that there could be more than one thing loading at the same time (which might not know about each other) which means that the loader popup could disappear before everything is loaded (first one loads, dispatches event and removes popup, while the other is still loading).
What I like to do is create a custom component for the popup loader (since it will be reused quite a bit) and from there I can either use states the are appropriate for my view or have a boolean flag binded to show the popup when true (this can easily be done using frameworks like Parsley). The popup would only cover the part of the system that's actually loading data (since I doubt that your whole app is loading data at the same time) which makes for a better UX.
I ended up using as3gif (until I can get this recreated as a .swf). The way I do this is by using my custom event class (AceEvent.SHOW_LOADER and AceEvent.HIDE_LOADER), which bubbles up to the top. I then use the PopUpManager to add/remove this with modal to disable the application.

Resources