User can't navigate if dialogue is open - popup

If dialogue open and user wants to open another screen or anything they needs to close the dialogue first and then navigate, otherwise they can't.
I am having javafx dialogue working but I am unable to figured out how to restrict user not navigate anywhere else without closing current dialogue.
Code:
final TextField templateTexBox = new TextField();
final Label templateNameLabel = new Label("Template Name");
final Label templateType = new Label("Type of Template");
final CheckBox cb = new CheckBox("Set as Default Template");
final ComboBox comboBox = new ComboBox();
comboBox.getItems().addAll("Private", "Public");
comboBox.setPromptText("Select Template Type");
if (getViewModel().selectedTemplate().get() != null) {
templateTexBox.setText(getViewModel().selectedTemplate().get().getPreference().getName());
cb.setSelected(getViewModel().selectedTemplate().get().getDefaultTemplate());
comboBox.setValue(getViewModel().selectedTemplate().get().getTemplateType());
}
final Stage stage = new Stage();
stage.initModality(Modality.WINDOW_MODAL);
final Dialog dlg = new Dialog(stage, "Save Template");
dlg.getStyleClass().add(Dialog.STYLE_CLASS_CROSS_PLATFORM);
dlg.setResizable(false);
dlg.setIconifiable(false);
templateNameLabel.setWrapText(true);
templateType.setWrapText(true);
templateNameLabel.setPrefWidth(130.0);
templateType.setPrefWidth(130.0);
templateTexBox.setPromptText("Enter Text");
templateTexBox.focusedProperty().addListener(new ChangeListener<Boolean>(){
#Override
public void changed(ObservableValue observable, Boolean oldValue, Boolean newValue) {
if(!newValue){
Optional<TemplatePreferences> templateOptional = getViewModel().getAllTemplates().stream().filter(template ->template.getPreference().getName().equalsIgnoreCase(templateTexBox.getText())).findAny();
if(!templateOptional.isPresent()){
cb.setSelected(false);
}
}
}
});
HBox tmpNameBox = new HBox(templateNameLabel, templateTexBox);
HBox tmpTypeBox = new HBox(templateType, comboBox);
HBox tmpDefaultBox = new HBox(cb);
tmpNameBox.setPrefHeight(40.0);
tmpTypeBox.setPrefHeight(40.0);
VBox wrapperBox = new VBox( tmpNameBox, tmpTypeBox, tmpDefaultBox );
dlg.setContent(wrapperBox);
dlg.getActions().addAll(Dialog.ACTION_OK, Dialog.ACTION_CANCEL);
Action action = dlg.show();
if (action == Dialog.ACTION_OK) {
if (StringUtils.isNotBlank(templateTexBox.getText()) && comboBox.getValue() != null) {
//saveTemplateData(templateTexBox.getText(), String.valueOf(comboBox.getValue()), cb.isSelected());
saveFilterTemplateData(templateTexBox.getText(), String.valueOf(comboBox.getValue()), cb.isSelected());
} else {
Dialogs.create().title("Missing Required Data")
.message("Please populate both Template Name and Template Type")
.styleClass(Dialog.STYLE_CLASS_CROSS_PLATFORM).showError();
saveTemplate();
}
}
** I am using this class
import org.controlsfx.dialog.Dialogs;
I have also tried with javafx dialog and craete my code like that but I am unable to achieve what I want.

Call
dlg.initModality(Modality.NONE);
before showing the dialog (see docs)

Related

Swap the type of link depending on model object

