Adding a Widget to Map breaks other widgets in GWT - java

I have basically two pairs of widgets, one has two datepickers and a submit button that submits the dates to an RPC on the server, and the other is a map which displays information between those dates. Each of them work individually, but when the map is displayed I cannot do anything to the datepickers or the submit button.
Here is the code that matters
public void onModuleLoad() {
final DockLayoutPanel dock = new DockLayoutPanel(Unit.PCT);
/*
* Asynchronously loads the Maps API.
*
* The first parameter should be a valid Maps API Key to deploy this
* application on a public server, but a blank key will work for an
* application served from localhost.
*/
Maps.loadMapsApi("", "2", false, new Runnable() {
public void run() {
final FormPanel form = new FormPanel();
form.setMethod(form.METHOD_POST);
DatePicker datePicker = new DatePicker();
final Label text = new Label();
text.setText("Start Date");
// Set the value in the text box when the user selects a date
datePicker.addValueChangeHandler(new ValueChangeHandler<Date>() {
public void onValueChange(ValueChangeEvent<Date> event) {
Date date = event.getValue();
String dateString = DateTimeFormat.getMediumDateFormat().format(date);
text.setText("Start Date - " + dateString);
}
});
// Set the default value
datePicker.setValue(new Date(), true);
// Add the widgets to the page
RootPanel.get().add(text);
RootPanel.get().add(datePicker);
DatePicker datePicker2 = new DatePicker();
final Label text2 = new Label();
text2.setText("End Date");
// Set the value in the text box when the user selects a date
datePicker2.addValueChangeHandler(new ValueChangeHandler<Date>() {
public void onValueChange(ValueChangeEvent<Date> event) {
Date date = event.getValue();
String dateString = DateTimeFormat.getMediumDateFormat().format(date);
text2.setText("End Date - " + dateString);
}
});
// Set the default value
datePicker2.setValue(new Date(), true);
// Add the widgets to the page
RootPanel.get().add(text2);
RootPanel.get().add(datePicker2);
RootPanel.get().add(new Button("Submit", new ClickListener()
{
public void onClick(Widget sender)
{
form.submit();
}
}));
form.addSubmitHandler(new SubmitHandler() {
#Override
public void onSubmit(SubmitEvent event) {
getAwards(text.getText(),text2.getText());
}
});
}
});
}
This is the code that creates the datepickers.
Here is the code that displays the map.
private void buildUi() {
ArrayList<Icon> icons = createIconList();
content = new ArrayList<String>();
LatLng sanDiego = LatLng.newInstance(32.83049, -117.122717);
final MapWidget map = new MapWidget(sanDiego, 9);
map.clearOverlays();
map.setSize("100%", "100%");
// Add some controls for the zoom level
map.addControl(new LargeMapControl());
java.util.Random rand = new java.util.Random();
for(ContractAward ca : sanDiegoAwards)
{
double off1 = (rand.nextDouble()-.5)/100;
double off2 = (rand.nextDouble()-.5)/100;
index++;
// Open a map centered on San Diego
LatLng contract = LatLng.newInstance(ca.getLat() + off1,ca.getLon()+off2);
MarkerOptions mo = MarkerOptions.newInstance();
mo.setTitle(""+index);
mo.setIcon(icons.get(whichIcon(ca.getAmount())));
final Marker mark = new Marker(contract,mo);
map.addOverlay(mark);
String caContent = "<P>Company: " + ca.getCompany() + "<br>";
caContent+= "Date: " + ca.getDate().toGMTString() + "<br>";
caContent+= "Amount: " + ca.getAmount() + "<br>";
caContent+= "ContractID: " + ca.getContractID() + "</P>";
content.add(caContent);
mark.addMarkerClickHandler(new MarkerClickHandler() {
public void onClick(MarkerClickEvent event) {
InfoWindow info = map.getInfoWindow();
info.open(mark, new InfoWindowContent(content.get(Integer.parseInt(mark.getTitle())-1)));
}
});
}
final DockLayoutPanel dock = new DockLayoutPanel(Unit.PCT);
dock.addEast(map, 80);
// Add the map to the HTML host page
RootLayoutPanel.get().add(dock);
}
I've tried changing the RootLayoutPanel.get().add(dock) to RootPanel.get().add(dock) but then the map itself does not display. I've also tried changing all the top parts to be docked and inserted via rootlayoutpanel but the same issue arises as is currently the problem.

