I'm facing an issue with JavaFX 8u40 where creating two or more modal windows will cause a system beep on Mac OS X when closing the children windows.
The example below creates a modal window who's a child of another modal window. When I close the child modal window, my system beeps (the same way it beeps if I try to click on the parent modal window).
The problem seems related to stage.initOwner(...) where closing the child modal window tries to access the parent modal window before the showAndWait() loop is finished.
I just want to confirm I'm not doing anything wrong before filing a bug report.
public class TestDialog extends Application {
public static void main(String[] args) {
launch(args);
}
#Override
public void start(Stage stage) {
Button showModalButton = new Button("Show Modal Window");
showModalButton.setOnAction(e -> {
Stage modalStage = new Stage();
modalStage.initModality(Modality.WINDOW_MODAL);
modalStage.initOwner(stage);
Button createInnerModalButton = new Button("Create inner modal window");
createInnerModalButton.setOnAction(e2 -> {
Stage innerModalStage = new Stage();
innerModalStage.initModality(Modality.WINDOW_MODAL);
innerModalStage.initOwner(modalStage);
Button closeInnerModalButton = new Button("Close");
closeInnerModalButton.setOnAction(e3 -> {
innerModalStage.close();
});
VBox innerVBox = new VBox(
new Label("This is an inner modal window"), closeInnerModalButton);
innerModalStage.setScene(new Scene(innerVBox));
innerModalStage.showAndWait();
});
VBox vBox = new VBox(
new Label("This is a modal window"), createInnerModalButton);
modalStage.setScene(new Scene(vBox));
modalStage.showAndWait();
});
stage.setScene(new Scene(showModalButton));
stage.show();
}
}
Related
I have two .fxml and two Controller.
At first, the Guest Information (blue) is shown and whenever the "Add" button is clicked, then it will pop up another stage (grey/white) to search for a Guest with ICnumber.
My plan when I done searching for a Guest(grey), I will click the "Add Guest" button, the stage(grey) will close and all the value will be passed to the Guest Information (blue).
#FXML //Guest Information (blue stage)
void addGuest(ActionEvent event) throws IOException {
iclb.setText("ok"); //ignore this
Parent root = FXMLLoader.load(getClass().getResource("Guest.fxml"));
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.setTitle("Hotel System - Guest Information");
stage.setResizable(false);
stage.show();
}
public void addGuestInfo(String icno) {
iclb.setText(icno); // this is the label for IC Number
}
--
#FXML //Search Guest (grey stage)
void addGuest(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("MenuDraft.fxml"));
Parent root = loader.load();
MenuController menu = loader.getController();
menu.addGuestInfo(ictf.getText());
Stage stage = (Stage) addbt.getScene().getWindow();
stage.close();
}
So far I manage to search a Guest and able to close the grey stage by clicing the "Add Guest" button, but those value didn't pass to the Guest Information (blue stage).
Im very new in using Javafx... anyone can give me a hand on this?
In your second ("grey") controller you can do this:
public class AddGuestController {
// I assume you have a Guest class to encapsulate the data in the form
private Guest guest = null ;
public Guest getGuest() {
return guest ;
}
#FXML
private void addGuest(ActionEvent event) {
guest = new Guest( /* data from form controls... */ );
addbt.getScene().getWindow().hide();
}
}
Then back in the first ("blue") controller, you can use stage.showAndWait() to block execution until the window closes, and check if a guest was created:
#FXML //Guest Information (blue stage)
private void addGuest(ActionEvent event) throws IOException {
FXMLLoader loader = new FXMLLoader(getClass().getResource("Guest.fxml"));
Parent root = loader.load();
Scene scene = new Scene(root);
Stage stage = new Stage();
stage.setScene(scene);
stage.setTitle("Hotel System - Guest Information");
stage.setResizable(false);
stage.showAndWait();
AddGuestController controller = loader.getController();
Guest guest = controller.getGuest();
if (guest != null) {
// update view from guest:
iclb.setText(guest.getIcNumber();
// etc.
}
}
I am developing an Eclipse plugin and I need to store the click location in X and Y axis coordinates.
So far, I am doing this by using the org.eclipse.ui.IStartup interface and using this in the class implementing it:
#Override
public void earlyStartup() {
IWorkbench wb = PlatformUI.getWorkbench();
wb.addWindowListener(generateWindowListener());
}
And the in the given method I do this:
private IWindowListener generateWindowListener()
{
return new IWindowListener() {
private MouseListener clickMouseListener = new ClickMouseListener();
#Override
public void windowOpened(IWorkbenchWindow window) {
//Nothing
}
#Override
public void windowDeactivated(IWorkbenchWindow window) {
System.out.println("deactivaed");
IWorkbenchPage activePage = window.getActivePage();
activePage.getActiveEditor().getAdapter(org.eclipse.swt.widgets.Control.class).addMouseListener(clickMouseListener);
}
#Override
public void windowClosed(IWorkbenchWindow window) {
//Nothing
}
#Override
public void windowActivated(IWorkbenchWindow window) {
System.out.println("activated");
IWorkbenchPage activePage = window.getActivePage();
activePage.getActiveEditor().getAdapter(org.eclipse.swt.widgets.Control.class).addMouseListener(clickMouseListener);
}
};
}
So I basically register a listener to the general workbench with the intent to register a new MouseListener - where I save the coordinates - on newly opened editors.
This, however, works only if the entire eclipse window is minimized/maximized, as this listener is bound to the main window. If a new editor is opened, nothing happens (as it probably should work).
I would like to register new MouseListeners everytime a new editor is opened/activated/clicked on - so I can register them to the editor right when a new editor is opened. How can I subscribe/listen to any events related to editors (mostly activated/open new editor) so I can then subscribe a MouseListener to the editor and get current X and Y axis of the mouse-clicks?
Thank for any suggestions.
Use an IPartListener to listen to part events in a workbench window:
IPartService partService = window.getPartService();
partService.addPartListener(listener);
This will tell you about all editors (and views) being opened, closed, activiated, ....
In the early startup method the workbench window is not yet available. Use Display.asyncExec to delay running your code until the UI initialization is complete:
Display.getDefault().asyncExec(new Runnable() {
#Override
public void run() {
IPartService service = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getPartService();
......
}
});
I am making a JavaFX app. I have create a Menuitem About. Upon clicking on the About Menuitem it will display a new window with some info about my app. The window is a Anchor Pane with custom close button. I have set the stage undercoated at run time. I want to close this window without closing my main application. I don't want to set its visibility turn off on method call. I see some solution in net like Window existingWindow = ((Node) event.getSource()).getScene().getWindow(); but i can't use this as am getting error similar to this Menu item not cast node javafx scene. How can I achieve this goal?
Actually this is not my own answer, but I managed to understand #James_D. I usually create to manage open windows, otherwise I have to write a lot of code And this is solution code.
In your controller class:
#FXML
void openAnotherWindow(ActionEvent actionEvent) {
try {
OpenWindow.openWindowMenuItem(someLabel, "views/some.fxml", "Title", 600, 400,
false, "resources/pictures/some_icon.png");
} catch (IOException e) {
e.printStackTrace();
}
}
And OpenWindow class
public class OpenWindow {
public static void openWindowMenuItem(Node label, String recource, String title,
int width, int height, boolean resizeable, String icon) throws IOException {
Parent root = FXMLLoader.load(Objects.requireNonNull(OpenWindow.class.getClassLoader().getResource(recource)));
Stage stage = new Stage();
Scene scene = new Scene(root, width, height);
if (icon != null) {
stage.getIcons().add(new Image(icon));
}
stage.setTitle(title);
stage.setResizable(resizeable);
stage.setScene(scene);
stage.show();
// close current window
label.getScene().getWindow().hide(); // this is key point
}
}
You can do it event without extra class. Hope it will help and again thanks to #James_D
I'm trying to add new widgets on an RPC view by clicking on an existing button. The code that I'm using is the following:
public void createPartControl(final Composite parent) {
parent.setLayout(new RowLayout(SWT.HORIZONTAL));
Button btnNewButton = new Button(parent, SWT.NONE);
btnNewButton.setText("New Button");
btnNewButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseDown(MouseEvent e) {
Button b=new Button(parent,SWT.BUTTON1);
b.setText("asdasd");
}
});
}
The buttons are getting added on the view but are not visible. If I resize the view then they become visible. Why is this happening and how can it be solved?
I need somehow to refresh the view or call the event that the resize action calls.
The attached code works without problems in standard java applications.
Thank you,
Nick
Call the layout method of your parent Composite when you add a widget:
btnNewButton.addMouseListener(new MouseAdapter() {
#Override
public void mouseDown(MouseEvent e) {
Button b=new Button(parent,SWT.BUTTON1);
b.setText("asdasd");
parent.layout();
}
});
I am trying to focus on a particular list view in a tree, I am using the following code
this.txtListName.setCursorPos(this.txtListName.getText().length());
this.txtListName.setFocus(true);
The text view has the cursor blinking inside it but when I type a key nothing happens, I have to select the text view again before being able to type.
Why is this happening.
SOLVED
The setting the the focus was done inside a for loop that looped over and created the Tree Items, when I removed it from the for loop it worked.
Could it be that something in your current call stack is taking the focus away after you set it. You could try setting the focus in a timeout:
(new Timer() {
#Override
public void run() {
txtListName.setFocus(true);
}
}).schedule(0);
I've tried to recreate your problem but the following snippet works for me:
public void onModuleLoad() {
Tree tree = new Tree();
final TextBox box = new TextBox();
box.setText("some content");
tree.add(box);
Button btn = new Button("set focus");
btn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
box.setCursorPos(box.getText().length());
box.setFocus(true);
}
});
RootPanel.get().add(tree);
RootPanel.get().add(btn);
}
Isn't that what you're trying to achieve?