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;
}
}
Related
Iteresiting case which make my work a nightmare in GWT. I try to add to my panel tab with dynamic changed table to add some params by user. Requirements are dynamic adding new elements and that user can overview all of them and eventually correct it.
I create all that with callTable but in one browser (Chromium or Opera) I can add new elements but in the same time on the same package in mozzila I see scroll bar but canot add dynamically new elements, but if I erase some preloaded one new one appears. Can someone explain to me what exactly goes wrong as it is one package run in incognito mode with erased history and cookies after every session
Maybe screen will be helpfull- param fill added dynamically:
view with new element 1
table with scrool bar but without option of adding new element 2
And source code:
//initial layout and component
final VLayout customLayout = new VLayout();
Canvas customComponent = new Canvas();
//dataprovider modal creation with in memory list
final ListDataProvider<String> model = new ListDataProvider<>(
getProvisioningParameterList());
final CellTable<String> table = new CellTable<>();
// create column with data
Column<String, String> nameColumn = new Column<String, String>(new EditTextCell()) {
#Override
public String getValue(String object) {
return object;
}
};
//column with delete button
Column<String, String> deleteBtn = new Column<String, String>(
new ButtonCell()) {
#Override
public String getValue(String object) {
return "x";
}
};
// add column to the table
table.addColumn(nameColumn, "Custom parameters");
table.addColumn(deleteBtn, "Click to delete row");
//initialize table row size
table.setWidth("100%");
// Set the field updater, whenever user clicks on button row will be removed.
deleteBtn.setFieldUpdater(new FieldUpdater<String, String>() {
#Override
public void update(int index, String object, String value) {
model.getList().remove(object);
model.refresh();
table.redraw();
}
});
// add a data display to the table which is adapter.
model.addDataDisplay(table);
//add Button
final IButton addButton = new IButton("Add");
addButton.setIcon("icons/add.png");
addButton.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
model.getList().add("fill");
model.refresh();
table.redraw();
}
});
//add custom config panel with proper view
ScrollPanel sp = new ScrollPanel();
sp.setAlwaysShowScrollBars(true);
customComponent.setContents("Params");
customComponent.setAutoHeight();
customLayout.setMargin(15);
customLayout.addMember(customComponent);
customLayout.addMember(addButton, 1);
customLayout.addMember(saveButton, 2);
customLayout.addMember(table);
If someone will still wonder about it I got a solution. I forgot to add ScrollPanel to layout. Edit Additionally I put table into scrollPanel in specific dimentions and that two element structure to main VLayout. Now it works as expected :)
I have a small web application project using GWT, where a button handles an event: populating a panel with widgets. Currently, clicking the button a second time will duplicate the panel, i want it so it clears the panel, and re adds the widgets.
So far I have:
final Button b = new Button("get schools near me");
final HorizontalPanel panel = new HorizontalPanel();
panel.getElement().setId("distanceTable");
RootPanel.get("core").add(b);
RootPanel.get("core").add(panel);
b.addClickHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event) {
Timer t = new Timer(){
#Override
public void run() {
//how do you clear the panel here first? before you
// do a bunch of things along the lines of:
panel.add(widget);
panel.add(widget2);
}
};
t.schedule(1400); // wait 1.4 seconds for callback
}
});
I get that anything you pass to the run function has to be as a final declaration, so how do I get around this?
You can use the clear method:
panel.clear();
Change final HorizontalPanel panel = new HorizontalPanel(); to a class level attribute. Then it can be easily passed on to the inner anonymous classes. And you can use the clear method inside Timer method as suggested by #philfr49
e.g
private HorizontalPanel panel = new HorizontalPanel();
.....
// Elsewhere
.....
final Button b = new Button("get schools near me");
panel.getElement().setId("distanceTable");
RootPanel.get("core").add(b);
RootPanel.get("core").add(panel);
b.addClickHandler(new ClickHandler(){
#Override
public void onClick(ClickEvent event) {
Timer t = new Timer(){
#Override
public void run() {
panel.clear();
panel.add(widget);
panel.add(widget2);
}
};
t.schedule(1400); // wait 1.4 seconds for callback
}
});
Continued from the comments to the question -- using a timer to wait for a callback result is not recommended.
I assume you are working with a strict Model-View-Controller separation, and that the code you printed is the View part with the callback happening in a separate Controller class.
Now, if it is not a lot of things being added to the panel, I would use following construct:
/*
* contains all the display parts of the appliation
*/
class View{
private HorizontalPanel panel = new HorizontalPanel(); // panel as a field
/*
* Getter for panel
*/
public HorizontalPanel getPanel(){
return this.panel;
}
/**
* Method to create the display part for 'Schools Near Me'
*
* #param schoolsNearMeHandler Clickhandler that decides what happens
* when the 'near me' button is clicked
* Contains code to request from server
* and display server result
*/
public void createSchoolsNearMeSection(ClickHandler schoolsNearMeHandler){
final Button b = new Button("get schools near me");
panel.getElement().setId("distanceTable");
RootPanel.get("core").add(b);
RootPanel.get("core").add(panel);
b.addClickHandler(schoolsNearMeHandler);
}
}
/*
* Creates and operates the View and makes sure the correct things get displayed
*/
class Controller{
private View view;
public Controller(){
// since the Controller drives the Model-View-Controller part,
// the view is being created here
view = new View();
// TODO more code to set up the view to perfection
// Create the 'schools near me' section
view.createSchoolsNearMeSection(new ClickHandler(){
#Override
public void onClick(ClickEvent event) {
loadSchoolsNearMe(); // send request to server
}
}
}
/**
* Loads schools near me from the server
*/
private void loadSchoolsNearMe(){
// generic callback -- use whatever callback interface is required for your way of requesting data from server
Callback callback = new Callback(){
public void onSuccess(ServerResult result){
// retrieve the panel where you want to display your data
HorizontalPanel panel = view.getPanel();
panel.clear();
// TODO execute whatever code necessary to create
// widget and widget2 from the ServerResult
// display the newly generated widgets
panel.add(widget);
panel.add(widget2);
}
public void onError(...){
// handle errors
}
}
// Create request
Request request = new Request(...);
// Execute request
RequestBuilder.execute(request, callback);
}
}
Of course, if there is a lot of complicated code and view-building to be done with the server result, you could once again put the display-part into the View object, keep the logic in the Controller, and just call the corresponding View functions to display whatever necessary.
I want to create listbox.and when user clicks on that i want to display datagrid into dropdown.
private DataGrid objDataGrid;
public CallDataGrid() {
// TODO Auto-generated constructor stub
}
public CallDataGrid(ArrayList<Student> objArrayList) {
System.out.println("Datagrid is now going to set.");
objDataGrid = new DataGrid<Student>();
objLayoutPanel = new SimpleLayoutPanel();
objScrollPanel = new ScrollPanel();
objScrollPanel.add(objDataGrid);
objLayoutPanel.add(objScrollPanel);
objDataGrid.setEmptyTableWidget(new Label("There is no data to display."));
final TextColumn<Student> nameColumn = new TextColumn<Student>() {
#Override
public String getValue(Student object) {
return object.getStrName();
}
};
objDataGrid.addColumn(nameColumn, "User Name");
objDataGrid.setColumnWidth(nameColumn,100,Unit.PX);
final TextColumn<Student> passwordColumn = new TextColumn<Student>() {
#Override
public String getValue(Student object) {
return object.getStrPassword();
}
};
objDataGrid.addColumn(passwordColumn, "Password");
objDataGrid.setColumnWidth(passwordColumn,90,Unit.PX);
objDataGrid.setWidth("190px");
objDataGrid.setHeight("100px");
objDataGrid.setRowData(0, objArrayList);
objDataGrid.setPageSize(5);
// now how can i set this datagrid into Listbox or suggestion box??
No direct way to do what you want. Instead of a ListBox widget you can use a TextBox with a button on the right. When clicking the button put your DataGrid into a PopupPanel and display it by setting the its position on the bottom of the TextBox.
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.
I have GUI screen which lets you set the privacy of a Contact from a selection being made through RadioButton. Although I can add the selection to the database like this...
private void addContactButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
ContactDAO cDao = new ContactDAO();
final ContactDTO cdto = new ContactDTO();
String privacy = "";
String alumni = "";
if (all.isSelected()) {
privacy = all.getText();
}
if (bio.isSelected()) {
privacy = bio.getText();
}
if (none.isSelected()) {
privacy = none.getText();
}
if (yes.isSelected()) {
alumni = yes.getText();
}
if (no.isSelected()) {
alumni = no.getText();
}
cdto.setAlumni(alumni);
cdto.setStatus(privacy);
cDao.add(cdto);
}
I am stuck on retrieving the previously selected item for edit mode. Each radiobutton option belong to a buttongroup.
private void editContact() {
txtID1.setText(String.valueOf(cDTO.getID()));
txtTitle1.setText(cDTO.getTitle());
txtFn1.setText(cDTO.getForename());
txtSn1.setText(cDTO.getSurname());
//get status from cDTO.getStaus and adjust appropriately to the radio button
}
in the above method I would like to set the selected item of the radio button. Just as you would do getSelectedItem() for JComboBox, I am trying to achieve the same for radio button. note cDTO contains the data string, cDTO.getStatus which gets the value from database. But how do I set it to the 3 radio buttons that i have, named allButton bioButton noneButton
Assuming that cDTO.getStatus() returns a String that matches a radio button's name: For each button in the ButtonGroup, b, do something like this:
b.setSelected(cDTO.getStatus().equals(b.getText()));