JavaFX how to check if mouse click triggered Tab selection - javafx

I have a tab pane that contains a bunch of tabs (obviously). Normally you can set a listener to each tab by calling setOnSelectionChanged() on the Tab. However, if the TabPane is being reorganized in some way, the tab pane automatically selects the first tab in the list. This is causing some performance issues for me so I would like to know if there is a way to know if a Mouse Click caused the Tab to be selected. Apparently tabs cannot have onMouseClick() listeners.

Whilst the solution to the answer wasn't found since tabs aren't actually nodes and don't have mouse click listeners, the performance issues were solved.
When changing tabs, I was (lazily) recreating the entire view and applying the model to the view. This caused a delay of approximately 140ms or more every time the tab changed. It was a bigger issue when implementing a search box to find the correct tab because as the tabs were being recreated from the search, the views were being recreating as the selection of the tabs changed (Tab pane automatically selects the first tab when adding new tabs).
Ultimately the design was changed to having the controller create the view once, and simply hooking the model to the view as the tab changed instead of recreating the view over and over.
I highly recommend looking at this post if your having performance issues and are relatively new to MVC/JavaFX programming:
Scene loads too slow
Currently changing tabs take approximately 15ms which is a significant improvement!

Related

Tooltip becomes broken after editing value in the grid's cell - ExtJS6

We have encountered a subtle issue with ExtJS grid.
It is quite regular grid with standard 'cell editor' plugin and two editable columns (having at least two is important).
Once an editable cell is submitted, the store backing the grid gets reloaded.
However grid reload takes place in a subsequent time slot because it's a part of asynchrouous task completion.
All this works well unless the user submits editable cell with the Tab key rather than with Enter. Tab makes second column's cell editor visible and shifts input focus there. After that the store reloads, or at least I believe it happens afterwards.
At first glance nothing bad happens to the UI, it continues working as usual. However after some time an attempt to hover the mouse over any element to which a tooltip is attached causes crash and console gets flooded with errors.
We've been able to establish immediate reason of this: garbage collection cycle that follows grid reload treats the input field belonging to the second column's editor as garbage. As a result Ext.Element instance wrapping this field has its dom property erased. By itself it's seemingly not an issue. However, for some reason, when it comes to show a tooltip, the system tries to get its hands on the Element that was previously garbage collected. Strangely enough, that element has nothing to do with tooltips.
In order to reproduce this open the fiddle and then
Double-click any cell in the first column to make it editable
Type any value
Press Tab on the keyboard
Wait 30 seconds
Move and hover the mouse over the grid cells to view tooltips
It does not need to be a grid tooltip, the bug equally occurs even if the mouse hovering over any unrelated UI element with tooltips.
So the question is: how can it be that garbage-collected element is reused, and how to correct this?

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.

Drop dialog on a list page not disappearing automatically

When I add a drop-dialog to a list page, the drop dialog drops down when I click on it, but does not disappear when I click somewhere else.
I am trying to add my own drop-dialog, but I can reproduce this issue with standard Dynamics AX objects. I guess I am just missing some property on an object, but I just cannot figure out which one.
If you want to reproduce my problem in order to solve it, do the following:
Create a new Form. (Form 1)
Change the FormTemplate property to ListPage (Click on Yes)
Add the query MainAccountListPage to the DataSources
Create an ActionPanTab.
Add a Drop-dialog button with the menu item MainAccountListPageBalanceParameters.
Save and open the new List page by right clicking and choosing open. (or open the menu item)
In my case, when I click on Parameters, the drop dialog drops down. When I then click outside the drop-dialog, it disappears as it should.
Create a new display menu item. Set the object to the new list page (Form 1)
Drag the Menu item to any menu. I added mine to General ledger (Common)
Restore, open new workspace. Click on the new menu item in the general ledger menu.
Click on “parameters” and click outside the drop dialog.
When I do this the drop dialog does not disappear again. You can see this same drop dialog working fine on the Main Accounts list page. I have tried changing properties on both menu items, on the menu, on the form etc. I have tried different drop dialogs and different list pages. It always works on the details page and when opened from the AOT.
Am I missing a property? Is the entire way I am adding the drop dialog wrong?
The answer to the above example is.. add the MainAccountDetailPart Form part to the list page's (Form1) Parts.
With my other example, EcoResProductPerCompanyListPage, I had to add the EcoResProductVariantsPerCompanyFactBox to Parts.
I have no idea why this is, but adding a part to a list page fixes the drop dialogs. For example, adding MainAccountDetailPart Form part to a new list page not only fixes the MainAccountListPageBalanceParameters in my example, but it also fixes any other drop dialog that previously did not want to close. Removing the part the breaks all the drop dialogs in the list page again.
Thanks, FH-Inway, for the suggestion, I would have never have found the answer without your method. The solution really surprised me!