Several possibilities I see on a first glance.
1) You are adding the datepicker stuff to RootPanel, but the map stuff to RootLayoutPanel. I suggest sticking to RootLayoutPanel for both, if it works, standards mode generally has more useful, up-to-date stuff in GWT.
2) Why are you doing that whole thing with Runnable in the first bit of code? Is there a reason all that stuff isn't in just onModuleLoad?

Solution ended up being to use RootLayoutPanel and combine the two docks that take up the east and west portions of the screen into 1 dock that takes the entire screen. Having two docks led to only the most recently added one being active, but putting the two docks into 1 lets both of them function.

Related

Gwt Button dropdown in celltable event handling on children

I have too many buttons in a table and I'd like to replace them by a button that open a dropdown list of actions. However I don't really know how to handle the events from the dropdown items. I manage to do it using a javascript function but it's not very practical because I can only pass primitive values.
I also want to make it as a custom cell in the future to use it in different pages in my project so returning some html isn't very practical.
Here's my code :
final ButtonCell buttonInfoCell = new ButtonCell();
Column<GwtStockProduct, String> buttonCell = new Column<GwtStockProduct, String>(buttonInfoCell) {
#Override
public void render(final Context context, final GwtStockProduct value, final SafeHtmlBuilder sb) {
Div div = new Div();
Div bG = new Div();
div.add(bG);
bG.addStyleName("btn-group");
Button button = new Button();
DropDownMenu dropDown = new DropDownMenu();
Span span = new Span();
span.addStyleName("caret");
span.setVisible(false);
button.add(span);
button.getElement().setAttribute("style", "background-image: none !important; background-color: #234C78 !important;");
// button.removeStyleName("");
button.addStyleName("btn-hide-icon btn-blue");
button.setDataToggle(Toggle.DROPDOWN);
button.setText("Change stock");
for (int i = 1; i < 5; ++i) {
AnchorListItem item = new AnchorListItem();
item.getElement().getFirstChildElement().removeAttribute("href");
item.getElement().getFirstChildElement().setAttribute("onclick", "triggerClick('" + i + "')");
item.setText("Item " + i);
dropDown.add(item);
}
// dropDown.getElement().setAttribute("style", "position: relative !important;");
bG.add(button);
bG.add(dropDown);
// sb.append(SafeHtmlUtils.fromTrustedString(buttonGroup));
sb.appendHtmlConstant(div.getElement().getInnerHTML());
}
#Override
public String getValue(final GwtStockProduct object) {
// TODO Auto-generated method stub
return null;
}
};
stockTable.addColumn(buttonCell, "Actions");
stockTable.setColumnWidth(buttonCell, 5, Unit.PCT);
I use SelectionCell to render a drop-down list of options. Maybe that will help you:
ArrayList<String> options = new ArrayList<String>();
options.add("choose an option..."); // the prompt text
options.add("option 1");
options.add("option 2");
// ...
final SelectionCell optionsCell = new SelectionCell(options);
Column<TableType, String> optionsColumn = new Column<TableType, String>(optionsCell) {
#Override
public String getValue(TableType object) {
return null;
}
};
optionsColumn.setFieldUpdater(new FieldUpdater<TableType, String>() {
#Override
public void update(int index, TableType object, String value) {
if(value == "option 1")
// process option 1
else if(value == "option 2")
// process option 2
// ...
// reset drop-down to show the prompt text
optionsCell.clearViewData(object);
redrawRow(index);
}
});
table.addColumn(optionsColumn, "options");
The first option is just a prompt text and after each selection change the drop-down list is reset to show the prompt.
The disadvantage is that you can not have different sets of options for different rows as the list is generated once for the whole column.

How to create an ArrayList from a dialog box in JavaFX?

