I'm studying the GWT framework and I'm trying to create a custom widget: this widget is a button that contain inside a menu of operations.
if you click in the area of the triangle I want a menu with some options (that are possible operations) and if I click in the other parts of the buttons I want that the operation is the first from the list.
I have put a ListBox widget inside a Button widget and I want 2 different clickListener. The problem is that the listener of the listBox inside the button don't work.
Do you know why?
Following the code
public class MyClass extends Composite {
private ListBox options;
private Button saveButton;
private HorizontalPanel savePanel;
private int indexHandler;
public MyClass(String label, List<String> operationList, final List<Command> commandList) {
savePanel = new HorizontalPanel();
initWidget(savePanel);
options = new ListBox();
saveButton = new Button(label);
for(String operation : operationList){
options.addItem(operation);
}
options.sinkEvents(Event.ONCLICK);
options.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
System.out.println("Test1");
indexHandler = options.getSelectedIndex();
commandList.get(indexHandler).execute();
options.setItemSelected(0, true);
}
});
saveButton.getElement().appendChild(options.getElement());
saveButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
System.out.println("Test2");
commandList.get(0).execute();
options.setItemSelected(0, true);
}
});
savePanel.add(saveButton);
}
}
Don't use ClickHandler on the ListBox. Use ChangeHandler instead.
Also, I don't think you need to mess with Elements here. Simply add your Button widget and your ListBox widget to a container (i.e. some panel). You can add button on top of ListBox, if you want.
Related
i am making an App where i have to save dynamically created Android.Widget.Button-Objects and its Attributes, like ID, when the App is closed and opened again.
These buttons are saved in an ArrayList.
My idea was to convert my Button-Objects into JSON and save them in the SharedPreference.
My Problem now is that i cant convert the Buttons into JSON, i am using following code for this, if found on stackoverflow:
(For Tryouts i am using a new Button-Object)
Button btn = new Button(this);
Gson gson = new Gson();
String json = gson.toJson(btn);
Its working with String-Object or Integer-Object but not with Button-Object.
Can someone help me?
If you create your buttons dynamically it means you probably set a color, a text, ... to them.
So when you want to save them you only need to know how many buttons you had and what custom attributes you've set to each of them.
So you can do something like that:
You manage 2 lists, one with the buttons and one with their custom attributes.
To make it easier you can use a custom ButtonBuilder to manage the attributes.
Each time you want a new button, you create a new ButtonBuilder, you set the attributes, you generate the button and you store both the builder AND the button in 2 separated lists. Then you can store the list of builders in the SharedPrefs and regenerate the buttons from this list next time you open the app.
List<ButtonBuilder> mBuilders = new ArrayList<>();
List<Button> mButtons = new ArrayList<>();
/**
* Display a new button
*/
public void addButton(/* List of parameters*/) {
ButtonBuilder builder = new ButtonBuilder()
.setBgColor(myColor)
.setText(myText);
Button button = builder.build(context);
mBuilders.add(builder);
mButtons.add(button);
// ... Display the button
}
/**
* Call this method when you need to regenerate the buttons
*/
public void regenerateButtonsOnStart() {
// Get from shared preferences
mBuilders = getBuildersFromSharedPrefs();
Button btn;
for (ButtonBuilder builder : mBuilders) {
btn = builder.build(context);
mButtons.add(btn);
// ... Display the button
}
}
/**
* Custom button builder
*/
public class ButtonBuilder {
private int mBgColor;
private String mText;
// ... whatever you want
public ButtonBuilder() {
}
public ButtonBuilder setBgColor(int bgColor) {
this.mBgColor = bgColor;
return this;
}
public ButtonBuilder setText(String text) {
this.mText = text;
return this;
}
public Button build(Context context) {
Button btn = new Button(context);
btn.setText(mText);
btn.setBackgroundColor(mBgColor);
return btn;
}
}
I have a GWT bootstrap 3 button as a ButtonCell created with IconType and ButtonType:
public abstract class ButtonColumn<T> extends Column<T, String> {
public ButtonColumn(IconType iconType, ButtonType buttonType) {
this(new ButtonCell(buttonType, iconType));
}
}
So when I create the button, I do
new ButtonColumn<Object>(IconType.PLAY, ButtonType.SUCCESS) {
#Override
public void onClick(Object obj) {
doStuff(obj);
}
};
I want to change my button IconType onClick. Is it possible to achieve it?
And can I create a custom IconType extending the GWT IconType Enum? I wanted to put an animated icon (like a loading icon).
Well, you can not change the button's icon in a row, especially when you create the whole column with an icon already specified. But you can redraw() a row and this could be a way to achieve what you want.
I use AbstractCell to render a button and onBrowserEvent:
first create an AbstractCell with ClickEvent in consumedEvents parameter
in the render() method render a button based on the clicked state
in the onBrowserEvent() method change the clicked state and re-render the row
The clicked state is best to be kept in the table's underlying data type so it is available for each row.
Here is a complete working example code:
final CellTable<TableType> table = new CellTable<TableType>();
AbstractCell<TableType> buttonCell = new AbstractCell<ButtonCellTest.TableType>(ClickEvent.getType().getName()) {
#Override
public void render(Context context, TableType value, SafeHtmlBuilder sb) {
Button button = new Button();
button.setType(ButtonType.SUCCESS);
button.setSize(ButtonSize.SMALL);
button.add(new Icon(value.isClicked() ? IconType.CHECK : IconType.TIMES));
sb.append(SafeHtmlUtils.fromTrustedString(button.toString()));
}
#Override
public void onBrowserEvent(Context context, Element parent, TableType value, NativeEvent event, ValueUpdater<TableType> valueUpdater) {
value.setClicked(!value.isClicked());
// ... do stuff...
table.redrawRow(context.getIndex());
}
};
table.addColumn(new Column<TableType, TableType>(buttonCell) {
#Override
public TableType getValue(TableType object) {
return object;
}
});
ArrayList<TableType> rowData = new ArrayList<TableType>();
rowData.add(new TableType("row 1"));
rowData.add(new TableType("row 2"));
...
table.setRowData(rowData);
And example table's data type keeping the clicked state:
public class TableType {
String text;
boolean clicked = false;
public TableType(String text) {
this.text = text;
}
public String getText() {
return text;
}
public boolean isClicked() {
return clicked;
}
public void setClicked(boolean clicked) {
this.clicked = clicked;
}
}
As for extending the IconType enum - no, you can not extend an enum in Java. See this question for example: Can enums be subclassed to add new elements?.
You could try to add your own CSS class but this should be asked as another question to get precise answers.
I have an issue with GWT SuggestBox widget.
I have a handler on every field of the form to submit it with enter key.
However I'd like to fill suggest box with enter key too.
Thus I'm trying to find a proper way to :
1. when I choose an item in suggest box (suggestion menu shown) and press enter, select this item
2. when suggestion menu is not show validate form
Any idea
When you look at SuggestBox constructors, you will find this:
public SuggestBox(SuggestOracle oracle,
ValueBoxBase<java.lang.String> box,
SuggestBox.SuggestionDisplay suggestDisplay)
oracle - supplies suggestions based upon the current contents of the text widget
box - the text widget
suggestDisplay - the class used to display suggestions
SuggestionDisplay is what you need to check if isSuggestionListShowing().
Example code:
#UiField
FormPanel uiFormPanel;
#UiField
TextBox uiTextBox;
#UiField(provided = true)
SuggestBox uiSuggestBox;
public SubmitTest() {
// provided fields
MultiWordSuggestOracle oracle = new MultiWordSuggestOracle();
oracle.add("Cat");
oracle.add("Dog");
oracle.add("Horse");
oracle.add("Canary");
TextBox box = new TextBox();
final DefaultSuggestionDisplay suggestDisplay = new DefaultSuggestionDisplay();
uiSuggestBox = new SuggestBox(oracle, box, suggestDisplay);
initWidget(uiBinder.createAndBindUi(this));
uiFormPanel.addSubmitHandler(new SubmitHandler() {
#Override
public void onSubmit(SubmitEvent event) {
event.cancel();
Window.alert("Submit!");
}
});
uiTextBox.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER)
uiFormPanel.submit();
}
});
uiSuggestBox.addKeyDownHandler(new KeyDownHandler() {
#Override
public void onKeyDown(KeyDownEvent event) {
if(event.getNativeKeyCode() == KeyCodes.KEY_ENTER)
if(!suggestDisplay.isSuggestionListShowing())
uiFormPanel.submit();
}
});
}
UiBinder:
<g:FormPanel ui:field="uiFormPanel">
<g:HTMLPanel>
<g:TextBox ui:field="uiTextBox" />
<g:SuggestBox ui:field="uiSuggestBox" />
</g:HTMLPanel>
</g:FormPanel>
I'm working on an Eclipse RCP application and I'm trying to update an expression value which is provided by MySourceProvider according to selection changes on a TableViewer in MyEditorPart.
MyEditorPart instance defines a TableViewer like this:
public class MyEditorPart extends EditorPart {
#Override
public void createPartControl(Composite parent) {
TableViewer tableviewer = new TableViewer(parent, SWT.CHECK);
tableviewer.setContentProvider(ArrayContentProvider.getInstance());
getSite().setSelectionProvider(tableViewer);
...
MySourceProvider have some expression values like this:
public class MySourceProvider extends AbstractSourceProvider {
public static final String EXPR = "org.xyz.isEntrySelected";
// other expressions
#Override
public String[] getProvidedSourceNames() {
return new String[] { EXPR,
// other expressions
};
}
#Override
public Map getCurrentState() {
HashMap<String, Object> map = new HashMap<String, Object>(1);
map.put(EXPR, expr_value); // expr_value calculated by the listener
// other expressions
return map;
}
I want to change expr_value according to selection changes on TableViewer.
I registered the listener like this:
window.getSelectionService().addPostSelectionListener(MyEditorPartId, selectionListener);
private final ISelectionListener selectionListener = new SelectionListener() {
#Override
public void selectionChanged(IWorkbenchPart part, ISelection selection) {
handleEvent();
}
};
The listener registers successfully but gets notified only once if I clicked somewhere on MyEditorPart (not just TableViewer but the whole editor). To get notified again, I have to click on some other view (or editor) part to lose focus and then click again on MyEditorPart.
1. Why does the listener gets notified only once when MyEditorPart re-gains focus?
2. How to listen only to selection changes to TableViewer rows?
What am I missing here? What is the proper way to listen to selection changes?
Thanks in advance.
What you need is not a SelectionListener, but a SelectionChangedListener.
With this you can write the following code:
viewer.addSelectionChangedListener(new ISelectionChangedListener() {
#Override
public void selectionChanged(SelectionChangedEvent event) {
IStructuredSelection selection = viewer.getStructuredSelection();
Object firstElement = selection.getFirstElement();
// do something with it
}
});
It does appear that this form of addPostSelectionListener only fires when the part becomes active. Use the:
addPostSelectionListener(ISelectionListener listener)
form of the listener which is called for every selection change.
You can then test the IWorkbenchPart id in the listener:
#Override
public void selectionChanged(final IWorkbenchPart part, final ISelection selection)
{
if (MyEditorPartId.equals(part.getSite().getId()))
{
// your code
}
}
Hiho,
currently I have a working popup menu which appears when I click on a treeview item.
But I want to show different popups for different tree view entries. I don't get a idea how to do so...
Here is my code for creating the menu:
MenuManager menuMgr = new MenuManager("#PopupMenu");
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(new IMenuListener() {
#Override
public void menuAboutToShow(IMenuManager manager) {
Action action = new Action() {
public void run() {
// So something
}
};
action.setText("Set as working file");
manager.add(action);
}
});
Menu menu = menuMgr.createContextMenu(getTree());
getTree().setMenu(menu);
You should propably use a MouseListener on the tree:
final Tree tree = new Tree(parent, ...);
tree.addMouseListener(new MouseAdapter() {
#override
public void mouseDown(MouseEvent me) {
if(tree.getSelection() instanceof MySpecificTreeNode) {
// create menu...
}
}
});
Two ideas. For both you need to listen to selections on the TreeView, because that's the only way to determine which Menu (or special content) you want to show.
Then you could either set the correct menu to the the tree right after you know which one to use or contribute the needed items to the existing menu (that's how it's done in the eclipse framework).