Trying to Add More tabs to tab panel upon clicking on a button - gwt

I would like to add more tabs to the tab panel upon receiving a reponse from a servelet.. the problem is that It only adds the last one and not the the others see part of the code below. It seems like it is only adding the last panel "Time Reports" but not the other two
Thank you
btnLogin.addClickListener(new ClickListener() {
public void onClick(Widget sender) {
if(getLoginResult())
{
HorizontalPanel temp = new HorizontalPanel();
panel.add(temp, "Add Hours");
panel.add(temp, "Time Sheets");
panel.add(temp, "Time Reports");
}
}
});
RootPanel.get().add(panel);
}
private boolean getLoginResult() {
AsyncCallback callback = new AsyncCallback() {
public void onSuccess(Object result) {
isAuthenticated = true;
}
public void onFailure(Throwable caught) {
Window.alert("Error when invoking the pageable data service :" + caught.getMessage());
isAuthenticated = false;
}
};
timesheetLoginServlet.isAuthenticated("1","rapidjava", callback);
return isAuthenticated;
}
}

You can add any widget to its parent only once. Change the temp to temp1, temp2 and temp3

Related

Why do I get MouseDown events from a position outside of the control's boundary?

I have a Composite containing a number of Text controls. I have attached MouseListeners to each control.
What surprises me is that sometimes, when I click on a control, I get a MouseDown event from its neighbour. The Event position is outside of the control's boundary and I get no event from the other control which I thought I had clicked on.
What can cause this to happen?
SNIPPET
Run. Press Esc to close the MessageBox. Click in field BBBB. Press Esc to close MessageBox. Click in field AAAA. The event is generated from field BBBB.
public class Test
{
public class MyListener implements MouseListener, FocusListener
{
private boolean active;
#Override
public void focusGained(FocusEvent e)
{
System.out.println(e);
message((Text) e.widget, "FocusGained");
}
#Override
public void focusLost(FocusEvent e)
{
System.out.println(e);
}
#Override
public void mouseDoubleClick(MouseEvent e)
{
}
#Override
public void mouseDown(MouseEvent e)
{
System.out.println(e);
}
private void message(final Text t, final String m)
{
if (active == false)
{
active = true;
MessageBox mb = new MessageBox(t.getShell());
mb.setText(m);
mb.setMessage(t.getMessage() + "\n\n" + m);
mb.open();
active = false;
}
}
#Override
public void mouseUp(MouseEvent e)
{
System.out.println(e);
message((Text) e.widget, e.toString());
}
}
private MyListener listener = null;
public static void main(String[] args)
{
Display display = new Display();
Shell shell = new Shell(display);
new Test(shell);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
public Test(Composite parent)
{
listener = new MyListener();
create(parent);
}
private void create(Composite parent)
{
parent.setLayout(new GridLayout(2, true));
createText(parent, "AAAA");
createText(parent, "BBBB");
parent.layout(true);
}
private Text createText(Composite parent, String message)
{
Text t = new Text(parent, SWT.NONE);
t.setMessage(message);
GridData gd = new GridData(SWT.FILL, SWT.CENTER, true, false);
t.setLayoutData(gd);
t.addFocusListener(listener);
t.addMouseListener(listener);
return t;
}
}
This is indeed strange. When traversing from B to A, the MouseUp event is marked as sent from field B.
If you replace the MessageBox with something non-interrupting i.e. System.out, the mouse event senders are the right ones.
To me, this seems more of a theoretical corner case. Decent applications would not interrupt the users field traversal with a modal window. However, if this is relevant for your, I'd report a bug to SWT.
I managed to get this working by de-coupling the pop-up window from the events. The message method now looks like this:
private void message(final Text t, final String m)
{
//NB active is declared as 'volatile'
if (active == false)
{
active = true;
t.getDisplay().asyncExec(new Runnable()
{
#Override
public void run()
{
MessageBox mb = new MessageBox(t.getShell());
mb.setText(m);
mb.setMessage(t.getMessage() + "\n\n" + m);
mb.open();
active = false;
}
});
}
else
{
System.out.println("Already active: " + t.getMessage());
}
}
This seems to give the events the opportunity to continue uninterrupted by the pop-up window. The pop-up will be activated a short while later. So far it works ok.

CellTable click swallowed

I've an combo box which is composed of a text field and a popup with a CellTable showing the suggestion items. The text field has a change handler that updates the CellTable's selection.
When typing a character and clicking an already selected suggestion, the first click is swallowed. The second click works and triggers the selection via the CellTable.addDomHandler(...).
Any idea why first click is swallowed?
Example code:
private static class SuggestFieldTextAndPopupSandbox extends SimplePanel {
private final TextField mText;
private CellTable<Handle<String>> mTable;
private SingleSelectionModel<Handle<String>> mTableSelection;
private SingleSelectionModel<Handle<String>> mSelection;
private ProvidesKey<Handle<String>> mKeyProvider = new SimpleKeyProvider<Handle<String>>();
private PopupPanel mPopup;
private List<Handle<String>> mData;
public SuggestFieldTextAndPopupSandbox() {
mData = Lists.newArrayList(new Handle<String>("AAA"), new Handle<String>("AAB"), new Handle<String>("ABB"));
mSelection = new SingleSelectionModel<Handle<String>>();
mText = new TextField();
mText.addKeyPressHandler(new KeyPressHandler() {
#Override
public void onKeyPress(KeyPressEvent pEvent) {
mPopup.showRelativeTo(mText);
}
});
mText.addBlurHandler(new BlurHandler() {
#Override
public void onBlur(BlurEvent pEvent) {
mTableSelection.setSelected(startsWith(mText.getValue()), true);
}
});
mText.addChangeHandler(new ChangeHandler() {
#Override
public void onChange(ChangeEvent pEvent) {
mText.setText(mText.getText().toUpperCase());
}
});
mTable = new CellTable<Handle<String>>(0, GWT.<TableResources>create(TableResources.class));
mTable.setTableLayoutFixed(false);
mTableSelection = new SingleSelectionModel<Handle<String>>(mKeyProvider);
mTable.setSelectionModel(mTableSelection);
mTable.addDomHandler(new ClickHandler() {
#Override
public void onClick(final ClickEvent pEvent) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
#Override
public void execute() {
mSelection.setSelected(mTableSelection.getSelectedObject(), true);
mText.setFocus(true);
mPopup.hide();
}
});
}
}, ClickEvent.getType());
mTable.addColumn(new TextColumn<Handle<String>>() {
#Override
public String getValue(Handle<String> pObject) {
return pObject.get();
}
});
mTable.setRowData(mData);
mPopup = new PopupPanel();
mPopup.setAutoHideEnabled(true);
mPopup.setWidget(mTable);
mPopup.setWidth("200px");
mPopup.setHeight("200px");
VerticalPanel p = new VerticalPanel();
p.add(mText);
setWidget(p);
}
private Handle<String> startsWith(final String pValue) {
final String val = nullToEmpty(pValue).toLowerCase();
int i = 0;
for (Handle<String> item : mData) {
String value = item.get();
if (value != null && value.toLowerCase().startsWith(val)) {
return item;
}
i++;
}
return null;
}
}
I reproduced your issue and here is the problem:
when you click on the suggestions the following is happening:
The text field is loosing focus which causes the corresponding ChangeEvent to be dealt with followed by the BlurEvent.
The click causes the popup to get the focus now which is why it is swallowed.
If you remove the ChangeHandler and the BlurHandler of the text field the issue disappears. But I think I found another solution
Try replacing the DOM handler of the mTable with a selection handler relative to the mTableSelection as follows:
mTableSelection.addSelectionChangeHandler(new Handler(){
#Override
public void onSelectionChange(SelectionChangeEvent event) {
Scheduler.get().scheduleFinally(new ScheduledCommand() {
#Override
public void execute() {
mSelection.setSelected(mTableSelection.getSelectedObject(), true);
mText.setFocus(true);
mPopup.hide();
}
});
}
});
Found a way how to properly solve this.
Skipping the blur handler when user hovers the suggestion list area seemed to fix that issue, at least from the tests that were done didn't see any more issues.
This was necessary because just before the user clicks a suggestion item, the text is blurred and it fires a selection change. This in turn cancels the selection made when user clicks an item.