Hello having trouble creating an array from a dialog box. I am able to type in the dialog and print out index [0] of ArrayList. But when I press Ok it restarts and replaces index [0] instead of adding to the ArrayList . How do I get the application to keep running instead of restarting?
Original Assignment:
Going back to the GUI assignment. You can modify this to use JavaFX
if you want to.
Create an application that has a button that has “Enter your info.”
When clicked it will present a JDialog that has labels and text boxes
that allow the user to enter their name, email, and phone number. The
JDialog will have buttons OK and Cancel.
When the user clicks Cancel, the dialog will go away without doing
anything else.
When the user clicks OK, the user’s information will be extracted from
the dialog, and dumped out on the console. Notice that you only are
listening for Click events. We will add to that spec.
Define a class to hold the info for a single person. Declare an
ArrayList of this type. When the user clicks OK, extract the info
from the dialog. This time, pass the info to the constructor method
of your class that will hold the info. Add this newly created object
to your array list.
Using an enhanced for loop, dump the ArrayList onto the console.
Add several user info's to the ArrayList, each time, dumping the
entire list to the console.
Sort the ArrayList. Dump the ArrayList onto the console.
public class UsefulGUI extends Application {
#Override
public void start(Stage primaryStage) {
Button button = new Button();
button.setText("Enter your info");
button.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
dialogBox();
}
});
StackPane pane = new StackPane();
pane.getChildren().add(button);
Scene scene = new Scene(pane, 500, 300);
primaryStage.setTitle("Useful GUI");
primaryStage.setScene(scene);
primaryStage.show();
}
public class User {
private String name;
private String email;
private String phone;
public User(String n, String e, String p) {
this.name = n;
this.email = e;
this.phone = p;
}
#Override
public String toString() {
return "Name: " + name + " Email: " + email + " Phone: " + phone;
}
}
public void dialogBox() {
Dialog<User> dialog = new Dialog<>();
ArrayList<User>list = new ArrayList<User>();
dialog.setTitle("User info");
Label name = new Label("Name: ");
Label email = new Label("Email: ");
Label phone = new Label("Phone: ");
TextField textName = new TextField();
TextField textEmail = new TextField();
TextField textPhone = new TextField();
GridPane grid = new GridPane();
grid.add(name, 1, 1);
grid.add(textName, 2, 1);
grid.add(email, 1, 2);
grid.add(textEmail, 2, 2);
grid.add(phone, 1, 3);
grid.add(textPhone, 2, 3);
dialog.getDialogPane().setContent(grid);
ButtonType buttonType = new ButtonType("Ok", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(buttonType, ButtonType.CANCEL);
dialog.setResultConverter(new Callback<ButtonType, User>() {
#Override
public User call(ButtonType b) {
if (b == buttonType) {
return new User(textName.getText(), textEmail.getText(), textPhone.getText());
}
return null;
}
});
Optional<User>info = dialog.showAndWait();
// Adds user to list
list.add(new User(textName.getText(), textEmail.getText(), textPhone.getText()));
System.out.print("Info Added.\n NEWUSER ");
System.out.println(new User(textName.getText(), textEmail.getText(), textPhone.getText()));
//Collections.sort(list);
for (int i = 0; i < list.size(); i++) {
System.out.println(i + ". " + list.get(i));
}
//if (info.isPresent()) {
// System.out.println(info.get());
//}
}
public void quitApplication() {
Platform.exit();
}
public static void main(String[] args) {
launch(args);
}
}

How to make something use the previous value of an integer even after the integer changes

I am new to programming, using JavaFX at the moment for a personal organization tool. I have showed here an arraylist of buttons(called books) and stages(called bookStages), a VBox called addBook, and an Int called bookButtonCount set to 0.
addBook.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
addBooks.getChildren().add(books.get(bookButtonCount));
books.get(bookButtonCount).setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent t) {
bookStages.get(bookButtonCount).show();
System.out.println(bookButtonCount);
}
});
bookButtonCount++;
}
});
The first button adds a button from the "books" arraylist to the VBox. The button from the vbox is supposed to open a stage from the stage arraylist. You should be able to fire the button multiple times, each time adding a new button to the vbox and setting that button to open its own stage. Though it seems that using bookButtonCount as a reference will not work because each time you press a button from the books arraylist in the vbox, it checks for the current value of bookButtonCount.(Which changes as more buttons are added) and opens the wrong stage.
Is there any way to have the action for the button be saved with the value of bookButtonCount at the time it is set only?
If not, how should I set this up?
Here is some more bits of code that may be useful:
ArrayList<Stage> bookStages = new ArrayList();
ArrayList<Button> books = new ArrayList();
for (int i=0;i<10;i++){
books.add(new Button("Book " + (i+1)));
bookStages.add(new Stage());
bookStages.get(i).setTitle("Book " + (i+1));
}
Just register the handler when you create the button and stage:
ArrayList<Stage> bookStages = new ArrayList();
ArrayList<Button> books = new ArrayList();
for (int i=0;i<10;i++){
Button button = new Button("Book " + (i+1));
books.add(button);
Stage stage = new Stage();
bookStages.add(stage);
stage.setTitle("Book " + (i+1));
button.setOnAction(e -> stage.show());
}
and
addBook.setOnAction(e -> {
addBooks.getChildren().add(books.get(bookButtonCount));
bookButtonCount++ ;
});

