All the examples for DialogBox does something like
void someFn()
{
DialogBox box = new DialogBox();
box.show();
}
but I want to create it earlier like
private DialogBox box = new DialogBox();
void someFn()
{
box.show();
}
The problem is that it shows up directly without waiting for any action.
Any ideas how this can be handled?
The dialog box is created by a function called from the constructor as
private DialogBox makeMenu() {
DialogBox ret = new DialogBox(true);
FlowPanel f = new FlowPanel();
f.getElement().getStyle().setProperty("minWidth", "350px");
// Add stuff
f.add(...)
ret.setWidget(f);
return ret;
}
OK, the answer was a step up. You should never add a DialogBox to a Panel and I did that as
FlowPanel container = new FlowPanel();
container.add(menu);
Stupid mistake, but not something you look for first.
Related
I am trying to return an ArrayList with two values, text and a text area. However when I press the button that is meant to do this, nothing happens. Can you please explain why this is the case?
The method that returns the ArrayList:
public ArrayList<Object> newFile(){
ArrayList<Object> objectArrayList = new ArrayList<>();
TextArea textField = new TextArea("Type File Information.., ");
AtomicReference<String> fileText = new AtomicReference<>();
textField.addTextListener((textListener) -> {
fileText.set(textField.getText());
});
objectArrayList.add(String.valueOf(fileText));
objectArrayList.add(textField);
return objectArrayList;
}
}
The code snippet that executes the method and gets the text area:
public void actionPerformed(ActionEvent e) {
String action = e.getActionCommand();
switch (action) {
case "New":
fileText = (String) newFile().get(0);
MainMenu mainMenu = new MainMenu();
mainMenu.add((TextArea)newFile().get(1));
break;
The code snippet where I add the handler:
newFile.addActionListener(mainMenuHandler);
Why are you using AWT. You should at least be using Swing.
MainMenu mainMenu = new MainMenu();
mainMenu.add((TextArea)newFile().get(1));
In your case you add the text area to the MainMenu, but you never add the MainMenu to the frame.
So you would need to add the "mainMenu" to the frame.
Also, when using Swing if you add a component to a visible frame then you need to invoke revalidate() and repaint() on the container you add the component to.
I got a strange issue. My web application works as it don't remove text/numbers from text boxes or resetting check boxes when I refresh the web page from the web browser.
But when I refresh the web page then I got the problem:
java.lang.IllegalStateException: Can't move a node from one state tree to another. If this is intentional, first remove the node from its current state tree by calling removeFromTree
java.lang.IllegalStateException: Unregistered node was not found based on its id. The tree is most likely corrupted.
And
Assertion error: No child node found with id 28
Assertion error: Node 3 is already registered
So why can't I set the content again after I have fresh the web page in Vaadin? I'm using Vaadin 14. If I don't refresh the web page, then I can change the content as much as I want. But as long I don't refresh the web page, then I will not get an error.
Notice that I have #PreserveOnRefresh enabled. Without that, I get no error. But then the text/values and all information will disappear when I refresh the page.
Here is my code.
#Route("")
#Viewport("width=device-width, minimum-scale=1, initial-scale=1, user-scalable=yes, viewport-fit=cover")
#PreserveOnRefresh
public class MainView extends AppLayout {
/**
*
*/
private static final long serialVersionUID = 1L;
public MainView() {
// Get the components
BuildPredictValidateTemplate buildPredictValidateTemplate = new BuildPredictValidateTemplate();
LoadExportTemplate loadExportTemplate = new LoadExportTemplate();
// Create logo and drawer
Image barImage = new Image("img/barImage.png", "Fisherfaces Logo");
barImage.setHeight("55px");
addToNavbar(new DrawerToggle(), barImage);
// Create tabs and add listeners to them
Tab buildPredictValidate = new Tab("Build & Predict & Validate");
buildPredictValidate.getElement().addEventListener("click", e -> {
setContent(buildPredictValidateTemplate.getBuildButtonPredictButtonValidateButtonTextArea());
});
Tab loadExport = new Tab("Load & Export");
loadExport.getElement().addEventListener("click", e -> {
setContent(loadExportTemplate.getSubjectCounterExportButtonUploaders());
});
// Add them and place them as vertical
Tabs tabs = new Tabs(buildPredictValidate, loadExport);
tabs.setOrientation(Tabs.Orientation.VERTICAL);
addToDrawer(tabs);
}
}
And
#Data
//#Component
public class BuildPredictValidateTemplate {
private VerticalLayout buildButtonPredictButtonValidateButtonTextArea;
public BuildPredictValidateTemplate() {
// Create the complete form layout
buildButtonPredictButtonValidateButtonTextArea = createBuildButtonPredictButtonValidateButtonTextArea();
}
private VerticalLayout createBuildButtonPredictButtonValidateButtonTextArea() {
// Text area that works like a terminal
TextArea textTerminal = new TextArea();
textTerminal.setPlaceholder("");
textTerminal.setWidthFull();
textTerminal.setHeightFull();
// Progressbar
ProgressBar progressBar = new ProgressBar();
progressBar.setValue(0);
// Buttons for Builing, Predicting and Validate
Button build = new Button("Build");
build.addClickListener(e -> {
System.out.println("Building");
});
Button predict = new Button("Predict");
predict.addClickListener(e -> {
System.out.println("Predicting");
});
Button validate = new Button("Validate");
validate.addClickListener(e -> {
System.out.println("Validating");
});
// Uploader for prediction
//Upload upload = new PictureUpload().getUpload();
// Add them all now
HorizontalLayout horizon = new HorizontalLayout(build, validate, predict);
return new VerticalLayout(horizon, progressBar, textTerminal);
}
}
And also
#Data
//#Component
public class LoadExportTemplate {
private VerticalLayout subjectCounterExportButtonUploaders;
public LoadExportTemplate() {
// Create layout for the uploads
VerticalLayout uploadsLayout = new VerticalLayout();
// Create subject counter for how many uploaders we should have
NumberField subjectCounter = createSubjectCounter(uploadsLayout);
// Create layout for holding subject counter, export button and uploaders
subjectCounterExportButtonUploaders = createLayoutForSubjectCounterExportButtonUploaders(subjectCounter, uploadsLayout);
}
private VerticalLayout createLayoutForSubjectCounterExportButtonUploaders(NumberField subjectCounter, VerticalLayout uploadsLayout) {
// Create SubjectCounter and ExportButton on a row
Button exportButton = new Button("Export to MATLAB code");
exportButton.addClickListener(e -> {
System.out.println("Exported to MATLAB code.");
});
HorizontalLayout layoutHorizon = new HorizontalLayout(subjectCounter, exportButton);
// Add the uploaders under the horizontal layout
return new VerticalLayout(layoutHorizon, uploadsLayout);
}
private NumberField createSubjectCounter(VerticalLayout uploadsLayout) {
NumberField subjectCounter = new NumberField();
subjectCounter.setValue(1d);
subjectCounter.setHasControls(true);
subjectCounter.setMin(1);
subjectCounter.addValueChangeListener(e-> {
// First clear, then fill with new uploaders
uploadsLayout.removeAll();
for(Double i = 0.0; i < e.getValue(); i++) {
PictureUpload pictureUpload = new PictureUpload();
uploadsLayout.add(pictureUpload.getUpload());
}
});
// Add one to begin with
//PictureUpload pictureUpload = new PictureUpload();
//uploadsLayout.add(pictureUpload.getUpload());
return subjectCounter;
}
}
I believe this is a bug in Vaadin, at least it is not what I would expect to happen.
I have created an issue for it here https://github.com/vaadin/flow/issues/8286
Edit:
As a workaround, you can toggle visibility instead. But this would require you to add all components to e.g. a Div, and set that as the content.
E.g setContent(new Div(component1, component2));
Then when clicking on a tab, you would have to hide all components except the one clicked, e.g.
getContent().getChildren().forEach(component -> {
boolean visible = component.equals(theComponentIWantToShow);
component.setVisible(visible);
});
I am just wondering...
When I click refresh button my gwt app comes to its default UI state despite its UI was modified during client-server interactions (callbacks) etc... But sometimes it is really essential thing to "cache" UI if user clicks refresh by mistake or reopened web page which user still logged-in;
So my question is...
Is there a way to restore gwt app UI (its before-refreshed state) in some standard way? Can History tokens help for this kind of issue?
edit
Concerning the history tokens I saw this example :
History.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String historyToken = event.getValue();
// Parse the history token
try {
if (historyToken.substring(0, 4).equals("page")) {
String tabIndexToken = historyToken.substring(4, 5);
int tabIndex = Integer.parseInt(tabIndexToken);
// Select the specified tab panel
tabPanel.selectTab(tabIndex);
} else {
tabPanel.selectTab(0);
}
} catch (IndexOutOfBoundsException e) {
tabPanel.selectTab(0);
}
}
});
... and I could notice it restores tabIndex from history; so will it help if tab panel won't be init-ed by module load (by default) but something this way:
//on button click...
getSimplePanel().setWidget(new MyTabbedPane());
edit
To be more clear here is my test code which I am trying to figure out how to restore MainUI I mean its previous UI state as if refresh button wasn't clicked.
the EntryPoint...
public class Main implements EntryPoint {
private SimplePanel simplePanel;
public void onModuleLoad() {
RootPanel rootPanel = RootPanel.get();
FlowPanel flowPanel = new FlowPanel();
rootPanel.add(flowPanel, 10, 10);
flowPanel.setSize("410px", "280px");
Button setWidgetButton = new Button("Click");
setWidgetButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
getSimplePanel().setWidget(new MainUI());
}
});
flowPanel.add(setWidgetButton);
simplePanel = new SimplePanel();
flowPanel.add(simplePanel);
}
protected SimplePanel getSimplePanel() {
return simplePanel;
}
}
...and composite;
public class MainUI extends Composite {
private VerticalPanel verticalPanel;
int index;
public MainUI() {
FlowPanel flowPanel = new FlowPanel();
initWidget(flowPanel);
Button button = new Button("+");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
getVerticalPanel().add(new Label(""+(++index)+": "+Math.random()));
}
});
flowPanel.add(button);
DecoratorPanel decoratorPanel = new DecoratorPanel();
flowPanel.add(decoratorPanel);
verticalPanel = new VerticalPanel();
decoratorPanel.setWidget(verticalPanel);
}
protected VerticalPanel getVerticalPanel() {
return verticalPanel;
}
}
...and, as a result, to have "cached" ui state without regenerating it again with extracting strings from history tokens and re-instantiate objects or what so ever...
for example if I have this UI (see image) I am interested to have totally the same one after refresh button is pressed...
but I am not pretty sure which way should I look for? I haven't seen any gwt snippet in this direction; So I really need your advice what way should I dig in?
Any useful comment is appreciated
Thanks
P.S. GWT 2.3
I think you miss to store the state into the URLs-Hashtag.
You can use GWTP (as suggested in the comments)
In fact you need to read the Hashtag in your onModuleLoad and restore your state.
This may work with getHash():
String state = Window.Location.getHash();
myRestoreStateFromTokenMethod(state);
update
Here are some snippets to create a push store.
List<String> states = [...]
public void onClick(){ states.add("newState");changeHash(states); }
public void changeHash(){
String hash = states.get(0) + ";"
for(other states) hash += states.get(i);
// use a UrlBuilder to set the Hash
}
Documentation for UrlBuilder
Or you can try this: https://github.com/jbarop/gwt-pushstate
How do I show a AJAX "Message Box" in GWT? I know I can use the Window.alert() function, but that's too ugly/annoying. Is there a built-in function for?
Thank you!
Yvan
Here is simple implementation of custom alert widget (modify it to what you want):
public static DialogBox alertWidget(final String header, final String content) {
final DialogBox box = new DialogBox();
final VerticalPanel panel = new VerticalPanel();
box.setText(header);
panel.add(new Label(content));
final Button buttonClose = new Button("Close",new ClickHandler() {
#Override
public void onClick(final ClickEvent event) {
box.hide();
}
});
// few empty labels to make widget larger
final Label emptyLabel = new Label("");
emptyLabel.setSize("auto","25px");
panel.add(emptyLabel);
panel.add(emptyLabel);
buttonClose.setWidth("90px");
panel.add(buttonClose);
panel.setCellHorizontalAlignment(buttonClose, HasAlignment.ALIGN_RIGHT);
box.add(panel);
return box;
}
And use it like (note center() method at the end, it actually shows the widget):
CustomWidgets.alertWidget("Adding account failed",
"System failed to add this account. Please chceck your settings properly.").center();
You can use DialogBox instead.
Hi is there any way to create something similar to Window.alert() in GWT?
Basically I wanted to customize the Window.alert()'s "Ok" button to say something else but
as I researched there is no way to customize the alert boxes.
Thanks.
Window.alert() is already available in GWT. It opens a native dialog box which contais OK button localized by the browser's locale. This alert box can not be changed.
Use PopupPanel or DecoratedPopupPanel.
You could use the PopupPanel.
I usually code a generic dialog box, that is created once and when I need it again the html content and title is replaced. You can also add a OK/Cancel button combination, this all is rather straightforward.
private DialogBox dialog = null;
private HTML dialogHtml = new HTML();
public void onDialog(final String title, final String html) {
if (dialog == null) {
dialog = new DialogBox();
dialog.getElement().getStyle().setZIndex(99);
dialog.setWidth("500px");
dialog.setGlassEnabled(true);
dialog.setAnimationEnabled(true);
dialog.setModal(true);
VerticalPanel vp = new VerticalPanel();
vp.add(dialogHtml);
HorizontalPanel hp = new HorizontalPanel();
hp.setWidth("100%");
Button close = new Button("close");
close.setWidth("200px");
close.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
dialog.hide();
}
});
hp.add(close);
hp.setCellHorizontalAlignment(close, HasHorizontalAlignment.ALIGN_CENTER);
hp.getElement().getStyle().setMarginTop(40, Unit.PX);
vp.add(hp);
vp.setSpacing(10);
dialog.add(vp);
}
dialogHtml.setHTML(html);
dialog.setHTML(title); // the actual title
dialog.show();
dialog.center();
}
The HTML content is something very simple, i.e.
<div style="width: 500px; overflow: auto;">...</div>