Why is a MenuItem not responding?

There is a ContextMenu which has two options and when the second option (item2 in the code) is pressed with the right mousebutton I want it to print out some text so I know I did actually activate it. Up till now nothing happens when I click on the second mousebutton.
I haven't had much experience yet with Eventhandlers so my apologies if I made a noobish mistake.
private void maakContextMenu() {
menu = new ContextMenu();
MenuItem item = new MenuItem("Kleur Assen");
MenuItem item2 = new MenuItem("tweede optie");
final LissajousCanvas canvas = this;
item.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
new KiesKleur(canvas).show();
}
});
item2.addEventHandler(MouseEvent.MOUSE_CLICKED, new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent t) {
System.out.println("in the loop");
if(t.getSource()==MouseButton.SECONDARY){
System.out.println("in too deep");
}
new KiesKleur(canvas).show();
}
});
menu.getItems().addAll(item, item2);
}
A MenuItem is not actually a Node, so it's not part of the scene graph in the way that Nodes are. So I'm not really sure if this is a bug or not; I think it probably only implements EventTarget so it can specifically generate ActionEvents. You'll have noticed there is no setOnMouseClicked(...) method available.
Here's a workaround. I'm not sure why it only works with MOUSE_PRESSED and not with MOUSE_CLICKED, but it's likely something to do with the default mouse event handling that generates the action events:
private void maakContextMenu() {
menu = new ContextMenu();
MenuItem item = new MenuItem("", new Label("Kleur Assen"));
Label menuItem2Label = new Label("tweede optie");
MenuItem item2 = new MenuItem("", menuItem2Label);
final LissajousCanvas canvas = this;
item.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
new KiesKleur(canvas).show();
}
});
menuItem2Label.addEventHandler(MouseEvent.MOUSE_PRESSED, new EventHandler<MouseEvent>(){
#Override
public void handle(MouseEvent t) {
System.out.println("in the loop");
if(t.getButton()==MouseButton.SECONDARY){
System.out.println("in too deep");
}
new KiesKleur(canvas).show();
}
});
menu.getItems().addAll(item, item2);
}