QMdiArea: First tab works fine, second tab's content is way too small

Situation: As the central widget of my application I have a QMdiArea in tabbed mode (wrapped in a custom class that inherited from QMdiArea). When I now add the first QMdiSubWindow via addSubWindow() everything is still fine, meaning the window and its contents are maximized to take up all the space of the QMdiArea. However, as soon as I add a second sub window, the following problem arises:
Problem: The content of the second window is not displayed, but instead the content from the first continues to (despite the fact that the second tab visually has the focus), but is reduced in size. It only takes up a few pixels. But if I now switch back to the first sub window/tab (either by clicking into the size-reduced widget which then automatically goes back to max size or by selecting the first tab header) and then selecting the 2nd again, all is fine = the widget/editor of the 2nd tab is now displayed and is maximized.
But only until I close the second tab, in which case the content from the first is displayed (as expected), but again only in the small size!
Screenshot:
Another related test case: 1st tab is created and is displayed full size as expected. If I now simply resize the overall QMainWindow, suddenly a faint border appears around the widget in my tab. So it appears to be in a mixed state between maximized and normal mode with borders. Does that create any new leads?
Screenshot:
I am so far not using any explicitly defined layouts, but given that the first tab works fine and after manual back-and-forth switching all others as well, I assume that it should work without.
Do I need to set explicit layout objects? Why does it work for the first tab, but not the second?
Some code as a base: This is the logic executed in my custom QMdiArea class that takes care of adding the new children:
// Note: pEditor inherits from / is a QMdiSubWindow itself
if(!pEditor->isInitialized())
{
pEditor->initialize();
pEditor->setWidget(pEditor->getEditorWidget());
pEditor->setInitialized(true);
}
pEditor->beforeDisplay();
addSubWindow(pEditor);
pEditor->showMaximized();
// HACK START
pExisting = subWindowList().at(0);
if(pExisting)
setActiveSubWindow(pExisting);
// HACK END
Update: Added the hack proposed by N1ghtLight. Marked as such in the coding.
Update 2: Edited / correct problem description + new test-case with screenshot.
After many hours of comparing the example project from N1ightLight to my own implementation, I finally came across the central differences. There were in fact two issues at play:
For some reason I had the following line in the creation of my MDI sub windows, which apparently screwed up the size handling. Getting rid of this line removed any need for the previously proposed hack. Combined with the layouting proposed by N1ghtLight, all size changes are now handled gracefully.
setWindowState(Qt::WindowMaximized); // do not use that state!
The second part regarding the tab closing (closing one tab did not bring up the next tab in the expected manner and size), is actually explained in the Qt documentation:
When you create your own subwindow, you must set the Qt::WA_DeleteOnClose widget attribute if you want the window to be deleted when closed in the MDI area. If not, the window will be hidden and the MDI area will not activate the next subwindow.
Since I was creating my own sub windows I had to set that flag, but I never did because I wanted to prevent Qt from automatically deleting my content widget as well. My solution now is that I set the flag, but whenever a MDI child is about to be closed, I remove the link to the widget, so Qt cannot delete it.
void CustomMDIWindow::closeEvent(QCloseEvent* pEvent)
{
setWidget(0);
pEvent->accept();
}
I will mark my own answer as the correct one, but will award the bounty to N1ightLight since his support eventually led to me finding the final solution.
The ugly workaround really can be the calling of setActiveSubWindow() twice: First for some available sub window and then for the newly created one. This should emulate the situation when you click on the first tab and then return to the second one.

Flex Spark tabbar : initialize hidden tabs

problem is I have a spark Tabbar, with many forms in each tab.
But I have a single global save button. Problem is, if I don't open a Tab,
it doesn't get initialized and therefore the forms it contains do not exist..
How Can I make it as if the user had clicked on every tab?
The best way to handle this is to have a data model that each tab is displaying and editing, rather than trying to go in and read the values out of the controls in each tab, and save those. This is at the heart of MVC.
However, if you're too invested in your current architecture to be able to change it and you are using a ViewStack with your TabBar, you may find that setting creationPolicy to "all" does what you want. If you're using States, I don't think you can force all of them to be instantiated without putting your application into each State at least once.

Resources