distinguish between radio buttons in vaadin

I'm building an application which has a few radio buttons and based on the selection the user makes I have to do one thing or another. Now I've used an OptionGroup to create the radio buttons but I don't seem to be able to understand how I can differentiate between radio buttons. In pure java it's pretty straightforward as I would create each radio button and then group them together with a ButtonGroup object but in vaadin I really don't know. The documentation is as usual abysmal, so I'm a bit stuck. Here is some code for you:
public class ConverterComponent extends CustomComponent{
private TextField name2 = new TextField();
private OptionGroup single;
private TextField userInput;
private TextField result;
private Button submit;
private Button reset;
private static final String conversion1 = "Km to miles";
private static final String conversion2 = "Miles to Km";
private static final long serialVersionUID = 1L;
public ConverterComponent(){
submit = new Button("Submit");
reset = new Button("Reset");
result = new TextField();
userInput = new TextField();
result.setEnabled(false);
result.setVisible(false);
userInput.setVisible(false);
reset.setVisible(false);
submit.setVisible(false);
single = new OptionGroup("Select the conversion");
single.addItems(conversion1, conversion2);
reset.addClickListener(new Button.ClickListener(){
#Override
public void buttonClick(ClickEvent event){
clearFields();
getResult().setVisible(false);
}
});
submit.addClickListener(new Button.ClickListener(){
#Override
public void buttonClick(ClickEvent event) {
getResult().setVisible(true);
//NEED TO KNOW WHICH RADIO BUTTON HAS BEEM CLICKED SO THAT i CAN DECIDE WHICH CONVERSION TO USE
}
});
single.addValueChangeListener(new Property.ValueChangeListener(){
#Override
public void valueChange(ValueChangeEvent event) {
clearFields();
/*System.out.println("You chose: " + event.getProperty().getValue().toString() + "\n");
System.out.println("other line " + event.getProperty() + "\n" + " id is " + single.getId() + " size " + single.size());*/
//System.out.println("event is " + event.getProperty().getValue());
switch(event.getProperty().getValue().toString()){
case conversion1:
System.out.println(conversion1);
break;
case conversion2:
System.out.println(conversion2);
break;
}
displayFields();
}
});
}
public OptionGroup getRadioButtons(){
return single;
}
public TextField getResult(){
return result;
}
public TextField getUserInput(){
return userInput;
}
public void displayFields(){
//getResult().setVisible(true);
getUserInput().setVisible(true);
getResetButton().setVisible(true);
getSubmitButton().setVisible(true);
}
public Button getResetButton(){
return reset;
}
public Button getSubmitButton(){
return submit;
}
public void clearFields(){
getResult().setValue("");
getUserInput().setValue("");
}
public void validateInputs(){
}
}
Bear in mind that I have to add more options in the future, but what I'm trying to get to is, when the the user selects a radio button, no matter which, he will get two input boxes one for his input and the other one - read only - displaying the conversion. The point is that when the selection is made and the input boxes are displayed I have to know already what selection the user has made because I have to be able to grab the input and convert it correctly. In the code above I'm displaying the user's choice but I don't have anything to check it or compare it to. Ideally what I would like to do is:
-click the first radio button
-determine which radio button has been selected so I know which conversion to use.
You can use any objects as item ids in Vaadin. For example you could do something like this:
If you for example have an enum presenting different conversions
public enum Conversion {
KM_TO_MILES,
MILES_TO_KM
}
then you could do something like this:
OptionGroup optionGroup = new OptionGroup();
optionGroup.addItem(Conversion.KM_TO_MILES);
optionGroup.setItemCaption(Conversion.KM_TO_MILES, "Km to miles");
optionGroup.addItem(Conversion.MILES_TO_KM);
optionGroup.setItemCaption(Conversion.MILES_TO_KM, "Miles to Km");
optionGroup.addValueChangeListener(e -> {
if (e.getProperty().getValue() == Conversion.KM_TO_MILES) {
// km to miles selected
}
});

