In my app I display a popup using JPopupMenu. I want to run some code when this popup closes (either directly, programmatically or when escape key is pressed). For windows I can attach a WindowListener but JPopupMenu doesn't have any corresponding feature, and SwingUtilities.windowForComponent returns the root window of the app. How do I implement this?
How about adding a PopupMenuListener to it? Something like:
jpopMenu.addPopupMenuListener(new PopupMenuListener
{
public void popupMenuCanceled(PopupMenuEvent popupMenuEvent)
{
//here the code you want to be executed at close
}
public void popupMenuWillBecomeInvisible(PopupMenuEvent popupMenuEvent){}
public void popupMenuWillBecomeVisible(PopupMenuEvent popupMenuEvent) {}
}
This should be automatically executed when you cancel/close the popMenu. I didn't add code to the other two methods, but feel free to play with them if needed.
Related
I'm using JavaFX to build an application. In some windows there's a button whose purpose is to close the current one. Currently I'm using this kind of approach, but I think it's not clean as I would like it to be.
public class AboutController {
#FXML
private Button aboutClose;
public void initialize() {
aboutClose.setOnAction(event ->
((Stage) (aboutClose.getScene().getWindow())).close());
}
}
Is there a better way to implement this task? How to get the stage I'm working on from the Controller without having to take it from the button itself?
I am using JavaFX 2.2 and I have a class which extends Application. Here is my code:
Class A extends Application {
public void Stage(final Stage primaryStage) { ... }
public void Start(){
launch();
}
btnLogin.setOnAction(new EventHandler<ActionEvent>() {
Platform.exit();
}
}
Class B{ }
Class C extends Application{
public void Stage(final Stage primaryStage) { ... }
public void Start(){
launch();
}
}
Actually, Class A is login screen; it will close when I successfully log in. Then the screen closed by platform.exit() function. After that I execute view button in Class B , Class C called but there are some problems.
java.lang.IllegalStateException: Application launch must not be called more than once
I just terminate the screen by using Platform.exit() function but I can't understand why it can't be closed.
Platform.exit() actually terminates whole jfx.
To keep things safe, just invoke launch() once and show/hide new windows.
Something like:
Platform.setImplicitExit(false);//make fx running in backgound.
Platform.runLater/AndWait {//make sure u create window in jfx thread
//window creation/show code here.
}
If Class B is the main screen and you need to Embed JavaFX in your application for Login Screen or any other screen, you don't need Class A and Class C to extend Application.
You can just create a new Window in Swing inside these classes (A and C) and use JFXPanel to embed JavaFX into your Swing Application. This way you can have full control on the application and you can easily open and close windows for Login or any other functionality that you want.
N.B. You should not have two class extending Application inside one app, as only one JavaFX thread is allowed per JVM.
Everytime you try to do this you will get this error
java.lang.IllegalStateException: Application launch must not be called more than once
Does JavaFX contain an equivalent to java.awt.EventQueue? For my application I need to intercept all GUI related events such as mouse and keyboard input, and so far I haven't been able to find a way to do it without attaching listeners to every GUI element.
This isn't quite the same as the question in your title, but to intercept all events, you can add an EventFilter to the Scene:
scene.addEventFilter(Event.ANY, new EventHandler<Event>() {
#Override
public void handle(Event event) {
System.out.println(event);
}
});
If you need to veto the event, call event.consume()
I have an application, where the user can scan a barcode. Therefor I have a textfield, which gets the focus on first load. The application allows further actions for opening dialogs or triggering loading of data.
I need to set the focus to that field every time the user has finished this actions.
Is there any possibiltiy to capture all events on the main stage?
I have tried to add a listener to the focusProperty but this is just triggered on first load and on maximizing the window.
You can add a listener to the FocusedProperty. The following code:
btn.focusedProperty().addListener(new ChangeListener<Boolean>(){
#Override
public void changed(ObservableValue<? extends Boolean> ov, Boolean t, Boolean t1) {
//do something
}
});
works well in my case.
I'm trying to separate function from state in my GUI application by the use of Action objects. I've been successful in using these to create menu items and buttons that have the same functionality.
My problem is this: I want to have the same Action for both the 'exit' item in my menu and the close button of the frame.
Currently I've been able to solve it by adding the following WindowListener to the frame:
private class MainWindowListener extends WindowAdapter {
#Override
public void windowClosing(WindowEvent e) {
new ExitAction(model).actionPerformed(new ActionEvent(e.getSource(), e.getID(), "Exit"));
}
}
Isn't there a simpler more straightforward way to do this?
Forwarding events is handy, but you can also use dispatchEvent(), as shown here.
Addendum: More examples that use Action are shown below.
LinePanel which connects buttons and keys.
ScrollAction which leverages existing Swing actions.
KeyPadPanel which illustrates forwarding actions.
GraphPanel which shows graph editor actions in a tool bar.