Context menu on Pane that disappears correctly - java

I am trying to have a JavaFX Pane (VBox in my case, but I don't think it matters) that has a ContextMenu that behaves correctly.
I have found these two questions: why Panes can't have ContextMenus and How to create ContextMenu within a Pane.
The problem I'm having with these two solutions (which are very similar) is that while the context menu correctly disappears if I click on the pane, it doesn't disappear if I click inside a control within that pane. The simplest way to observe this flaw is to create such a pane with a TextField. Right-click on the pane to show the context menu, then click inside to TextField to focus on it. While a proper context menu would disappear at this point, this "hacked-in" context menu (for lack of a better term) happily stays in it's place, possibly blocking the user's view of the text field they are trying to fill.
Now, I know I can add a change listener to the focused property of each and every control on my pane, but that feels redundant. Is there a better way to make sure the context menu is hidden when a control in my pane is selected (or, more accurately - when the user click the mouse anywhere in the owning window outside the context menu)?
What I tried so far and doesn't work -
Adding a change listener to the pane's focused property - it appears the pane isn't considered focused if one of it's children is
Adding a change listener to the context menu's focused property - it appears the context menu's focus isn't changed when clicking outside of it.

Ok, so after some digging in the source code for JavaFX I have found this workaround (which is what "solves" this problem for normal controls). Simply add this line of code -
contextMenu.setImpl_showRelativeToWindow(true);
Now, I know using internal implementation methods is discouraged as they may disappear, but this is the only solution I have found. If anyone has a better solution I'll be glad to hear it, but I suspect this is simply a bug that should be filed (i.e. - there should be a way to use the showRelativeToWindow mechanism when setting context menus on panes).
I guess a somewhat safer solution would be to have a throwaway control (not in the scene graph) on which to set the context menu, but I don't know if this would have any unwanted side effects:
Label throwaway = new Label(); // No special reason for using Label, could be any Control.
throwaway.setContextMenu(contextMenu); // note that this is the only place `throwaway` is used, it is never added to the scene graph
// or referenced again, but just setting the context menu on a control solves the problem.
Edit
After digging some more I have found this, and a solution in the discussion - you should call the show method overload which takes a window, not a node! Not very clear, but it works:
myPane.setOnContextMenuRequested(event ->
contextMenu.show(myPane.getScene().getWindow(), event.getScreenX(), event.getScreenY())
);

Related

How to add close button to all tabs but one in JavaFX?

I am trying to create a tab system, with similar function to tabs in Chrome, where there is a cross on each tab to close it, like this:
With JavaFX, I can get close, by setting the tabpane closing policy to ALL_TABS. Unfortunately this means my new tab button (also a tab iself) can be closed:
I am aware of the SELECTED_TAB rule, which would fix this problem, but this would defeat the purpose. I am not aware of any other closing policy that would allow exceptions to the ALL_TABS rule.
I tried adding my own cross to each tab individually using the setGraphic method for the Tab class, however I couldn't figure out how to handle that mouse click event such that it closed the correct tab.
I realise I could also make the new tab button something other than a tab, but I wouldn't really know how to integrate that with the tab pane.
So, is there a simpler method that I'm not seeing? If not, then how can I achieve this kind of tabbing system in JavaFX?
plusTab.setClosable(false);
I did a simple skim of the documentation. Will this work?

Setting a JTextfield focused from start

Making a project for school that involves scanning something from my "start frame" that looks like this --> http://i.gyazo.com/21ed444ad98b441e95c69901eceaef00.png
the textfield in the left bottom corner is where your scanned ID goes. to make it look cleaner i want to set it focused from start and then invisible. (does this even work?) so you can just scan without seeing numbers appear on the screen.
But setting the focus does not work for me. I've tried all these methodes
txtKlantID.grabFocus();
txtKlantID.requestFocus();
txtKlantID.requestFocusInWindow();
txtKlantID being the name of the textfield.
thanks in advance
i want to set it focused from start... But setting the focus does not work for me. I've tried all these methods
The proper method to use is the requestFocusInWindow() method. However, you can't request focus on a component unless the component is displayed in a visible GUI. So the basic code must be structured like:
frame.pack();
frame.setVisible(true);
component.requestFocusInWindow();
It may not always be possible to structure your code that way and you want a component to request focus when it is created. In this case you can add an AncestorListener to the component so that it will request focus when it is displayed. Check out the RequestFocusListener for code that does this for you.

Javafx popup won't hide behind other application upon losing focus

So my question, as stated (sort of) in the title, is about the behaviour in some respects of the Javafx (namely 2.2) Popup. Most of the time, you get a popup, and you give it a window to act as it's parent, you give it some scene, and it tends to act relatively independently.
This is all fine, however, in my case, I needed a popup that would anchor itself to a particular stage (window), at a particular location, when an event happened. That popup would then, in turn, disappear when the window disappeared (minimize, off screen, whatever), moved when it would, and in all essence and functionality, be a physical extension of the window, just with a custom shape.
Now of course, there are a lot of nuances with that, and everything for the most part, works great. The only thing I can't seem to figure out is that normally in a platform like Windows 7 64 bit, say. You open two programs, alright. Then if the programs are overlapping a little bit, whichever has focus gets to have the entire program displayed, whereas the other one gives the impression of being 'behind' the other window. (Whether or not windows actually renders application graphics 'behind' a window when another has focus on the same spot, I'm not sure.). Normally, javafx also supports this functionality just fine. But for some reason, The Popup class in javafx (see docs here) doesn't do that. It's always on top of whatever it's displayed with, without exception. For the point of completeness, here's my pretty straightforward popup code (at least the part pertaining to showing it and it's properties):
Popup myPop = new Popup();
//************************Popup Property Setter**************************
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
myPop.setWidth(width);
myPop.setHeight(initialHeight);
myPop.setAutoHide(false);
myPop.setAutoFix(false);
myPop.setHideOnEscape(false);
myPop.setX(xLocation);
myPop.setY(yLocation);
//&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&
//**********************end of Popup Properties**************************
myPop.getContent().add(main_anchor);
myPop.show(FileChooserWindow.get_stage());
main anchor has some various components i include inside of the 'myPop' popup, and FileChooserWindow is a non-null parent window that will be open at the time of this method calling without exception.
Here is a screenshot as well of the behaviour I'm referring to. Notice the highlighted text in the pdf, that is where my cursor currently has focus. Also, the window that the popup is anchored to can be seen in the back of the pdf poking out from the left.
Any help you guys can give would be much appreciated. I really hope I don't have to check for active processes and their location relative to the popup, that's getting dangerously close to my knowledge border, and sounds like a total PITA.
So, after toying with this for a few more days, I have a rough workaround, although it is a hack in the full meaning of the term.
Although the popup behaviour is still mystifying me, I can simulate a fix in this behaviour by adding a changeListener to the stage to which it is attached (since I didn't want the popup to close if it's parent window had focus, only if anything BUT the popup and it's parent got focus).
See code as follows:
FileChooserWindow.get_stage().focusedProperty().addListener(new ChangeListener<Boolean>(){
#Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean oldValue, Boolean newValue) {
if (!newValue){
if(AutogenPopup.popupReturner().focusedProperty().get()){
AutogenPopup.popupReturner().hide();
}
}else{
if(FileChooserController.refreshAutoPopup && FileChooserController.autoGen_flag){
AutogenPopup.popupReturner().show(FileChooserWindow.get_stage());
}
}
}
});
never mind some of those flags that I'm checking against, they are simply some internal tools to make sure that the popup only appears when the program is in the proper state.
Now, one interesting thing to note. The AutogenPopup.popupReturner().focusedProperty().get()
Seemed to be returning true when the popup's parent window LOST focus. Which is quite counter-intuitive to me, and in my opinion, is even a touch buggy. Now, this does not simulate the behaviour of a modern operating system where a window can slide in and out of focus incrementally, since the popup will just completely disappear upon it's parent window losing focus. But seeing as how my popup just displays additional text entry on the side of the main window, this is an acceptable compromise until I think of a better solution. (Perhaps the better solution is not to use a popup at all, and instead skin a window to act in a popup-y fashion).
Anyway, I hope this helps someone, maybe eventually there will be a more fine-grained way to control this popup functionality.

Program with split screen, how can I change the content [Java]

I had just a few class of java on college, but I want to do a thing that I don't know how.
Is basically a window with a SplitPane, on Left side I have a menu made with toggle buttons, and on the Right side I need to change the content based on each button.
Theres any way to design the ViewA and ViewB on separated JFrame Form and load then inside my Right Side when I click on menu items?
Another idea is, put the ViewA and ViewB put a JTabbedPane on the Right Side, and hide the Tabs. So there's any way to hide the tabs?
I have none experience developing in java, any problem about this concept (difficult, loading time, memory, maintenance), If you guy know a better way to to this, I just don't want a lot of windows popping up.
A really simply way would be to simply have a set of jPanels in the right side, with only one ever set to Visible.
Basically, for each toggle on the left side, you will have an Event Listener that does this:
private void toggle1ActionPerformed(java.awt.event.ActionEvent evt) {
jPanel1.setVisible(false);
jPanel2.setVisible(false);
jPanel3.setVisible(true);
}
Simply changing the true value depending on the individual toggle.
In Netbeans, if using the GUI editor, you can simply double click the toggle button to generate the listener and appropriate method, then fill in the code for it.

Custom Java Window Title Bar Menu

I'm trying to allow the user to change the title of a window in Java without adding components to the window itself. I'm actually trying this with a JInternalFrame, but figure the solution should be similar for a JFrame. I simply want to add an additional menu item in the context menu that pops up when right clicking on a window title bar. For example, the Set title below:
This example is on Windows XP, but perhaps there's a way to get the window context menu OS independently perhaps similar to the SystemTray.getSystemTray() (but for individual windows within an application). From this I would be able to provide my own ActionListener to popup a dialog for the user to enter a new title.
Is this a much bigger task than I'm guessing it is? Does anyone have solutions they've used before?
Short answer: I don't think this is easy. I'm not 100% sure if it is possible.
First, JFrame and JInternalFrame are actually quite different. JFrame is a top level component whose title bar and such are typically provided by the OS. JInternalFrame's entire content (including title bar) is provided by the Swing LAF.
For a JInternalFrame, the context menu is provided by the LAF, not JInternalFrame itself. You would have to do something with the UIComponent in order to change the context menu. I think you would likely have to provide a custom UI component in order to do this, which is ugly and typically breaks across different LAFs or works but looks terrible at best. See BasicInternalFrameTitlePane, the createSystemMenu method.
I don't think this is possible without digging way too deep into Swing's internal UI system and I wouldn't even consider doing this. Why don't you use the inbuilt JMenuBar of JInternalFrame?
myInternalFrame.setJMenuBar(myMenuBar);

Categories

Resources