I can't see my Vaadin Dialog which I'm trying to add on a simple Vertical Layout
Here is my code:
Dialog d = new Dialog(new Label("Simple label"));
d.setCloseOnEsc(false);
d.setCloseOnOutsideClick(false);
Button cancelBtn = new Button("Cancel", event -> {
d.close();
});
d.add(cancelBtn);
add(d);
I hope anyone can help me :)
Dialog::open
A Dialog is a specific component - it is not normally rendered within the given container, but opens as a popup. Therefore, it has special semantics to make it to render - after creating a dialog, you have to call dialog.open() to make it display.
This is also not specific to Vaadin - in many frameworks, dialogs (and other popups) are displayed in a special manner - it's somewhat of a pattern.
Related
I'm currently creating a dialog using JavaFX. The Dialog it self works very well but now I'm trying to add an input validation which warns the user when he forgets to fill out a text field.
And here comes my question: Is it possible to prevent the dialog from closing inside the Result Converter? Like this:
ButtonType buttonTypeOk = new ButtonType("Okay", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().add(buttonTypeOk);
dialog.setResultConverter((ButtonType param) -> {
if (valid()) {
return ...
} else {
Alert alert = new Alert(Alert.AlertType.WARNING);
alert.setHeaderText("Pleas fill all fields!");
alert.showAndWait();
//prevent dialog from closing
}
});
I noticed that the dialog dosn't close if an error was thrown inside the resault converter but this doesn't seems to be a good way to solve this problem.
If it isn't possible to solve the problem this way I could disable the button as described in this post. But I would prefer to keep the button enabled and display a message.
Thank you in advance !
How you are supposed to manage data validation in a dialog is actually explained in the Javadoc, I quote:
Dialog Validation / Intercepting Button Actions
In some circumstances it is desirable to prevent a dialog from closing
until some aspect of the dialog becomes internally consistent (e.g. a
form inside the dialog has all fields in a valid state). To do this,
users of the dialogs API should become familiar with the
DialogPane.lookupButton(ButtonType) method. By passing in a ButtonType
(that has already been set in the button types list), users will be
returned a Node that is typically of type Button (but this depends on
if the DialogPane.createButton(ButtonType) method has been
overridden). With this button, users may add an event filter that is
called before the button does its usual event handling, and as such
users may prevent the event handling by consuming the event. Here's a
simplified example:
final Button btOk = (Button) dlg.getDialogPane().lookupButton(ButtonType.OK);
btOk.addEventFilter(
ActionEvent.ACTION,
event -> {
// Check whether some conditions are fulfilled
if (!validateAndStore()) {
// The conditions are not fulfilled so we consume the event
// to prevent the dialog to close
event.consume();
}
}
);
In other words, you are supposed to add an event filter to your button to consume the event in case the requirements are not fulfilled which will prevent the dialog to be closed.
More details here
One other way to solve this is by using setOnCloseRequest if you don't want to relay only on the user clicking the "Okay" button. The event handler will be called when there is an external request to close the Dialog. Then the event handler can prevent dialog closing by consuming the received event.
setOnCloseRequest(e ->{
if(!valid()) {
e.consume();
}
});
I am looking to figure out how to set the text of a label on an external Application Window.
What I have:
I have two windows so far. The first one is the main application window that will appear when the user starts the program. The second window is another separate window that I have created specifically to display a custom error window.
The problem: I seem to be unable to call the label that I have created on the error window and set the text to something custom. Why? I want to be able to reuse this window many times! This window is aimed for things like error handling when there is invalid input or if the application cannot read/save to a file.
I was going to post screen shots but you need 10 rep for that. It would have explained everything better.
Here is the code for the label on the Error_dialog window:
Label Error_label = new Label(container, SWT.NONE);
Error_label.setBounds(10, 10, 348, 13);
Error_label.setText("Label I actively want to change!");
Here is the condition I would like to fire off when it is met:
if(AvailableSpaces == 10){
//Set the label text HERE and then open the window!
showError.open();
}
I have included this at the top of the class as well:
Error_dialog showError = new Error_dialog();
Just save the label as a field in your dialog class and add a 'setter' method. Something like:
public class ErrorDialog extends Dialog
{
private Label errorLabel;
... other code
public void setText(String text)
{
if (errorLabel != null && !errorLabel.isDisposed()) {
errorLabel.setText(text);
}
}
You will need to use your dialog like this:
ErrorDialog dialog = new ErrorDialog(shell);
dialog.create(); // Creates the controls
dialog.setText("Error message");
dialog.open();
Note: you should stick to the rules for Java variable names - they always start with lower case.
Further learn to use Layouts. Using setBounds will cause problems if the user is using different fonts.
I have developed a custom component consist of a layout and two labels within it. This layout is draggable. The code is similar to this :
DragAndDropWrapper boxWrap= new DragAndDropWrapper(layout);
mainLayout.addComponent(boxWrap);
After that I have a RichTextArea that allows the layout to be dropped in it. With this code.
RichTextArea richText= new RichTextArea;
DragAndDropWrapper dndWrapper = new DragAndDropWrapper(richText);
dndWrapper.setDropHandler(new DropHandler() {
public void drop(DragAndDropEvent event) {
//Do whatever you want when something is dropped
}
//Criterio de aceptacion
public AcceptCriterion getAcceptCriterion() {
return AcceptAll.get();
}
});
The code works fine. But when I drop the layout within the RichTextArea y want to get the Text written in this area and add some text but the method richText.getValue() is not updated unless I change the focus to another component or tab out. I guess there is not being communication with the server side so the value is not updated. Is there any way to force a a focus change when mousedown on the layout? I tried with JavaScript but i dont know how to add a onmousedown="function()" attribute to the layout component. I also tried extending RichTextArea and implementing the MouseListener or something or a TextChangeListener, but nothing works.
Any clue? Thank you.
PS: The component cannot be different from a RichTextArea.
Have you set richText.setImmediate(true); ?
I have this.setVolumeControlStream(AudioManager.STREAM_MUSIC); at the start of all activities in my application so when the user presses the volume up or down buttons, he controls the media volume.
I have a popup window in my program and when that appears the user can no longer control the volume.
Looking at similar questions it seems that setting up onKeyup/down listeners can interfere with the process - but I have not set any up - the only listeners I have for the popup window are setOnClickListeners for the buttons and a setOnDismissListener for the window.
How can I fix this?
Looks like you have to call setOwnerActivity on the Dialog object.
Documentation from the method:
Sets the Activity that owns this dialog. An example use: This Dialog will use the suggested volume control stream of the Activity.
While not tested, this should do the trick. There is also the possibility to use setVolumeControlStream.
I had been creating the popup window with
my_popup_window = new PopupWindow(layout, x, y, true);
I then change it to this...
my_popup_window = new PopupWindow(layout);
my_popup_window.setWidth(x);
my_popup_window.setHeight(y);
and the volume control started to work again. I don't understand why - but it worked.
I just do this pop.setFocusable(false). and it worked.
though the Mick's answer didn't work for me, this is for posterity.
//Declaration
PopupWindow mWindow;
...
//Constructor
mWindow = new PopupWindow(context);
...
//Prepare to Show
mWindow.setContentView();
mWindow.setBackgroundDrawable();
mWindow.setFocusable(false);
...
setting setFocusable to false helped my activity capture onKeyDown() again.
I can see how to instantiate a second MVC group, e.g.
def (loginPaneModel, loginPaneView, loginPaneController) =
createMVCGroup('LoginPane', 'LoginPane', [:]);
view.loginPanel = loginPaneView.loginPanel
But I don't want to show as part of my main window. I want it to pop up over it. What do I call to do that? Thanks!
The easiest way would be to use the view panel as the root of a dialog in the parent MVC group. In the view for the group that yor code snippet is the controller of you could do something like this...
application(title:'your app', ....) {
// your existing code...
loginDialog = dialog(title:'Login Panel', visible:false) {
panel(loginPanel)
}
}
And then when you need to show the dialog (in the same controller)
view.loginDialog.visible = true
Nesting a dialog inside of another window has the side effect of setting the dialog's owner to the frame or dialog of the parent. Having a dialog owned by another dialog/window is what causes the dialog to be linked with the parent and always float on top of that parent. It will also raise/lower with the parent as well.
Well, it seems that only the first line is needed. That was enough to pop up a window. I believe the key, though, was to make the view a frame.
def frame = frame(title:'Login', pack:true, locationByPlatform:true) {
...
}
frame.pack()
frame.show()