I don't know how to show another page on button click in blackberry using java.
I assume you have a ButtonField added to some kind of Screen. You need to set the FieldChangeListener for the ButtonField:
class YourScreen extends FullScreen {
public YourScreen() {
super();
ButtonField btn = new ButtonField("mybutton");
btn.setChangeListener(new FieldChangeListener() {
public void fieldChanged(Field field, int context) {
synchronized (UiApplication.getApplication().getEventLock()) {
UiApplication.getUiApplication().pushScreen(new FullScreen());
}
}
});
add(btn);
}
}
Also note that you need to either get the event lock before pushing the screen or pass UiApplication.invokeLater a Runnable like so:
UiApplication.getUiApplication().invokeLater(new Runnable() {
public void run() {
UiApplication.getUiApplication().pushScreen(new FullScreen());
}
});
Some basics on UI threading issue on BB here: http://www.thinkingblackberry.com/archives/182
UiApplication.getUiApplication.pushScreen(new Screen());
http://www.blackberry.com/developers/docs/4.5.0api/index.html
Related
I am trying to make a password checker, and I am trying to have an icon set as X until the user meets the condition of the password being at least 8 characters long. I am trying to set up a while loop for while the program is running, which will in turn run another while loop which will update the icon. I am doing this because a want it to always be checking to see if the condition is met and not need the user to click a button for example. I have placed the code inside the initComponents of the public form PasswordCheckerUI, but when I hit run on the program, it says running but my GUI doesn't pop up. How would I change the code to make this work(if needed) or where would I have to move it to? I have tried making a public static void with the code and calling it within the initCompnents, but it yielded the same results. Lastly, I tried to call the method within the main method, but the variables aren't static so that did not work either
public class PasswordCheckerUI extends javax.swing.JFrame {
public PasswordCheckerUI() {
initComponents();
while (Thread.currentThread().isAlive()) {
while (txtPassword.getText().length() < 8) {
lblMinCharIcon.setIcon(X);
if (txtPassword.getText().length() >= 8) {
lblMinCharIcon.setIcon(Check);
}
}
}
}
}
Events in Swing don't just happen when the user clicks on a button - they happen all the time (when moving the mouse, when clicking, when editing text, when ...) and they are therefore the best way to solve your problem.
You can for example listen the document change events on the txtPassword and change the icon depending on the new length of the password:
public class PasswordCheckerUI {
private JTextField txtPassword;
private JLabel lblMinCharIcon;
public PasswordCheckerUI() {
txtPassword = new JTextField(40);
txtPassword.getDocument().addDocumentListener(
new DocumentListener() {
#Override
public void insertUpdate(DocumentEvent e) {
checkPasswordLen(txtPassword);
}
#Override
public void removeUpdate(DocumentEvent e) {
checkPasswordLen(txtPassword);
}
#Override
public void changedUpdate(DocumentEvent e) {
checkPasswordLen(txtPassword);
}
}
);
}
private void checkPasswordLen(JTextField tf) {
if (tf.getText().length() < 8) {
lblMinCharIcon.setIcon(x);
} else {
lblMinCharIcon.setIcon(check);
}
}
}
I have a custom widget which is can accept a widget inside of it. Here is the code:
public class CustomDivWidget extends Widget {
protected Element divElement = DOM.createDiv();
public CustomDivWidget() {
divElement.getStyle().setWidth(100, Unit.PX);
divElement.getStyle().setHeight(100, Unit.PX);
divElement.getStyle().setBorderStyle(BorderStyle.SOLID);
divElement.getStyle().setBorderWidth(1, Unit.PX);
divElement.getStyle().setBorderColor("blue");
setElement(divElement);
}
public void add(Widget child) {
divElement.appendChild(child.getElement());
}
}
Then this is how I used it:
public void onModuleLoad() {
CustomDivWidget customDiv = new CustomDivWidget();
TextButton button = new TextButton("Button 1");
button.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
Window.alert("Button 1 clicked!");
}
});
customDiv.add(button);
RootPanel.get().add(customDiv);
}
When I run it, it show correctly the widget I want like this :
But the problem is, the click handler was not working when I tried to click the button. The questions are :
Why it is not working?
What should I do to make it working?
Any comments or suggestions will be appreciated. Thanks and regards.
I think you are bypassing GWT's event system this way (I'm not sure though). However, why not using a FlowPanel?
protected FlowPanel fp = new FlowPanel();
public CustomDivWidget() {
fp.getElement().getStyle().setWidth(100, Unit.PX);
fp.getElement().getStyle().setHeight(100, Unit.PX);
fp.getElement().getStyle().setBorderStyle(BorderStyle.SOLID);
fp.getElement().getStyle().setBorderWidth(1, Unit.PX);
fp.getElement().getStyle().setBorderColor("blue");
setElement(fp.getElement());
}
Apart from that, why are you using DOM elements instead of widgets? Using widgets instead of having to deal with the DOM is one of the key features of a toolkit like GWT (just my opinion here).
Edit : try to attach the handler directly to the DOM, to see if it makes any difference :
DOM.setEventListener(button.getElement(), new EventListener() {
#Override
public void onBrowserEvent(Event e) {
switch (DOM.eventGetType(e)) {
case Event.ONCLICK:
System.out.println("click");
break;
}
}
});
I am just wondering...
When I click refresh button my gwt app comes to its default UI state despite its UI was modified during client-server interactions (callbacks) etc... But sometimes it is really essential thing to "cache" UI if user clicks refresh by mistake or reopened web page which user still logged-in;
So my question is...
Is there a way to restore gwt app UI (its before-refreshed state) in some standard way? Can History tokens help for this kind of issue?
edit
Concerning the history tokens I saw this example :
History.addValueChangeHandler(new ValueChangeHandler<String>() {
public void onValueChange(ValueChangeEvent<String> event) {
String historyToken = event.getValue();
// Parse the history token
try {
if (historyToken.substring(0, 4).equals("page")) {
String tabIndexToken = historyToken.substring(4, 5);
int tabIndex = Integer.parseInt(tabIndexToken);
// Select the specified tab panel
tabPanel.selectTab(tabIndex);
} else {
tabPanel.selectTab(0);
}
} catch (IndexOutOfBoundsException e) {
tabPanel.selectTab(0);
}
}
});
... and I could notice it restores tabIndex from history; so will it help if tab panel won't be init-ed by module load (by default) but something this way:
//on button click...
getSimplePanel().setWidget(new MyTabbedPane());
edit
To be more clear here is my test code which I am trying to figure out how to restore MainUI I mean its previous UI state as if refresh button wasn't clicked.
the EntryPoint...
public class Main implements EntryPoint {
private SimplePanel simplePanel;
public void onModuleLoad() {
RootPanel rootPanel = RootPanel.get();
FlowPanel flowPanel = new FlowPanel();
rootPanel.add(flowPanel, 10, 10);
flowPanel.setSize("410px", "280px");
Button setWidgetButton = new Button("Click");
setWidgetButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
getSimplePanel().setWidget(new MainUI());
}
});
flowPanel.add(setWidgetButton);
simplePanel = new SimplePanel();
flowPanel.add(simplePanel);
}
protected SimplePanel getSimplePanel() {
return simplePanel;
}
}
...and composite;
public class MainUI extends Composite {
private VerticalPanel verticalPanel;
int index;
public MainUI() {
FlowPanel flowPanel = new FlowPanel();
initWidget(flowPanel);
Button button = new Button("+");
button.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
getVerticalPanel().add(new Label(""+(++index)+": "+Math.random()));
}
});
flowPanel.add(button);
DecoratorPanel decoratorPanel = new DecoratorPanel();
flowPanel.add(decoratorPanel);
verticalPanel = new VerticalPanel();
decoratorPanel.setWidget(verticalPanel);
}
protected VerticalPanel getVerticalPanel() {
return verticalPanel;
}
}
...and, as a result, to have "cached" ui state without regenerating it again with extracting strings from history tokens and re-instantiate objects or what so ever...
for example if I have this UI (see image) I am interested to have totally the same one after refresh button is pressed...
but I am not pretty sure which way should I look for? I haven't seen any gwt snippet in this direction; So I really need your advice what way should I dig in?
Any useful comment is appreciated
Thanks
P.S. GWT 2.3
I think you miss to store the state into the URLs-Hashtag.
You can use GWTP (as suggested in the comments)
In fact you need to read the Hashtag in your onModuleLoad and restore your state.
This may work with getHash():
String state = Window.Location.getHash();
myRestoreStateFromTokenMethod(state);
update
Here are some snippets to create a push store.
List<String> states = [...]
public void onClick(){ states.add("newState");changeHash(states); }
public void changeHash(){
String hash = states.get(0) + ";"
for(other states) hash += states.get(i);
// use a UrlBuilder to set the Hash
}
Documentation for UrlBuilder
Or you can try this: https://github.com/jbarop/gwt-pushstate
I want my GUI to make some checks when a JOptionPane appears.
Because I can't find any other way, I though I can do those each time the application window loses focus(its just checking a string). For that reason I added the following code on my JFrame:
appFrame.addWindowListener(new WindowAdapter() {
#Override
public void windowLostFocus(WindowEvent e) {
System.out.println("Focus Lost");
}
#Override
public void windowClosing(WindowEvent e) {
//some other stuff here that work
}
});
The window closing listener works fine. Although when the JFrame isn't focused nothing happens. Shouldn't "Focus Lost" be printed each time I switch from JFrame to some other window? Also, will this method be triggered when a JOptionPane is shown?
The key to me is that you want a change in the GUI triggered by a change of a String variable. The best way I see to solve this is to make the String variable a bound property by using PropertyChangeListenerSupport. This way you can have the GUI attach a PropertyChangeListener to the class that holds the String variable and then be notified when it changes allowing you to update the GUI appropriately.
If you go this route, consider giving the observed class a SwingPropertyChangeSupport field so that the listeners will be notified on the Swing event thread and hopefully avoid any Swing concurrency issues.
Here's a brief example:
import java.awt.Dimension;
import java.awt.event.*;
import java.beans.*;
import javax.swing.*;
import javax.swing.event.SwingPropertyChangeSupport;
public class ShowPropertyChangeSupport {
#SuppressWarnings("serial")
private static void createAndShowGui() {
final MainGUI mainGui = new MainGUI("Title");
final ObservedClass observedClass = new ObservedClass();
observedClass.addPropertyChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent pcEvt) {
if (pcEvt.getPropertyName().equals(ObservedClass.BOUND_PROPERTY)) {
mainGui.setTitle(pcEvt.getNewValue().toString());
}
}
});
mainGui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
mainGui.pack();
mainGui.setLocationRelativeTo(null);
mainGui.setVisible(true);
int timerDelay = 6000; // every 6 seconds
new Timer(timerDelay, new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
String result = JOptionPane.showInputDialog(mainGui,
"Please enter a String", "Set GUI title", JOptionPane.PLAIN_MESSAGE);
if (result != null) {
observedClass.setBoundProperty(result);
}
}
}){{setInitialDelay(1000);}}.start();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
// ** note that I don't like extending JFrame,
// but will do this for sake of example simplicity
class MainGUI extends JFrame {
public MainGUI(String title) {
super(title);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(400, 300);
}
}
class ObservedClass {
public static final String BOUND_PROPERTY = "bound property";
private String boundProperty = "";
private SwingPropertyChangeSupport spcSupport = new SwingPropertyChangeSupport(
this);
public SwingPropertyChangeSupport getSpcSupport() {
return spcSupport;
}
public void setSpcSupport(SwingPropertyChangeSupport spcSupport) {
this.spcSupport = spcSupport;
}
public String getBoundProperty() {
return boundProperty;
}
public void setBoundProperty(String boundProperty) {
String oldValue = this.boundProperty;
String newValue = boundProperty;
this.boundProperty = newValue;
spcSupport.firePropertyChange(BOUND_PROPERTY, oldValue, newValue);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
spcSupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
spcSupport.removePropertyChangeListener(listener);
}
}
The key to all this in my mind is to use the listener so that the class with the bound property -- the String being listened to -- has no knowledge of the GUI, the listener, and the GUI, likewise has no knowledge of the class with the bound property. They are fully decoupled.
I'm not going to go into why you are doing what you are doing, but it is not working as you expect for the following reason:
WindowAdapter is a convenience class so you can create one listener and register it for multiple types of events. You have only registered it for one set of events, you need to also register it for focus events via: Window.addWindowFocusListener()
WindowAdapter adapter = new WindowAdapter() {
#Override
public void windowLostFocus(WindowEvent e) {
System.out.println("Focus Lost");
}
#Override
public void windowClosing(WindowEvent e) {
//some other stuff here that work
}
};
appFrame.addWindowListener(adapter);
appFrame.addWindowFocusListener(adapter);
1) JOptionPane / modal JDialog have got modality issue, but modality could be advantage if all containers have got own owner, for real workaround you need to know (I'll talking about how can I do test that)
numbers of Window[], and if isDisplayable(), then you can use follows
you can get SwingUtilities#getAccessibleIndexInXxx can returns AccessibleState
KeyboardFocusManager (very interesting methods for multi-touch) returns getXxxFocusXxx methods
Focus, FocusSubsystem is pretty asynchronous,
2) Please, with due respect, I don't know why you needed that, for why reasons I need to know about that, there is about business rules, you always need to know ...., and if is done on EDT
Focus, FocusSubsystem is pretty asynchronous,
Now that I am able to set the content of my second wizard's page depending on the first page selection, I am looking for a way to give the focus to my 2nd page's content when the user clicks the next button on the first page.
By default, when the user click the next button, the focus is given to the button composite (next, back or finish button depending on the wizard configuration)
The only way I found to give focus to my page's content is the following one:
public class FilterWizardDialog extends WizardDialog {
public FilterWizardDialog(Shell parentShell, IWizard newWizard) {
super(parentShell, newWizard);
}
#Override
protected void nextPressed() {
super.nextPressed();
getContents().setFocus();
}
}
To me it's a little bit "boring and heavy" to have to override the WizardDialog class in order to implement this behavior. More over, the WizardDialog javadoc says:
Clients may subclass WizardDialog, although this is rarely required.
What do you think about this solution ? Is there any easier and cleaner solution to do that job ?
This thread suggests:
In your wizard page, use the inherited setVisible() method that is called automatically before your page is shown :
public void setVisible(boolean visible) {
super.setVisible(visible);
// Set the initial field focus
if (visible) {
field.postSetFocusOnDialogField(getShell().getDisplay());
}
}
The postSetFocusOnDialogField method contains :
/**
* Posts <code>setFocus</code> to the display event queue.
*/
public void postSetFocusOnDialogField(Display display) {
if (display != null) {
display.asyncExec(
new Runnable() {
public void run() {
setFocus();
}
}
);
}
}
VonC's answer works great, I personally found it to be a little easier to work with like this though:
#Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (visible) {
Control control = getControl();
if (!control.setFocus()) {
postSetFocus(control);
}
}
}
private void postSetFocus(final Control control) {
Display display = control.getDisplay();
if (display != null) {
display.asyncExec(new Runnable() {
#Override
public void run() {
control.setFocus();
}
});
}
}