How do I know if increment/decrement on JSpinner is pressed?

I have a few JSpinners and they are numeric values starting at 10 and can be incremented until 99.
In my program the user has 15 points to disperse evenly across 6 skills. Every JSpinner has an EventListener to detect if its pressed, but more specifically I need to know which button was pressed so I know which action to take. They dont want to take a point off of strength and have it decrement the Total Points by 1, Instead if the Decrement is pressed it should Add 1.
What would be the best method to execute this?
(Also I am using NetBeans so a bit of the program is autoGenerated.)
Presumably you are somewhere inside a ChangeListener's stateChanged method - take a look at ChangeEvent#getSource()
Ok, your edit made my original answer pretty pointless.
Would creating your own SpinnerModel be a viable option?
I encountered the same problem, this is how I solved the implementation for my actions scenario:
First I collect all arrow buttons:
private static HashMap<String, BasicArrowButton> getSpinnerButtons(JSpinner spinner, String[] arrowNames) {
final Stack<String> arrows = new Stack<String>();
arrows.addAll( Arrays.asList( arrowNames ) );
final HashMap<String, BasicArrowButton> buttons = new HashMap<String, BasicArrowButton>();
while (buttons.size()<2) {
for (final Component c : spinner.getComponents()) {
if (c instanceof BasicArrowButton) {
final BasicArrowButton bab = (BasicArrowButton)c;
for (final String sName : arrows) {
if (sName.equals(bab.getName())&&!buttons.containsKey(sName)) {
buttons.put(sName,bab);
break;
}
}
}
}
}
return buttons;
}
Then I attach some listener:
final String KEY_PROP = ".DIRECTION";
final String BS = spinner.getName(), BN="Spinner.nextButton", BP="Spinner.previousButton";
final String BSKEY = BS+KEY_PROP, BNKEY = BN+KEY_PROP, BPKEY = BP+KEY_PROP;
final HashMap<String, BasicArrowButton> buttons = getSpinnerButtons(spinner, new String[]{BN,BP});
spinner.putClientProperty( BSKEY, 1000);
spinner.putClientProperty( BNKEY, buttons.get(BN).getDirection()*+10000);
spinner.putClientProperty( BPKEY, buttons.get(BP).getDirection()*-10000);
final PropertyChangeListener pcl = new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent evt) {
final JSpinner spinnerRef = ((JSpinner)evt.getSource());
final String pName = evt.getPropertyName();
final short swing = Short.parseShort( String.valueOf(evt.getOldValue()) );
final short val = Short.parseShort( String.valueOf(evt.getNewValue()) );
if (Math.abs(swing)<2D)
System.out.printf("This is a DIRECTION CHANGE\nOld Direction=%s;\nNew Direction=%s;\nProp Value: %s", swing, val, spinnerRef.getClientProperty(pName) ).println();
else //arrows
System.out.printf("This is the CURRENT DIRECTION\nArrow=%s;\nDirection=%s;\nProp Value: %s", swing, val, spinnerRef.getClientProperty(pName) ).println();
System.out.println("==============");
}
};
spinner.addPropertyChangeListener(BSKEY, pcl);
spinner.addPropertyChangeListener(BNKEY, pcl);
spinner.addPropertyChangeListener(BPKEY, pcl);
final ActionListener spinnerActions = new ActionListener() {
private short oldDir=0;
#Override
public void actionPerformed(ActionEvent e) {
final BasicArrowButton bab = ((BasicArrowButton)e.getSource());
final short swingDir = (short)bab.getDirection();
final short newDir = (swingDir!=SwingConstants.NORTH&&swingDir!=SwingConstants.WEST) ? Integer.valueOf(-1).shortValue() : Integer.valueOf(+1).shortValue();
bab.getParent().firePropertyChange(bab.getName()+KEY_PROP, swingDir*1000, newDir);
bab.getParent().firePropertyChange(bab.getParent().getName()+KEY_PROP, oldDir, newDir);
this.oldDir=newDir;
}
};
buttons.get(BP).addActionListener(spinnerActions);
buttons.get(BN).addActionListener(spinnerActions);

Categories