So I'm trying to load three specific scenes if some buttons are clicked. It is a simple loading screen that calls three other scenes which has 2 textfields(txtUser,txtPass) and 2 buttons (btnCancel, btnEnter) and 2 selecting buttons (btnStd, btnProf) which loads a fxml separately - a third fxml if both are clicked disabled
The tricky part is in this Enter button which is called after enabled or disabling two other buttons, for students and teachers. This also loads a third if both buttons are pressed: the administrator
#FXML
private void onActionBtnEnter(ActionEvent event) {
try {
if (txtUser.getText() == null || txtUser.getText().isEmpty()) {
new Message().showModal(Alert.AlertType.ERROR, "User validation",
(Stage) btnEntrar.getScene().getWindow(),"Needs username");}
else if (txtPass.getText() == null || txtPass.getText().isEmpty()) {
new Message().showModal(Alert.AlertType.ERROR, "Password validation",
(Stage) btnEntrar.getScene().getWindow(), "Needs password");}
else {
FlowController.getInstance().goMain(); //this is one of the fxlm views to load
((Stage) btnEnter.getScene().getWindow()).close(); //closes the login and loads the scene
}
}
catch (Exception ex) {
Logger.getLogger(LandingViewController.class.getName()).log(Level.SEVERE, "Login error.", ex);
}
}
This works alright but instead of choosing specific fxml to load it only loads goMain() which contains administratorview.fxml. I also did a goMain2() and goMain3().
For students, the studentsview.fxml should load. For profesors the profesorview.fxml. Following code for buttons methods and actions
#FXML
private void onActionBtnStd(ActionEvent event) {
btnStd.setDisable(true);
txtPass.setDisable(false);
txtUser.setDisable(false);
}
#FXML
private void onActionBtnProf(ActionEvent event) {
btnProf.setDisable(true);
txtPass.setDisable(false);
txtUser.setDisable(false);
}
So far good, but loads only a single fxml because they aren't called yet. So I guess in the btnEnter action there should be some code which I tried as in (same event as above):
#FXML
private void onActionBtnEntrar(ActionEvent event) {
else if (btnStd.getValue().isDisabled()){ //added else if but I don't know how to call a boolean property in a void
FlowController.getInstance().goMain();
((Stage) btnEnter.getScene().getWindow()).close();}
else if (btnProf.getValue().isDisabled()){
FlowController.getInstance().goMain2();
((Stage) btnEnter.getScene().getWindow()).close();}
else if (btnProf.getValue().isDisabled() && btnStd.getValue().isDisabled()){
FlowController.getInstance().goMain3();
((Stage) btnEnter.getScene().getWindow()).close();}
Silly me, I added .getValue() in the if statement - all it was needed is to put the component.isDisabled() or .isEnabled() if it holds a boolean. However it doesn't load the adminview if both are checked disabled - it load the studentview. Investigating further...
Edit: Ok the last "else if" must be called first than the other two. It works like a charm.
Related
I wrote a software for handling Pizza Payments as a school project. For this I create a custom row as a Anchorpane. After loading a few Entries from a MySQL DB, the ListView for showing the possible Pizzas to choose is struggling (showing white space above and under the entries, where the other Entries should be displayed but aren't).
If you want to see the main Pane FXML click here, if you want to see the Custom ListCell Anchorpane just click here.
To see the error visually just click here
Because I have no idea how this custom cells are rendered in detail I have no idea where the error is, so I tried nothing to fix it.
//the adding a new Pizza Row method in the WindowController Class for the main window
private void addPizzaRow(Pizza pizza) {
try {
FXMLLoader loader = new FXMLLoader(new File(WindowController.ROW_FXML).toURI().toURL());
pizzenContr = new RowPizzasController();
loader.setController(pizzenContr);
Pane rootPane = loader.load();
// initialize tab controller
pizzenContr.init(pizza);
this.pizzenListview.getItems().add(rootPane);
} catch (IOException e) {
e.printStackTrace();
System.exit(1);
}
}
//the called init() method
public void init(Pizza pizza) {
pizzaImageview.setImage(new Image("Classdependencies/Window/PizzaListViewImg.png"));
//set title and image (icon)
this.pizzaLabel.setText(pizza.getName());
this.kleinButton.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
}
});
After five or 6 Entries white space above and under the entries is showing, where the other Entries should be displayed but aren't.
Looks like the error had something todo with absolute height I gave the cells Panes after I set this to default in Scenebuilder it worked fine again.
like the title implies i've got a problem with my application. The application is supposed to run in fullscreen mode (no intention for switching back to window mode), so i designed a footer-bar holding some images (with a Label, in a VBox) so the user could navigate or exit the program.
So after starting the application all Buttons work just fine with touch. Even the Exit-button in my footer-bar responded correctly by opening my custom Dialog. But here starts my Problem. The Dialog is shown by showAndWait()-Method call, but does not respond to Touch-Events. In contrary mouse-events are still processed (i still can use a mouse to click the Buttons in my Dialog and the Dialog is responding correctly).
I hope someone got an idea what i'm doing wrong.
MyDialog.java:
public static boolean showExitDialog(Window owner, ResourceBundle resources) {
LOGGER.info("Showing exit dialog...");
final Dialog<ButtonType> dialog = new Dialog<ButtonType>();
dialog.getDialogPane().getStylesheets().add(MyDialog.getInstace().getCssPath());
dialog.setContentText(resources.getString("label.exitdialog.text"));
dialog.setHeaderText(resources.getString("label.exitdialog.header"));
dialog.initOwner(owner);
dialog.initStyle(StageStyle.TRANSPARENT);
dialog.initModality(Modality.APPLICATION_MODAL);
dialog.getDialogPane().getButtonTypes().add(new ButtonType(resources.getString("btn.Exitdialog.exit"), ButtonData.OK_DONE););
dialog.getDialogPane().getButtonTypes().add(new ButtonType(resources.getString("btn.Exitdialog.cancel"), ButtonData.FINISH));
Optional<ButtonType> result = dialog.showAndWait();
LOGGER.debug("Result: {}", result.get());
if(result.isPresent() && result.get().getButtonData() == ButtonData.OK_DONE) {
LOGGER.info("Closing exit dialog returning true...");
return true;
} else {
LOGGER.info("Closing exit dialog returning false...");
return false;
}
}
In MainApp.java:
private EventHandler<WindowEvent> confirmCloseEventHandler = event -> {
// close event handling logic.
// consume the event if you wish to cancel the close operation.
if(MyDialog.showExitDialog(primaryStage, rb)) {
event.consume();
System.exit(0);
}
};
...
primaryStage.setOnCloseRequest(confirmCloseEventHandler);
In FooterBar.java:
#FXML
private void exitProgramPressedTouch(TouchEvent event) {
event.consume();
controller.getWindow().fireEvent(new WindowEvent(controller.getWindow(), WindowEvent.WINDOW_CLOSE_REQUEST));
}
*Edit* Oh totally forgot: No Exception or anything else is thrown.
I don't know the reason for the described behavior - maybe a bug. However, you could try to listen for ActionEvent instead of TouchEvent. It handles both touch and mouse events:
#FXML
private void exitProgramPressedTouch(ActionEvent event) {
event.consume();
controller.getWindow().fireEvent(new WindowEvent(controller.getWindow(), WindowEvent.WINDOW_CLOSE_REQUEST));
}
Maybe you need also to change the attribute which binds the event listener (from onTouch to onAction) in your FXML file.
Finally, I think, you could avoid System.exit(0); if you consume the close event only when the cancel button has been clicked:
if(!MyDialog.showExitDialog(primaryStage)) {
event.consume();
}
I have a login form with 2 JTextFields - one "elbtUser" the other "pass" (username and password) and everything works. I want to show a message as shown below if username is left empty and pass is clicked else the button will enable. It works but the message keeps repeating in an endless loop. How to I get back to form break out?
pass.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent arg0) {
if(elbtUser.getText().equals("")) {
JOptionPane.showMessageDialog(null, "username cannot be empty");
}
else {
btnLogin.setEnabled(true);
}
}
});
I can't say for 100% certainty, but I'm guessing after the dialog is closed the text field regains focus and triggers the action listener. If this is the case, try 1 of two things:
1) add a variable to keep state and when the dialog should be shown. Once on focus gained, and then it should be reset when elbtUser gains focus.
2) You can force elbtUser to request focus after dialog is shown, elbtUser.requestFocus();
//edit.. i Just tried (1) as it seemed easier and it works,
pass.addFocusListener(new FocusAdapter() {
#Override
public void focusGained(FocusEvent arg0) {
if(elbtUser.getText().equals("")) {
//do this *BEFORE* displaying the dialog!!!
elbtUser.requestFocus(false);
JOptionPane.showMessageDialog(null, "username cannot be empty");
}
else {
}
}
});
Is this the intended functionality or am I doing something wrong?
All I'm doing is creating a GXT Button and calling setMenu to attach a GXT menu. On first click, the menu shows properly, on second click, the menu disappears on MouseDown, but reappears on MouseUp. The only way to get the menu to hide is to click away from the button.
I confirmed that it isn't anything strange with a particular button in my code by adding another button:
Button button = new Button("test");
Menu menu = new Menu();
button.setMenu(menu);
add(button);
If this is intended, is there a suggestion on how to add a listener to close the menu on second click?
I am guessing that it is working as intended since the menu always hides as soon as it loses focus. What I did below is override the onAutoHide method in the menu to not hide if the button with the specified ID is pressed (change accordingly). This gives me the ability to check if the menu is shown in the onClick method of the button - and then not show it again. Be warned though...I am in no way an expert and this is a hack :)
Button button = new Button("Test") {
#Override
protected void onClick(ComponentEvent ce) {
ce.preventDefault();
focus();
hideToolTip();
if (!disabled) {
ButtonEvent be = new ButtonEvent(this);
if (!fireEvent(Events.BeforeSelect, be)) {
return;
}
if (menu != null) {
if (!menu.isVisible())
showMenu();
else
hideMenu();
}
fireEvent(Events.Select, be);
}
}
};
button.setId("TESTBUTTONID");
Menu menu = new Menu() {
#Override
protected boolean onAutoHide(PreviewEvent pe) {
if (pe.getEventTypeInt() == Event.ONMOUSEDOWN
&& !(pe.within(getElement()) || (fly(pe.getTarget())
.findParent(".x-ignore", -1) != null))
&& !(fly(pe.getTarget()).findParent(".x-btn", -1) != null
&& fly(pe.getTarget()).findParent(".x-btn", -1).getId()
.equalsIgnoreCase("TESTBUTTONID"))) {
MenuEvent me = new MenuEvent(this);
me.setEvent(pe.getEvent());
if (fireEvent(Events.AutoHide, me)) {
hide(true);
return true;
}
}
return false;
}
};
button.setMenu(menu);
RootPanel.get().add(button);
for my app I need the space key to call a function independent from the focused widget, everywhere in the app but only if the according tab is opend. I found that one can add a filter to the display, like this:
getShell().getDisplay().addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event arg0) {
if( arg0.character == 32 ) { /**SPACE*/
if( mainTabs.getSelection().equals(analyseSoundFilesTab)) {
soundController.playButtonClickHandler();
}
}
}
});
That works fine most of the time, but if I give a button the focus via the "tab" or "shift tab", its kinda strange - the space bar will than activate a "button pressed", as if one clicks the button with the mouse. Im a bit stuck now, I don't know how to avoid this...
For the buttons, I have implemented a SelectionListener.
Regards.
You can use TraverseListener and disabled press event detection using doin field. Here is a sample code:
display.addFilter(SWT.KeyDown, new Listener() {
public void handleEvent(Event e) {
if (e.character == 32) {
System.out.printf("Space detected %s\n", e);
}
}
});
Button b1 = new Button(shell, SWT.PUSH);
b1.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent se) {
System.out.printf("Button pressed %s\n", se);
}
});
b1.addTraverseListener(new TraverseListener() {
#Override
public void keyTraversed(TraverseEvent te) {
System.out.printf("Traverse detected %s\n", te);
te.doit = true;
}
});
If addTraverseListener() didn't exist, your space button was detected after filter, so you would see "Space detected..." and after that "Button pressed...". Now that you set te.doit = true, you say to SWT to do space bar traversal (which does nothing actually) instead of firing key listener. You may optionally check te.detail to only prevent mnemonic traversals.
Choosing the 'Space key' is the real problem, because it is a general feature in most (all?) OS's that pressing space is equal to selecting the widget that has focus.
A way out would be using subclassed Button widgets that ignoring Space.
But it would confuse a lot of users, just because they expect that a focussed button is selected when they hit space and do not expect some other action.