GWT Drag and Drop File Upload not working

So I have implemented a very simple drag and drop file upload widget. Basically my widget is a vertical panel with a couple of labels and a button inside. The user can either drag file into vertical panel or click button and browse for file.
My problem is that when I drag a file into the vertical panel it fires the DragLeaveEvent every time I drag the item over the space that the labels or button occupies. I want it to know that the item is in the vertical panel even when it is on top of the label or button. Im sure I am missing something simple. I provide the drag functionality by adding these dom handlers to the vertical panel:
addDomHandler(new DragEnterHandler() {
#Override
public void onDragEnter(DragEnterEvent event) {
System.out.println("drag enter");
highlight(true);
}
}, DragEnterEvent.getType());
addDomHandler(new DragLeaveHandler() {
#Override
public void onDragLeave(DragLeaveEvent event) {
System.out.println("drag leave");
highlight(false);
}
}, DragLeaveEvent.getType());
addDomHandler(new DragOverHandler() {
#Override
public void onDragOver(DragOverEvent event) {
}
}, DragOverEvent.getType());
addDomHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
System.out.println("drop");
// stop default behaviour
event.preventDefault();
event.stopPropagation();
// starts the fetching, reading and callbacks
if (fileUploadHandler != null) {
handleFiles(event.getDataTransfer(), fileUploadHandler);
}
highlight(false);
}
}, DropEvent.getType());
Check that the event target is a child (or grand child) of your panel, or in this case maybe rather whether the event target is exactly your panel's element:
if (verticalPanel.getElement().isOrHasChild(Node.as(event.getNativeEvent().getEventTarget()))) {
// within the panel (possibly on a child)
}
if (verticalPanel.getElement() == Node.as(event.getNativeEvent().getEventTarget())) {
// targetting exactly the panel (e.g. leaving the panel, not one of its children)
}
Through lots of research I have come to the only solution I could find. I set highlight to true in the dragover handler instead of drag enter.
panel.addDomHandler(new DragEnterHandler() {
#Override
public void onDragEnter(DragEnterEvent event) {
}
}, DragEnterEvent.getType());
panel.addDomHandler(new DragLeaveHandler() {
#Override
public void onDragLeave(DragLeaveEvent event) {
highlight(false);
}
}, DragLeaveEvent.getType());
panel.addDomHandler(new DragOverHandler() {
#Override
public void onDragOver(DragOverEvent event) {
highlight(true);
}
}, DragOverEvent.getType());
panel.addDomHandler(new DropHandler() {
#Override
public void onDrop(DropEvent event) {
// stop default behaviour
event.preventDefault();
event.stopPropagation();
// starts the fetching, reading and callbacks
handleFiles(event.getDataTransfer());
highlight(false);
}
}, DropEvent.getType());
I copy pasted your code, but also added a:
RootPanel.get().addHandler(dropHandler, DropEvent.getType());
My drophandler looks like this:
DropHandler dropHandler = new DropHandler() {
#Override
public void onDrop(DropEvent event) {
handleFiles(event.getDataTransfer(), new FileUploadHandler() {
#Override
public TYPE specifyFileType() {
return TYPE.BINARY;
}
#Override
public void handleFileContent(String fileName, String fileContent) {
// do stuff with filename and content
}
#Override
public boolean checkFileName(String fileName) {
return true;
}
});
event.preventDefault();
event.stopPropagation();
}
};
and the file-upload interface:
public interface FileUploadHandler {
static public enum TYPE {
TEXT, BINARY, DATAURL
};
// check the filename and extension and return true if you are happy with
// proceeding
// returnning false will prevent the file from being read
boolean checkFileName(String fileName);
// tell the method to use to read this file
TYPE specifyFileType();
// do your stuff here, eg upload to a server
void handleFileContent(String fileName, String fileContent);
}
and the handle files func: (note you will have to change classpath to the FileUploadHandler-interface)
// native method to make use of the HTML5 file API functionality
private final native void handleFiles(JavaScriptObject dataTransfer, FileUploadHandler fileUploadHandler) /*-{
var files = dataTransfer.files;
var i;
var file;
var reader = new FileReader();
for (i = 0; i < files.length; i++) {
file = files[i];
if (fileUploadHandler.#<classpath_to>.FileUploadHandler::checkFileName(Ljava/lang/String;)(file.name)) {
var type = fileUploadHandler.#<classpath_to>.FileUploadHandler::specifyFileType()();
reader.onload = function(e) {
fileUploadHandler.#<classpath_to>.FileUploadHandler::handleFileContent(Ljava/lang/String;Ljava/lang/String;)(file.name, e.target.result);
}
if (type == "TEXT") {
reader.readAsText(file);
} else if (type == "BINARY") {
reader.readAsBinaryString(file);
} else if (type == "DATAURL") {
reader.readAsDataURL(file);
// not supported
} else if (type == "ARRAYBUFFER") {
reader.readAsArrayBuffer(file);
} else {
}
}
}
}-*/;

How to prevent DoubleSubmit in a GWT application?

To clarify what double submit is: When the user clicks on a submit button twice, the server will process the same POST data twice. To avoid this (apart from disabling the button after a single submit), most web frameworks like Struts provide a token mechanism. I am searching for the equivalent of this in GWT.
If you want to avoid submitting twice, how about:
boolean processing = false;
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
if (!processing) {
processing = true;
button.setEnabled(false);
// makes an RPC call, does something you only want to do once.
processRequest(new AsyncCallback<String>() {
#Override
public void onSuccess(String result) {
// do stuff
processing = false;
button.setEnabled(true);
});
});
}
}
});
That's the gist of it.
This will be helpfull for you -
final Button btn = new Button("Open");
btn.addSelectionListener(new SelectionListener<ButtonEvent>() {
#Override
public void componentSelected(ButtonEvent ce) {
btn.setEnabled(false);
openMethod(name, new AsyncCallback<Void>() {
public void onFailure(Throwable caught) {
btn.setEnabled(true);
}
public void onSuccess(Void result) {
MessageBox.alert(info, "Opened Window", null);
btn.setEnabled(true);
window.hide();
}
});
}
});