first of all Im working on a time tracking page with login authentication using ldap.
For the login I created a dialogbox setting verticalpanel as its widget. My verticalpanel contains two textboxes to enter username/password and one button to send data to the ldap server.
On module load the dialogbox pops up and gets the time tracking content on login success.
To my question:
"LoginWidget" and "LoginClickHandler" have separated classes, hence I need to get the login button on module load to add "LoginClickHandler".
What is the best way to handle this? - since I know that my solution isnt that good.
LoginWidget class
public class LoginWidget{
private Button loginButton;
private DialogBox dialogBox;
private TextBox tbxUser;
private PasswordTextBox tbxPw;
private Label lblUser;
private Label lblPW;
private Label lblError;
public LoginWidget(){
dialogBox = new DialogBox();
tbxUser = new TextBox();
tbxPw = new PasswordTextBox();
lblUser = new Label();
lblPW = new Label();
lblError = new Label();
dialogBox.setText("Login");
dialogBox.setAnimationEnabled(true);
loginButton = new Button("Login");
// set the id of a widget by accessing its Element
loginButton.getElement().setId("closeButton");
final HTML serverResponseLabel = new HTML();
VerticalPanel dialogVPanel = new VerticalPanel();
dialogVPanel.addStyleName("dialogVPanel");
dialogVPanel.add(lblUser);
lblUser.setText("User:");
dialogVPanel.add(tbxUser);
dialogVPanel.add(lblPW);
lblPW.setText("PW:");
dialogVPanel.add(tbxPw);
dialogVPanel.add(lblError);
dialogVPanel.add(serverResponseLabel);
dialogVPanel.setHorizontalAlignment(HasHorizontalAlignment.ALIGN_RIGHT);
dialogVPanel.add(loginButton);
dialogBox.setWidget(dialogVPanel);
dialogBox.show();
dialogBox.center();
}
public Button getLoginButton(){
return loginButton;
}
public DialogBox getDialogBox(){
return dialogBox;
}
public TextBox getTbxUser(){
return tbxUser;
}
public TextBox getTbxPw(){
return tbxPw;
}
public Label getLblError(){
return lblError;
}
}
LoginClickHandler class
public class LoginClickHandler implements ClickHandler {
/**
*/
private LoginWidget lw;
private ServiceImplURL serviceImplURL;
private TimeTracking dtt = new TimeTracking();
public LoginClickHandler(ServiceImplURL sIU, LoginWidget _lw){
/**
*/
this.lw = _lw;
this.serviceImplURL = sIU;
}
public void onClick(ClickEvent event) {
/**
*/
serviceImplURL.getRpcLdap().authenticate(lw.getTbxPw().getText(), lw.getTbxUser().getText(), new AsyncCallback<Boolean>() {
/**
*/
#Override
public void onSuccess(Boolean isLdapAuthOk) {
/**
*/
if(isLdapAuthOk){
lw.getDialogBox().hide();
User user = new User(lw.getTbxUser().getText(), lw.getTbxPw().getText());
serviceImplURL.getRpcSession().setUsername(user.getUsername(), new AsyncCallback<Void>() {
#Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
#Override
public void onSuccess(Void result) {
// TODO Auto-generated method stub
}
});
serviceImplURL.getRpcDB().insertUser(user.getUsername(), new AsyncCallback<Void>() {
/**
*/
#Override
public void onFailure(Throwable caught) {
/*
* connection error to implement
*/
}
#Override
public void onSuccess(Void result) {
/*
* do nothing
*/
}
});
dtt.loadContent();
}
else{
lw.getLblError().setStyleName("error");
lw.getLblError().setText("Passwort oder Username falsch!");
}
}
#Override
public void onFailure(Throwable caught) {
// TODO Auto-generated method stub
}
});
}
}
My Entrypoint
#Override
public void onModuleLoad() {
/**
*/
loadLoginWidget();
}
/**
* Creates the login pop up.
*/
public void loadLoginWidget(){
/**
*/
LoginWidget lw = new LoginWidget();
LoginClickHandler lch = new LoginClickHandler(serviceImplURL, lw);
lw.getLoginButton().addClickHandler(lch);
}
I already tried to extend Button but I dont think its a difference.
Pass a listener class (eg. your LoginClickHandler) to the view constructor:
public LoginWidget( LoginClickHandler listener )
{
...
loginButton.addClickHandler( listener )
...
}
More generally you may want to interject an interface defining the actions and have LoginClickHandler implement it:
public interface LoginListener
{
void onLogin();
...
}
public class LoginWidget
{
public LoginWidget( LoginListener listener )
{
this.listener = listener;
Button loginButton = new Button( "Login" );
loginButton.addClickHandler( new ClickHandler()
{
public void onClick( ClickEvent event ) { listener.onLogin(); }
} );
}
...
}
and finally
public class LoginClickHandler implements LoginListener
{
#Override public void onLogin()
{
serviceImplURL.getRpcLdap()...
...
}
}
and
public void loadLoginWidget()
{
LoginWidget lw = new LoginWidget( new LoginClickHandler() );
...
}
Cheers,
Related
I am struggling with a problem using TinySound (http://finnkuusisto.github.io/TinySound/). I've made a method to play a sound (i've implemented the Music class, since it allows to be played without a thread sleep limiter). My problem is that the "Play" button in my GUI can be spammed, resulting in the sound or music being played in a stack. I've checked out the setMultiClickThreshold in the Java API, but this do not solve my problem (You never know how long the sound or music-file is going to be).
Has anyone used TinySound, or know a workaround this challenge?
Here is the code for the method (I will provide more if necessary):
public void playSound(String filePath) {
soundFile = new File(filePath);
TinySound.init();
Music sound = TinySound.loadMusic(soundFile);
sound.play(false);
while(sound.done()) {
TinySound.shutdown();
}
}
Consider using a SwingWorker, disabling the JButton on button press, and re-enabling it when the SwingWorker has completed its actions. The re-enabling could be done within a PropertyChangeListener that has been added to your Swingworker and that responds to a PropertyChangeEvent.newValue() of SwingWorker.StateValue.DONE.
For example, your code could look something like,....
public class SwingworkerEg {
// .....
public void playSound(String filePath) {
soundFile = new File(filePath);
TinySound.init();
Music sound = TinySound.loadMusic(soundFile);
sound.play(false);
while (sound.done()) {
TinySound.shutdown();
}
}
// The JButton or menu item's Action or ActionListener class
private class PlayAction extends AbstractAction {
#Override
public void actionPerformed(ActionEvent e) {
// disable the button or menu item
setEnabled(false);
// create worker to play music in a background thread
// pass in the file path
PlayWorker playWorker = new PlayWorker(filePath);
// listen for when the worker thread is done
playWorker.addPropertyChangeListener(new PlayWorkerListener(this));
// execute the worker (in a background thread)
playWorker.execute();
}
}
// To listen for when the worker is done
class PlayWorkerListener implements PropertyChangeListener {
private PlayAction playAction;
// pass in the Action so we can re-enable it when done
public PlayWorkerListener(PlayAction playAction) {
this.playAction = playAction;
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
// if the worker is done
if (evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
// re-enable the button
playAction.setEnabled(true);
}
}
}
// this is to call playSound in a background thread
class PlayWorker extends SwingWorker<Void, Void> {
private String filePath;
// pass in the file path String
public PlayWorker(String filePath) {
this.filePath = filePath;
}
#Override
protected Void doInBackground() throws Exception {
// this is called in a background thread
playSound(filePath);
return null;
}
}
}
Here's a trivial working example:
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.*;
#SuppressWarnings("serial")
public class SwingWorkerEg2 extends JPanel {
private JSpinner spinner = new JSpinner(new SpinnerNumberModel(3, 3, 10, 1));
public SwingWorkerEg2() {
add(new JLabel("Seconds to wait:"));
add(spinner);
add(new JButton(new FooAction("Please Press Me!")));
}
// The JButton or menu item's Action or ActionListener class
private class FooAction extends AbstractAction {
public FooAction(String name) {
super(name); // set button name
int mnemonic = (int) name.charAt(0); // get first letter as int
putValue(MNEMONIC_KEY, mnemonic); // set button mnemonic for first letter
}
#Override
public void actionPerformed(ActionEvent e) {
// disable the button or menu item
setEnabled(false);
int spinnerValue = ((Integer) spinner.getValue()).intValue();
// create worker to play music in a background thread
FooWorker playWorker = new FooWorker(spinnerValue);
// listen for when the worker thread is done
playWorker.addPropertyChangeListener(new FooWorkerListener(this));
// execute the worker (in a background thread)
playWorker.execute();
}
}
// To listen for when the worker is done
class FooWorkerListener implements PropertyChangeListener {
private FooAction fooAction;
// pass in the Action so we can re-enable it when done
public FooWorkerListener(FooAction fooAction) {
this.fooAction = fooAction;
}
#Override
public void propertyChange(PropertyChangeEvent evt) {
// if the worker is done
if (evt.getNewValue().equals(SwingWorker.StateValue.DONE)) {
// re-enable the button
fooAction.setEnabled(true);
}
}
}
// this is to call count down in a background thread
class FooWorker extends SwingWorker<Void, Void> {
private int spinnerValue;
// pass in the file path String
public FooWorker(int spinnerValue) {
this.spinnerValue = spinnerValue;
}
#Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < spinnerValue; i++) {
System.out.println("count is: " + i);
Thread.sleep(1000);
}
System.out.println("count is: " + spinnerValue);
return null;
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("SwingWorker Example");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new SwingWorkerEg2());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
Make sure to read Concurrency in Swing for more on how to use SwingWorkers
Got it to work! Thank you very much! I will try to implement it in my ActionController class, it is a bit messy keeping everything in the same method in the SoundHandler ;)
here is the final working SoundHandler:
import java.io.File;
import javax.swing.SwingWorker;
import kuusisto.tinysound.Music;
import kuusisto.tinysound.TinySound;
import imports.ActionController;
import imports.GUI;
/**
* This class handles the playing of the sound and extends SwingWorker so that
* the JFrame do not freeze when the sound is played.
*
* #author Gaute Gjerlow Remen
* #version 1.0
*/
public class SoundHandler extends SwingWorker<Void, Void> {
private GUI gui;
private ActionController actionController;
private File soundFile;
public SoundHandler() {
actionController = new ActionController(this);
gui = new GUI(actionController);
}
/**
* Plays the sound file in another thread
* #param filePath
* #throws Exception if the thread is interrupted
* #return null when doInBackground is finished
*/
public void playSound(String filePath) {
soundFile = new File(filePath);
SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {
#Override
protected Void doInBackground() throws Exception {
TinySound.init();
Music sound = TinySound.loadMusic(soundFile);
sound.play(false);
while (!sound.done()) {
gui.unablePlayButton();
}
gui.enablePlayButton();
TinySound.shutdown();
return null;
}
};
worker.execute();
}
/**
* #return file opened in the GUI
*/
public String openFile() {
return gui.openFile();
}
/**
* Calls the about window in GUI
*/
public void showAbout() {
gui.showAbout();
}
/**
* Calls the showNoSong window in GUI
*/
public void showNoSong() {
gui.showNoSong();
}
/**
* Calls the changeSongLabel window in GUI
*/
public void changeSongLabel() {
gui.changeSongLabel();
}
/**
* A empty method made only for the extending of the class
*/
#Override
protected Void doInBackground() throws Exception {
// TODO Auto-generated method stub
return null;
}
}
I've created a vaadin table. When I do right-click it shows context menu with +New... text and when I click on it - it shows modal window with two tables. Every table has the same fuctionality.
The problem is that every time I open and close modal window it adds duplicates for context menu items on modal tables(on the main page it works correct). Moreover - it adds several modal windows when I click on modal table context menu (for example if I open window 5 times - it add 5 context menu items and 5 modal windows for clicked modal context menus)
The only way to return to one item - restart whole application.
What is the problem?
Every my table looks like this
#Component("taskTable")
#Scope("prototype")
public class TaskTable extends AbstractObjectTable {
#Autowired
private TaskService taskService;
#Autowired
private NewTaskWindow taskWindow;
#Autowired
private ShowTaskDetailsWindow detailsWindow;
private Action[] action = new Action[] { new Action("+New...") };
#Override
public Table createTable() {
caption = "Tasks";
headers = new String[] { "Description", "Project", "Status", "Weight", "Developer", "ID" };
this.addActionHandler(new Handler() {
#Override
public Action[] getActions(Object target, Object sender) {
return action;
}
#Override
public void handleAction(Action action, Object sender, Object target) {
switch(action.getCaption()) {
case "+New...": {
PmcUi.getCurrent().addWindow(taskWindow.createWindow());
break;
}
}
//what to do for action
}
});
this.addItemClickListener(new ItemClickListener(){
#Override
public void itemClick(ItemClickEvent event) {
if (event.isDoubleClick()) {
PmcUi.getCurrent().addWindow(detailsWindow.createWindow());
}
return;
}
});
return super.createTable();
}
#Override
protected IndexedContainer projectDatasource() {
IndexedContainer indexedContainer = new IndexedContainer();
for(String header: headers) {
indexedContainer.addContainerProperty(header, String.class, "");
}
List<Task> tasks = taskService.findAllTasks();
for(int i = 0; i < tasks.size(); i++) {
Object id = indexedContainer.addItem();
Task item = tasks.get(i);
indexedContainer.getContainerProperty(id, headers[0]).setValue(item.getDescription());
indexedContainer.getContainerProperty(id, headers[1]).setValue(item.getTaskProject());
indexedContainer.getContainerProperty(id, headers[2]).setValue(item.getStatus());
indexedContainer.getContainerProperty(id, headers[3]).setValue(item.getWeight());
indexedContainer.getContainerProperty(id, headers[4]).setValue(item.getTaskDeveloper());
indexedContainer.getContainerProperty(id, headers[5]).setValue(item.getTaskId());
}
return indexedContainer;
}
}
Where AbstractObjectTable
public abstract class AbstractObjectTable extends Table {
protected String caption;
protected String[] headers = null;
protected Table createTable() {
this.setContainerDataSource(projectDatasource());
this.setVisibleColumns(headers);
this.setSelectable(true);
this.setImmediate(true);
return this;
}
protected abstract IndexedContainer projectDatasource();
}
My +New... modal windows looks similar to that
#Component("newTaskWindow")
public class NewTaskWindow {
private Window createTaskWindow;
#Autowired
private TaskService taskService;
public Window createWindow() {
createTaskWindow = new Window("New Task");
initWindow();
fillWindow();
return createTaskWindow;
}
private void initWindow() {
createTaskWindow.setSizeUndefined();
createTaskWindow.setResizable(false);
createTaskWindow.setModal(true);
createTaskWindow.addCloseListener(new CloseListener() {
#Override
public void windowClose(CloseEvent e) {
Notification.show("Closed");
}
});
}
private void fillWindow() {
final TextField taskDescription = new TextField("Description");
final ComboBox taskProject = new ComboBox("Select project");
final ComboBox taskDeveloper = new ComboBox("Select developer");
final TextField taskWeight = new TextField("Task weight");
final TextField taskStatus = new TextField("Task status");
Button create = new Button("Create");
create.addClickListener(new Button.ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
Task task = new Task();
task.setTaskId(UUID.randomUUID().toString());
task.setStatus(taskStatus.getValue());
task.setTaskDeveloper(taskDeveloper.getValue().toString());
task.setTaskProject(taskProject.getValue().toString());
task.setWeight(taskWeight.getValue());
task.setDescription(taskDescription.getValue());
taskService.insertTask(task);
createTaskWindow.close();
}
});
Button close = new Button("Cancel");
close.addClickListener(new Button.ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
createTaskWindow.close();
}
});
HorizontalLayout layout = new HorizontalLayout(create, close);
FormLayout formLayout = new FormLayout(taskProject, taskDeveloper, taskWeight, taskStatus,
taskDescription, layout);
formLayout.setMargin(true);
createTaskWindow.setContent(formLayout);
}
}
And my details windows also have similar architecture.
#Component("showTaskDetailsWindow")
public class ShowTaskDetailsWindow {
private Window showDetailsWindow;
#Autowired
private TaskService taskService;
public Window createWindow() {
showDetailsWindow = new Window("Show details");
initWindow();
fillWindow();
return showDetailsWindow;
}
private void initWindow() {
showDetailsWindow.setSizeUndefined();
showDetailsWindow.setResizable(false);
showDetailsWindow.setModal(true);
showDetailsWindow.addCloseListener(new CloseListener() {
#Override
public void windowClose(CloseEvent e) {
Notification.show("Closed");
}
});
}
private void fillWindow() {
final TextField taskDescription = new TextField("Description");
final TextField taskProject = new TextField("Task project");
final TextField taskDeveloper = new TextField("Task developer");
final TextField taskWeight = new TextField("Task weight");
final TextField taskStatus = new TextField("Task status");
FormLayout formLayout = new FormLayout(taskProject, taskDeveloper, taskWeight, taskStatus, taskDescription);
formLayout.setMargin(true);
showDetailsWindow.setContent(formLayout);
}
}
What is the problem? Why it is continuously multiplying?
The problem is your getActions implementation
#Override
public Action[] getActions(Object target, Object sender) {
return new Action[] { new Action("+New...")};
}
You should create one instance of the "new Action("+New...")" item and store it for example in the TaskTable object.
The getActions(..) should alsways return the same instance.
If you always create a new action, it just adds them to the already existing actions.
Looks like the createTable() method of the TaskTable class is called too many times but the provided code doesn't show where that method is called. That causes that multiple action handlers and item click listeners are added to a table.
I have an application that after successfull login (on a JFrame), starts to create the main frame (class MainUI that extends from JFrame). That MainUI class contains a JTabbedPane (which each tab is a class that extends from JPanel) and, on setVisible method, creates and shows each tab.
I want to add on the login form, after successfull login, a Spinner image to indicate that the MainUI is being created.
After display the Spinner image, I invoke the creation of the MainUI and call the setVisible method on EventQueue.invokeLater(); but the Spinner image is not updated. If I use new Thread(runner).start(); is updated, but I get a lot of Component creation must be done on Event Dispatch Thread
Some code of Login.java:
buttonLogin.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
login();
}
});
private void login()
{
//check DB and permissions
//if all is ok
lMsj.setIcon(spinner);
new Thread(new Runnable() {
public void run() {
showMainUI(usr);
}
}).start();
}
private void showMainUI(final Usuario usr)
{
Runnable runner = new Runnable() {
public void run() {
final MainUI mui = new MainUI();
mui.setVisible(true);
dispose();
}
};
EventQueue.invokeLater(runner);
}
and some code of MainUI.java
public MainUI()
{
SwingUtilities.invokeLater(new Runnable() {
#Override public void run() {
setMinimumSize(new Dimension(1280, 960));
createComponents();
}
});
}
private void initComponents()
{
//..
// menuItem = new ...
// ...
}
#Override
public void setVisible(boolean value)
{
//..
if (Security.get().isAllowed("tab1")){
addTab1();
}
//..
}
private void addTab1(){
//..
getTabbedPane().addTab("Tab1", new Tab1());
//..
}
How I can fix this, so that the image is updated and the user interface is created in the "background"?
I am developing a GWT project on eclipse, and when I run the Development Mode everything works fine. But when I deploy the WAR file (generated following this guide click) on my tomcat server, http://localhost:8080/myproj/ shows only a blank page.
I tried to add Window.alert("..") as first line in onModuleLoad() method and it DOES show correctly.
Clearing browser-cache was useless.
Server startup executes without problems nor exceptions.
What should I do to solve this problem?
This is my entry point class
public class Segnalazioni_Degrado implements EntryPoint {
protected static List<Macrocategoria> listaMacrocategorie;
protected static List<Segnalazione> segnalazioniAttiveCached = new ArrayList<Segnalazione>();
protected static List<SegnalazioneRisolta> segnalazioniRisolteCached = new ArrayList<SegnalazioneRisolta>();
protected static final DataLayerServiceAsync dataLayerService = GWT
.create(DataLayerService.class);
protected static final LoginServiceAsync loginService = GWT
.create(LoginService.class);
protected static final MailServiceAsync mailService = GWT
.create(MailService.class);
protected static Properties props;
private final String TITOLO = "PORTALE SEGNALAZIONI DEGRADO";
private LatLng romaLatLng;
private DockLayoutPanel mainPnl;
private HorizontalPanel northPnl;
private HorizontalPanel southPnl;
private VerticalPanel westPnl;
private AbsolutePanel centerPnl;
protected static StatsPanel statsPnl;
protected static MenuPanel menuPnl;
protected static LoginPanel loginPnl;
protected static LegendPanel legendPnl;
protected static MapWidget map;
private Label titoloLbl;
private/* Button */FocusWidget areaRiservataBtn;
private Button followUsOnTwitterBtn;
private HTML mailto;
/**
* TODO tweet segnalazione inserita o risolta, porta su .css tutto il
* possibile, prendi tutto da config, fai log su server, crea mail, leggenda
* icone, elimina file foto non solo link
*/
public void onModuleLoad() {
loadProps();
buildUI();
}
void loadProps() {
props.set("scarsa manutenzione manto stradale", "images/red.png");
props.set("veicolo abbandonato", "images/red.png");
props.set("discarica abusiva", "images/green.png");
props.set("accumulo spazzatura", "images/green.png");
}
void buildUI() {
Maps.loadMapsApi("", "2", false, new Runnable() {
public void run() {
buildHomePage();
}
});
}
private void buildHomePage() {
mainPnl = new DockLayoutPanel(Unit.PCT);
mainPnl.setStyleName("mainPanel");
northPnl = new HorizontalPanel();
northPnl.setStyleName("northPanel");
southPnl = new HorizontalPanel();
southPnl.setStyleName("southPanel");
westPnl = new VerticalPanel();
westPnl.setStyleName("westPanel");
centerPnl = new AbsolutePanel();
centerPnl.setStyleName("centerPnl");
loginPnl = new LoginPanel();
statsPnl = new StatsPanel();
menuPnl = new MenuPanel();
Segnalazioni_Degrado.dataLayerService
.getListaMacrocategorie(new AsyncCallback<List<Macrocategoria>>() {
#Override
public void onFailure(Throwable caught) {
caught.printStackTrace();
}
#Override
public void onSuccess(List<Macrocategoria> result) {
Segnalazioni_Degrado.listaMacrocategorie = result;
centerPnl.add(new LegendPanel());
}
});
/**
* costruisco la Google Map
*/
Size mapSize = Size.newInstance(500, 500);
MapOptions mapOpts = MapOptions.newInstance();
mapOpts.setSize(mapSize);
romaLatLng = LatLng.newInstance(41.8902624, 12.4923096);
map = new MapWidget(romaLatLng, 12, mapOpts);
map.checkResizeAndCenter();
map.setSize("99%", "99%");
map.addControl(new LargeMapControl());
map.setDoubleClickZoom(true);
map.setScrollWheelZoomEnabled(true);
map.setStyleName("map");
/**
* costruisco il titolo del portale
*/
titoloLbl = new Label(TITOLO);
titoloLbl.setStyleName("titolo");
/**
* costruisco bottone per accedere ad area riservata
*/
/* areaRiservataBtn = new Button("Accedi all'area riservata"); */
areaRiservataBtn = new Button("AREA RISERVATA");
areaRiservataBtn.setStyleName("bottomBtn");
areaRiservataBtn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
new AreaRiservataDialog();
}
});
/**
* costruisco bottone twitter
*/
followUsOnTwitterBtn = new Button();
followUsOnTwitterBtn.addStyleName("bottomBtn");
followUsOnTwitterBtn.addStyleName("twitter");
followUsOnTwitterBtn
.getElement()
.appendChild(
new HTML(
"<div><img src=images/twitter.gif><b>segui #stop_degrado</b></div>")
.getElement());
followUsOnTwitterBtn.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Window.open("https://twitter.com/stop_degrado", "_blank", "");
}
});
/**
* costruisco bottone mailto
*/
mailto = new HTML("<a href=mailto:dummy#fake.foo> Contattaci </a>");
mailto.setStyleName("bottomBtn");
/**
* creo bottone ABOUT US
*/
Button aboutus = new Button("ABOUT US");
aboutus.setStyleName("bottomBtn");
aboutus.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
new AboutUsPopup();
}
});
northPnl.add(titoloLbl);
northPnl.add(loginPnl);
westPnl.add(menuPnl);
westPnl.add(statsPnl);
southPnl.add(followUsOnTwitterBtn);
southPnl.add(aboutus);
southPnl.add(areaRiservataBtn);
southPnl.add(mailto);
centerPnl.add(map);
mainPnl.addNorth(northPnl, 8);
mainPnl.addWest(westPnl, 30);
mainPnl.addSouth(southPnl, 3.5);
mainPnl.add(centerPnl);
RootLayoutPanel.get().add(mainPnl);
MenuPanel.refreshBtn.click();
}
}
I think it is a NullPointer:
protected static Properties props; // << NULL
public void onModuleLoad() {
loadProps(); // props is still NULL
buildUI();
}
void loadProps() {
// props is still NULL
props.set("scarsa manutenzione manto stradale", "images/red.png"); // BANG!
[...]
By the way:
Why did you make props static? There is only one instance of you EntryPoint. So no state can be shared.
I have a ButtonField on MainScreen, from which I am pushing a PopupScreen where I have added an ObjectListfield. What I want to do is to update the label of ButtonField on MainScreen with the element selected from ObjectListfield of PopupScreen.
Please tell me if it is possible to do without using Dialog class (I really want to use PopupScreen and not Dialog class) and the method by which this can be done. I'd appreciate if some sample code will be provided.
I have added my code.
public final class MyScreen extends MainScreen {
HorizontalFieldManager hfm;
ButtonField btn;
public MyScreen() {
// Set the displayed title of the screen
super();
setTitle("MyTitle");
btn = new ButtonField("label",ButtonField.CONSUME_CLICK);
final mypopup mps = new mypopup();
btn.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field,int context) {
UiApplication.getUiApplication().pushModalScreen(mps);
}
});
hfm = new HorizontalFieldManager();
hfm.add(btn);
add(hfm);
}
public void setlabel(String labelnew) {
btn.setLabel(labelnew);
}
public String getlabel() {
return this.btn.getLabel();
}
}
class mypopup extends PopupScreen implements FieldChangeListener {
String it;
ObjectListField obj = new ObjectListField() {
public boolean navigationClick(int status,int time) {
int selectedindex=obj.getSelectedIndex();
it=(String)obj.get(obj, selectedindex);
UiApplication.getUiApplication().popScreen(UiApplication.getUiApplication().getActiveScreen());
/*MyScreen my=new MyScreen();
my.btn.setLabel(it);
my.invalidate(); */
//close();
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
/* This im doing to see that setlabel and getlabel are
working properly */
MyScreen my=new MyScreen();
my.setlabel(it);
String gt=my.getlabel();
Dialog.alert(gt);
my.hfm.invalidate();
//the label of button is changed but not updating in mainscreen.
}
});
return true;
}
};
public mypopup() {
super(new VerticalFieldManager());
String[] type=new String[] {"a","b","c","d"};
obj.set(type);
add(obj);
}
public void fieldChanged(Field field, int context) {
// TODO Auto-generated method stub
}
}
You need to change following block of code,
MyScreen my = new MyScreen();
my.setlabel(it);
String gt = my.getlabel();
Dialog.alert(gt);
my.hfm.invalidate();
With the code block,
Screen scr = UiApplication.getUiApplication().getActiveScreen();
if (scr instanceof MyScreen) {
MyScreen my = (MyScreen) scr;
my.setlabel(it);
my.invalidate();
}
Add the button in one Manager either HorizontalFieldManager or VerticalFieldManager and after setting text on button invalidate the managerlike this way
public final class MyScreen extends MainScreen
{
ButtonField btn;
public MyScreen()
{
// Set the displayed title of the screen
super();
setTitle("MyTitle");
btn=new ButtonField("label",ButtonField.CONSUME_CLICK);
final mypopup mps=new mypopup();
btn.setChangeListener(new FieldChangeListener()
{
public void fieldChanged(Field field,int context){
UiApplication.getUiApplication().pushModalScreen(mps);
}
});
HorizontalFieldManager hfmToholdButtons = new HorizontalFieldManager();
btn.setLabel(mps.gettext());
hfmToholdButtons.add(btn);
hfmToholdButtons.invalidate();
}
}