I'm at complete loss how to proceed further:
I have panel with a DropDownChoice and a submit button next to it. Depending on the selected value of the DropDownChoice (Obtained upon the firing of a OnChangeAjaxBehavior attached to it, the submit button needs to either replace the whole panel with a different one, OR become an ExternalLink.
Currently, the code looks like that:
public class ReportSelectionPanel extends Panel {
protected OptionItem selectedOption ;
public ReportSelectionPanel(String id) {
super(id);
IModel<List<OptionItem>> choices = new AbstractReadOnlyModel() {
// Create a list of options to be displayed in the DropDownChoice
} ;
final IModel<OptionItem> optionModel =
new PropertyModel<OptionItem>(this,"selectedOption") ;
final DropDownChoice<OptionItem> options =
new DropDownChoice("selectChoice",optionModel,choices) ;
// I don't know what the button should be... Plain Button? A Link?
final Component button = ???
options.add( new OnChangeAjaxBehavior() {
protected void onUpdate(AjaxRequestTarget target) {
if ( selectedOption.getChild() == null ) {
// button becomes an ExternalLink.
// A new window will popup once button is clicked
} else {
// button becomes a Something, and upon clicking,
// this ReportSelectionPanel instance gets replaced by
// an new Panel instance, the type of which is
// selectedOption.getChild()
}
} ) ;
I'm really not quite sure what the commented lines should become to achieve the result. Any suggestions?
Thanks!
Eric
IMHO it's nicer to keep just one button and just react differently depending on the selected option:
final Component button = new AjaxButton("button") {
public void onClick(AjaxRequestTarget target) {
if (selectedOption.getChild() == null) {
PopupSettings popup = new PopupSettings();
popup.setTarget("'" + externalUrl + "'");
target.appendJavascript(popup.getPopupJavaScript());
} else {
ReportSelectionPanel.this.replaceWith(new ReportResultPanel("..."));
}
}
};
// not needed if options and button are inside a form
// options.add( new OnChangeAjaxBehavior() { } ) ;

KeyEvent on Dialog not consumed when closing in JavaFX

I have a requirement to navigate a table when the user hits the ENTER key. For this I have created an event filter similar to:
private EventHandler<KeyEvent> keyReleasedFilter = event -> {
if ((event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB)) {
previousPosition = table.getFocusModel().getFocusedCell();
//do my navigation
}
}
I have run into an issue where JavaFX Modal Dialogs used during navigation of the table to indicate an error, cause issues with this filter. If the user closed the dialog with the ENTER key, that event is trapped by my event filter on the parent stage. I am not sure how to prevent that. It is causing inconsistent navigation.
Here is a simple application that demonstrates the behavior:
public void start(Stage primaryStage) {
final Alert d = new Alert(Alert.AlertType.ERROR);
d.initModality(Modality.WINDOW_MODAL);
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.addEventFilter(KeyEvent.KEY_RELEASED, event -> {
if ((event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB)) {
d.showAndWait();
}
});
Scene scene = new Scene(new StackPane(btn), 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
I have noticed that the dialog is closed with the KEY_PRESSED event, and will not capture the KEY_RELEASED event.
I have tried adding an EVENT FILTER to the dialog (Button/DialogPane/Scene and even Stage) - none intercept the KEY_RELEASED event.
Thanks.
Unless there is another reason to use the KEY_RELEASED event, then I would recommend switching to triggering on KEY_PRESSED for navigation as well and switch your EventFilter to an EventHandler. The example below will allow you to toggle the Alert on and off. When it's on, you'll notice that the button text doesn't change. When it's off, the button text will change. Take a look at how JavaFX constructs Event chains here if you haven't already.
boolean error = false;
int i = 0;
#Override
public void start(Stage primaryStage)
{
final Alert d = new Alert(Alert.AlertType.ERROR);
d.initModality(Modality.WINDOW_MODAL);
Button err = new Button();
err.setText("Error off");
err.addEventHandler(ActionEvent.ACTION, t ->
{
error = !error;
if (error)
err.setText("Error on");
else
err.setText("Error off");
});
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.addEventHandler(KeyEvent.KEY_PRESSED, event ->
{
if ((event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB)) {
if (error)
{
d.showAndWait();
}
else
{
i++;
btn.setText(String.valueOf(i));
}
}
});
Scene scene = new Scene(new VBox(btn, err), 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
So I have a hack that works - I really don't like it, so I am hoping that there is a better solution (a clean one) to solve this issue....
Basically, right before I open my dialog, I set a boolean so I know it's open. Then in my event filter, kick out if that is set to true.
public class EventTester extends Application{
public static void main(String[] args){
launch(args);
}
private boolean modalWasShowing = false;
#Override
public void start(Stage primaryStage) {
final Alert d = new Alert(Alert.AlertType.ERROR);
d.initModality(Modality.WINDOW_MODAL);
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.addEventFilter(KeyEvent.KEY_RELEASED, event -> {
if(modalWasShowing){
modalWasShowing=false;
return;
}
if ((event.getCode() == KeyCode.ENTER || event.getCode() == KeyCode.TAB)) {
modalWasShowing = true;
d.showAndWait();
}
});
Scene scene = new Scene(new StackPane(btn), 300, 250);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
Please let me know if you know of a better way to handle this.

Combo Box is not observed

I have the following Code:
public class GuiView extends Application {
private ObservableList<String> shareNames = FXCollections.observableArrayList();
public void start(Stage stage) {
...
ComboBox<String> comboBox = new ComboBox<String>();
comboBox.getItems().addAll(this.shareNames);
MenuItem open = new MenuItem("Open...");
open.setOnAction( e -> {
// FileChooser code...
if (selctedFile != null) {
this.shareNames.addAll("teststring");
}
});
}
}
When I run through the open dialog successfully the combo box doesn't update and shows the teststring. What is going wrong here?
You are updating shareNames, but that is not the list used by the combo box.
Either replace
comboBox.getItems().addAll(this.shareNames);
with
comboBox.setItems(this.shareNames);
or replace
this.shareNames.addAll("teststring");
with
comboBox.getItems().add("teststring");

GXT 3, editable grid, need to perform action on enter

I am new to GXT 3, and am confused by the API. Perhaps you could clarify.
In Editor Grid, how do I catch and examine keyboard keys pressed inside a cell in focus?
Create your grid and pass it to GridEditing instance:
final GridEditing<MyType> ge = new GridInlineEditing<MyType>(grid);
// note: final Grid grid = new Grid(store, cm);
// note: ColumnModel cm = new ColumnModel(configs);
// note: List> configs = new ArrayList>();
Construct your ColumnConfig
ColumnConfig<MyType, String> kanji = new ColumnConfig<MyType, String>(kfgProps.kanji());
// note: kfgProps here extends PropertyAccess
Add your editor
ge.addEditor(kanji, text);
// note: text = new TextField();
Add your DomHandler
text.addDomHandler(new KeyDownHandler() {
#Override public void onKeyDown(KeyDownEvent event) {
if (KeyCodes.KEY_ENTER == event.getNativeEvent().getKeyCode()) {
// do whatever
}
}
}, KeyDownEvent.getType());

SWT: show popup menu below toolbar button after clicking on it

I want to show a popup menu below a toolbar button when the user clicks this button. I've read about the SWT.DROP_DOWN style for a ToolItem but this seems very much limited to a simple list of items according to this sample. Instead, I want to show a popup menu with, e.g., checkbox and radio button menu items.
You can make MenuItem with styles SWT.CHECK, SWT.CASCADE, SWT.PUSH, SWT.RADIO, SWT.SEPARATOR
see javadoc..
So you can "hang" swt menu to selection of dropdown on toolbar item like this
public class Test {
private Shell shell;
public Test() {
Display display = new Display();
shell = new Shell(display, SWT.SHELL_TRIM);
shell.setLayout(new FillLayout(SWT.VERTICAL));
shell.setSize(50, 100);
ToolBar toolbar = new ToolBar(shell, SWT.FLAT);
ToolItem itemDrop = new ToolItem(toolbar, SWT.DROP_DOWN);
itemDrop.setText("drop menu");
itemDrop.addSelectionListener(new SelectionAdapter() {
Menu dropMenu = null;
#Override
public void widgetSelected(SelectionEvent e) {
if(dropMenu == null) {
dropMenu = new Menu(shell, SWT.POP_UP);
shell.setMenu(dropMenu);
MenuItem itemCheck = new MenuItem(dropMenu, SWT.CHECK);
itemCheck.setText("checkbox");
MenuItem itemRadio = new MenuItem(dropMenu, SWT.RADIO);
itemRadio.setText("radio1");
MenuItem itemRadio2 = new MenuItem(dropMenu, SWT.RADIO);
itemRadio2.setText("radio2");
}
if (e.detail == SWT.ARROW) {
// Position the menu below and vertically aligned with the the drop down tool button.
final ToolItem toolItem = (ToolItem) e.widget;
final ToolBar toolBar = toolItem.getParent();
Point point = toolBar.toDisplay(new Point(e.x, e.y));
dropMenu.setLocation(point.x, point.y);
dropMenu.setVisible(true);
}
}
});
shell.open();
while(!shell.isDisposed()) {
if(!display.readAndDispatch()) display.sleep();
}
display.dispose();
}
public static void main(String[] args) {
new Test();
}
}