LWUIT: Need help `Back` command is not working properly - java-me

We show a SPLASH screen using form which is followed with MENU form that holds many buttons like about-us, login, feedback etc.
Now I move to LOGIN form that holds menu and back commands. My problem is when the back command is clicked in this form it goes to SPLASH screen.
The expected behavior is the back command in LOGIN form must go back to MENU form and not SPLASH form.
How to do this?
Splash.java
public class Splash extends MIDlet implements ActionListener {
Image img_Splash;
Form frm_Main;
String str_URL;
int Width, Height;
Label lbl_Splash;
Command cmd_Cancel;
public void startApp() {
Display.init(this);
frm_Main = new Form();
try {
//Resources theme = Resources.open("/44444.res");
img_Splash = Image.createImage("/res/splash.png");
Resources theme = Resources.open("/666666.res");
UIManager.getInstance().setThemeProps(
theme.getTheme(theme.getThemeResourceNames()[0]));
} catch (IOException io) {
io.printStackTrace();
Dialog.show("Theme Exception", io.getMessage(), "Ok", null);
}
lbl_Splash = new Label(img_Splash);
lbl_Splash.getStyle().setBgColor(16777215);
frm_Main.addComponent(lbl_Splash);
frm_Main.setScrollable(true);
cmd_Cancel = new Command("Cancel");
frm_Main.addCommand(cmd_Cancel);
frm_Main.addCommandListener(this);
frm_Main.show();
// th
Thread splashThread = new Thread() {
public void run() {
try {
sleep(5000);
} catch (InterruptedException ex) {
ex.printStackTrace();
} finally {
MainMenu mainmenu = new MainMenu(frm_Main);
mainmenu.show();
}
}
};
splashThread.start();
}
public void pauseApp() {
}
public void destroyApp(boolean unconditional) {
//notifyDestroyed();
}
public void actionPerformed(ActionEvent ae) {
Command con = ae.getCommand();
String str_CmdName = con.getCommandName();
if (str_CmdName.equals("Cancel")) {
notifyDestroyed();
}
}
}
Mainmenu.java
class MainMenu extends Form implements ActionListener {
Form frm_Main;
//MainMidlet main;
public Button btn_main_Login, btn_main_NewUser, btn_main_Help;
public Label lbl_main_Login, lbl_main_NewUser, lbl_main_Help;
public Image img_main_Login, img_main_NewUser, img_main_Help;
public Command cmd_Exit, cmd_Select;
public MainMenu(Form form) {
this.frm_Main = form;
try {
img_main_Login = Image.createImage("/res/btn_main_login.png");
img_main_NewUser = Image.createImage("/res/btn_main_newuser.png");
img_main_Help = Image.createImage("/res/btn_main_help.png");
} catch (IOException io) {
io.printStackTrace();
//Dialog.show("Image not Found!", io.getMessage(), "Ok", null);
System.out.println("Image not found" + io.getMessage());
}
//--------- Whole form define as BorderLayout with three Container.
BorderLayout bor_MainMenuLayout = new BorderLayout();
setLayout(bor_MainMenuLayout);
setScrollable(false);
//----------- Define Container for Header On North
Container con_Header = new Container();
lbl_Header = new Label(img_Header);
con_Header.addComponent(lbl_Header);
//----------- Define Container as GridLayout and place
//----------- on BorderLayout Center position
//--------- Define Container(CENTER) for search details
//--------- with BoxLayout
BoxLayout bx_CenterLayout = new BoxLayout(BoxLayout.Y_AXIS);
Container con_Center = new Container(bx_CenterLayout);
con_Center.setScrollableY(true);
con_Center.getStyle().setPadding(0, 10, 3, 3);
//--------- FlowLayout for Header Details
FlowLayout flw_MenuHdr = new FlowLayout();
Container con_HdrDetails = new Container(flw_MenuHdr);
lbl_MenuHdr = new Label("Menu");
lbl_MenuHdr.getStyle().setBgTransparency(0);
lbl_MenuHdr.getStyle().setPadding(0, 5, 10, 0);
con_HdrDetails.addComponent(lbl_MenuHdr);
con_Center.addComponent(con_HdrDetails);
//---------- GridLayout define 1 rows and 3 coloumn
//---------- First row
GridLayout grd_Row1Layout = new GridLayout(1, 3);
Container con_Row1Layout = new Container(grd_Row1Layout);
btn_main_Login = new Button(img_main_Login);
btn_main_Help = new Button(img_main_Help;
btn_main_NewUser = new Button(img_main_NewUser);
con_Row1Layout.addComponent(btn_main_Login);
con_Row1Layout.addComponent(btn_main_Help);
con_Row1Layout.addComponent(btn_main_NewUser);
con_Center.addComponent(con_Row1Layout);
//----------- Add Command on softkey
cmd_Exit = new Command("Exit");
cmd_Select = new Command("Select");
addCommand(cmd_Select);
addCommand(cmd_Exit);
addCommandListener(this);
addComponent(BorderLayout.NORTH, con_Header);
addComponent(BorderLayout.CENTER, con_Center);
//this.getStyle().setBgColor(12105912);
frm_Main.getStyle().setBgColor(12105912);
}
public void actionPerformed(ActionEvent ae) {
Command cmd = ae.getCommand();
String str_CmdName = cmd.getCommandName();
//----------- When Click on Exit Button
if (str_CmdName.equals("Exit")) {
//System.exit(0);
//frm_Main.notifyAll();
}
//----------- When Click on Select Button
if (str_CmdName.equals("Select")) {
//----------- When Click on Login
if (btn_main_Login.hasFocus()) {
String str_MemberId = GlobalClass.getInstance().getMemberId();
if (!(str_MemberId == "" || str_MemberId == null)) {
SearchDiamond searchdiamond = new SearchDiamond(frm_Main);
searchdiamond.setTransitionInAnimator(
Transition3D.createRotation(800, true));
searchdiamond.show();
} else {
Login login = new Login(frm_Main);
login.setTransitionInAnimator(
Transition3D.createRotation(800, true));
login.show();
}
}
//----------- When Click on New User
if (btn_main_NewUser.hasFocus()) {
//Dialog.show("New User", "NewUser", "Ok", null);
NewUser newuser = new NewUser(frm_Main);
//newuser.setTransitionInAnimator(
CommonTransitions.createFade(1500));
newuser.setTransitionInAnimator(
Transition3D.createRotation(800, true));
newuser.show();
}
//----------- When Click on Help
if (btn_main_Help.hasFocus()) {
Help help = new Help(frm_Main);
help.setTransitionInAnimator(
Transition3D.createRotation(800, true));
help.show();
}
//----------- When Click on Exit
if (btn_main_Exit.hasFocus()) {
System.exit(0);
}
}
}
}
Login.java
class Login extends Form implements ActionListener {
Form frm_Main;
Label lbl_Header, lbl_Footer, lbl_SepLine, lbl_HdrAlreadyMember, lbl_UserID, lbl_PWD,
lbl_Blank2, lbl_Blank3, lbl_HdrNewMember, lbl_Info;
TextField txtf_UserID, txtf_PWD;
Button btn_Login;
Command cmd_Back, cmd_AboutUs, cmd_Privacy;
public Login(Form form) {
this.frm_Main = form;
//--------- Whole form define as BorderLayout with three Container.
BorderLayout bor_LoginLayout = new BorderLayout();
setLayout(bor_LoginLayout);
setScrollable(false);
//--------- Define Container(NORTH) for Header.
Container con_Header = new Container();
lbl_Header = new Label();
con_Header.addComponent(lbl_Header);
//--------- Define Container(CENTER) for search details
//--------- with BoxLayout
BoxLayout bx_CenterLayout = new BoxLayout(BoxLayout.Y_AXIS);
Container con_Center = new Container(bx_CenterLayout);
con_Center.setScrollableY(true);
con_Center.getStyle().setMargin(5, 5, 0, 0);
//--------- FlowLayout for Header Details
FlowLayout flw_HdrLayout = new FlowLayout();
Container con_HdrDetails = new Container(flw_HdrLayout);
lbl_HdrAlreadyMember = new Label("Already a Member?");
lbl_HdrAlreadyMember.setAlignment(Component.LEFT);
con_HdrDetails.addComponent(lbl_HdrAlreadyMember);
con_Center.addComponent(con_HdrDetails);
//--------- BoxLayout for Login details
BoxLayout bx_Login1Layout = new BoxLayout(BoxLayout.Y_AXIS);
Container con_Login1Details = new Container(bx_Login1Layout);
con_Login1Details.setScrollableY(true);
lbl_UserID = new Label("User Name:");
txtf_UserID = new TextField("");
txtf_UserID.setFocusable(true);
txtf_UserID.setFocus(true);
txtf_UserID.setConstraint(TextField.ANY);
txtf_UserID.setInputMode("abc");
lbl_PWD = new Label("Password:");
txtf_PWD = new TextField("");
txtf_PWD.setConstraint(TextField.PASSWORD);
con_Login1Details.addComponent(lbl_UserID);
con_Login1Details.addComponent(txtf_UserID);
con_Login1Details.addComponent(lbl_PWD);
con_Login1Details.addComponent(txtf_PWD);
//--------- BoxLayout for Login Button
FlowLayout flw_LoginBtnLayout = new FlowLayout(CENTER);
Container con_LoginBtnDetails = new Container(
flw_LoginBtnLayout);
con_LoginBtnDetails.setScrollableY(true);
btn_Login = new Button("Login");
btn_Login.setPreferredSize(new Dimension(80, 25));
btn_Login.setAlignment(Component.CENTER);
con_LoginBtnDetails.addComponent(btn_Login);
con_Login1Details.addComponent(con_LoginBtnDetails);
con_Center.addComponent(con_Login1Details);
//--------- BoxLayout for other Login details
BoxLayout bx_Login2Layout = new BoxLayout(BoxLayout.Y_AXIS);
Container con_Login2Details = new Container(bx_Login2Layout);
con_Login2Details.setScrollableY(true);
con_Login2Details.getStyle().setMargin(5, 5, 10, 10);
//--------- Login type 3 New Remember Me
chk_RememberMe = new CheckBox("Remember Me");
chk_RememberMe.setTickerEnabled(false);
con_Login2Details.addComponent(chk_RememberMe);
//--------- Login type 3 New Forgot Password
btn_ForgotPWD = new Button("Forgot Password?");
btn_ForgotPWD.setTickerEnabled(false);
btn_ForgotPWD.setAlignment(Component.LEFT);
btn_ForgotPWD.setTextPosition(Component.RIGHT);
con_Login2Details.addComponent(btn_ForgotPWD);
con_Center.addComponent(con_Login2Details);
con_Center.getStyle().setPadding(0, 0, 10, 10);
addComponent(BorderLayout.NORTH, con_Header);
addComponent(BorderLayout.CENTER, con_Center);
cmd_Back = new Command("Back");
this.setBackCommand(cmd_Back);
addCommand(cmd_Back);
addCommandListener(this);
//---------- Add More Command for Menu item
cmd_AboutUs = new Command("About Us");
cmd_Privacy = new Command("Privacy");
addCommand(cmd_AboutUs);
addCommand(cmd_Privacy);
//------- When Login Button is Clicked
btn_Login.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
....
}
});
}
public void actionPerformed(ActionEvent ae) {
Command con = ae.getCommand();
String str_CmdName = con.getCommandName();
if (str_CmdName.equals("Back")) {
// here back code
frm_Main.setTransitionInAnimator(
Transition3D.createRotation(800, true));
frm_Main.showBack();
}
....
if (str_CmdName.equals("About Us")) {
AboutUs aboutus = new AboutUs(frm_Main);
aboutus.show();
}
if (str_CmdName.equals("Privacy")) {
Privacy privacy = new Privacy(frm_Main);
privacy.show();
}
}
}
EDIT: Added the form's source code

Got it!
In MainMenu(...) constructor you are storing the reference of SPLASH screen in the class variable frm_Main, this class variable you are passing to the Login(...) constructor in the MainMenu.actionPerformed(...) so effectively you are passing the reference of Splash form object. You need to pass the current class which is MainMenu's reference to the Login(...) constructor and NOT the MainMenu.frm_Main.
Do this, if you don't expect to get back to the Splash screen from MainMenu screen:
public MainMenu(Form form)
{
this.frm_Main = this; //by referring to `MainMenu.this` and not input
//parameter `form` which is referring to Splash
//object
...
If you want to maintain the back reference for MainMenu screen than do this in MainMenu.actionPerformed(...)
Login login = new Login(/*global variable for `MainMenu.this`*/);

Related

Codename one Layered Layout not fill the screen

I implemented floating button with this thread : How to achieve Floating Action Button in Codenameone?
but I have an layout issue. THe content doesn want to fill the screen. Here the screenshot :
Here how I created the content :
final Container paneContainer = new Container(new LayeredLayout());
private Container getBottomContainer(Form parent) {
newsfeedContainer.setLayout(new BoxLayout(BoxLayout.Y_AXIS));
newsfeedContainer.setScrollableY(true);
loadData();
newsfeedContainer.addPullToRefresh(new Runnable() {
public void run() {
loadData();
}
});
//newsfeedContainer.add(new Button("Button")).add(new Button("Button")).add(new Button("Button")).add(new Button("Button")).add(new Button("Button"));
return newsfeedContainer;
}
private Container getUpperContainer(Form par) {
FlowLayout flow = new FlowLayout(Component.RIGHT);
flow.setValign(Component.BOTTOM);
Container conUpper = new Container(flow);
Button plus = new Button();
FontImage.setMaterialIcon(plus, FontImage.MATERIAL_ADD, 5);
plus.addActionListener((ActionEvent evt) -> {
Form f = new PostComment().commentForm(parent);
f.getToolbar().setBackCommand(parent.getTitle(), BACK_POLICY, e -> parent.showBack());
f.show();
});
conUpper.addComponent(plus);
conUpper.setScrollableX(false);
conUpper.setScrollableY(false);
return conUpper;
}
public Container getContainer(Form parent) {
this.parent = parent;
paneContainer.setScrollableY(false);
paneContainer.addComponent(BorderLayout.center(getBottomContainer(parent)));
paneContainer.addComponent(BorderLayout.south(getUpperContainer(parent)));
return paneContainer;
}
How to make the container fill the screen and make the 'plus' button in the bottom right properly?
Make your Form BorderLayout and place the paneContainer in the center

MonoTouch DialogViewController - why must it be in the first place of a UINavigationController?

I want to use a DialogViewController inside of a UITabViewController.
Problem: Nested elements don't show a navigation bar, and so it is not possible to go back.
When I push my class (inherited from DialogViewController) to a UINavigationController, then the behavior is correct. If I use the same class in a tab of a UITabViewController (even with an underlying UINavigationController), then the behaviour is wrong.
Can anyone help me out?
Although the question is not assisted with some code sample, I made a small example hoping to solve your question. For this example I used the Tabbed Application template which comes with Xamarin.iOS and named it TabbingTest.
The following code goes in the AppDelegate. Change the FinishedLaunching method to contain:
public override bool FinishedLaunching (UIApplication app, NSDictionary options)
{
window = new UIWindow (UIScreen.MainScreen.Bounds);
var viewControllers = new UIViewController[]
{
CreateTabFor("Test", "first", new TestDialogController ()),
CreateTabFor("Second", "second", new SecondViewController ()),
};
tabBarController = new UITabBarController ();
tabBarController.ViewControllers = viewControllers;
tabBarController.SelectedViewController = tabBarController.ViewControllers[0];
window.RootViewController = tabBarController;
window.MakeKeyAndVisible ();
return true;
}
Then add the following methods:
private int _createdSoFarCount = 0;
private UIViewController CreateTabFor(string title, string imageName, UIViewController view)
{
var controller = new UINavigationController();
controller.NavigationBar.TintColor = UIColor.Black;
var screen = view;
SetTitleAndTabBarItem(screen, title, imageName);
controller.PushViewController(screen, false);
return controller;
}
private void SetTitleAndTabBarItem(UIViewController screen, string title, string imageName)
{
screen.Title = NSBundle.MainBundle.LocalizedString (title, title);
screen.TabBarItem = new UITabBarItem(title, UIImage.FromBundle(imageName),
_createdSoFarCount);
_createdSoFarCount++;
}
Create a class named TestDialogController and paste the following code inside.
using System;
using MonoTouch.Dialog;
using MonoTouch.UIKit;
namespace TabbingTest
{
public class TestDialogController : DialogViewController
{
public TestDialogController (): base(UITableViewStyle.Plain,null,false)
{
var root = new RootElement ("Tabbing test"){
new Section (){
new RootElement ("First level", 0, 0) {
new Section (null, "This is the first level."){
new RootElement ("Second level", 0, 0) {
new Section (null, "This is the second level."){
new BooleanElement ("Flipflops", false)
}
}
}
}}
};
this.Root = root;
}
}
}
Now run the application.
You can see that even the nested elements show up nicely in the navigation bar. Even with multilevel nesting.

How to control flow of multiple Rss Files

I developed RssFeed Application using LWUIT j2me(java) for 2 xml files, now I want to show those 2 xml files on LWUIT Tabs.
That means, when my application runs, default tab will be displayed (on that tab my first Rss xml file Titles should be displayed), and when the user click on tab2 my second Rss xml titles should be displayed.
I am able to display the same titles of one rss files on both the tabs, how to control my flow to achieve my task?
Here my code:
public class XMLMidlet extends MIDlet implements ActionListener {
public XMLMidlet() {
Display.init(this);
news = new Vector();
m_backCommand = new Command("Back");
cmdExit = new Command("EXIT");
cmdDetails = new Command("Details");
}
public void startApp() {
//RssFeed URL's
String urls[] = {"http://topnews-23.rss",
"http://topstory-12.rss"};
for(int i=0;i<urls.length;i++){
ParseThread myThread = new ParseThread(this,urls[i]);
//this will start the second thread
myThread.getXMLFeed(urls[i]);
}
}
//method called by the parsing thread
public void addNews(News newsItem,String url) {
try{
news.addElement(newsItem);
form1 = new Form();
myNewsList = new List(newsVector);
newsList =new List(newsVector);
myNewsList.setRenderer(new NewsListCellRenderer());
newsList.setRenderer(new NewsListCellRenderer());
tabs=new Tabs(Component.TOP);
tabs.addTab("TopNews", myNewsList);
tabs.addTab("Topstory",newsList);
form1.addComponent(tabs);
form1.show();
}
catch(Exception e){
e.printStackTrace();
}
}
You should move below code
myNewsList = new List(newsVector);
newsList =new List(newsVector);
myNewsList.setRenderer(new NewsListCellRenderer());
newsList.setRenderer(new NewsListCellRenderer());
tabs=new Tabs(Component.TOP);
form1 = new Form();
tabs=new Tabs(Component.TOP);
tabs.addTab("TopNews", myNewsList);
tabs.addTab("Topstory",newsList);
from addNews method to constructor XMLMidlet. addNews method should use url parameter to differ for which list the newsItem is directed.
Update
Below is how I think you should implement addNews method:
public void addNews(News newsItem, String url) {
if (url.endsWith("topnews-20.rss")) {
myNewsList.addElement(newsItem);
} else if (url.endsWith("topstory-25.rss")) {
newsList.addElement(newsItem);
}
}
serRenderer does not need to be called from addNews and form1.show() should be moved to startApp.

LWUIT 1.5 How to capture tab click event, fetch content from server and show it in selected tab?

I am using LWUIT 1.5 tabs to show notifications. I have three Tabs and I fetch notifications from a php web service. I successfully fetched list of notifications for first Tab. But for next two Tabs I am failing to understand what code I should write to
Detect that second/third Tab is clicked. I know how to add commandListener to a Button. What commandListener is there for Tab selection?
How to refresh content of a Tab when new data is received from the server?
private void showNotificationList() {
try {
Form f = new Form("Notifications");
f.setScrollable(false);
f.setLayout(new BorderLayout());
final List list = new List(getNotifications()); //gets hashtables - notices
list.setRenderer(new GenericListCellRenderer(createGenericRendererContainer(), createGenericRendererContainer()));
list.setSmoothScrolling(true);
//System.out.println("adding list component to listview");
list.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
int i = list.getSelectedIndex();
noticeDetailsForm(notices[i]);
//Dialog. show( "title", notices[i].toString(), "ok", "exitt");
}
});
//Container c2 = new Container(new BoxLayout(BoxLayout.Y_AXIS));
//c2.addComponent(list);
Tabs tabs = new Tabs(Tabs.TOP);
tabs.addTab("Recent", list);
tabs.addTab("Urgent", new Label("urgent goes here"));
tabs.addTab("Favourites", new Label("favs goes here"));
//f.addComponent(tabs);
f.addComponent(BorderLayout.CENTER, tabs);
Command backComm = new Command("Back") {
public void actionPerformed(ActionEvent ev) {
Dashboard.dbInstance.setUpDashboard();
}
};
f.addCommand(backComm);
//System.out.println("showing lsit form");
f.show();
} catch (Exception ex) {
ex.printStackTrace();
}
}
private Container createGenericRendererContainer() throws IOException { //System.out.println("container called");
//System.out.println("container called");
Container c = new Container(new BorderLayout());
c.setUIID("ListRenderer");
Label xname = new Label("");
Label description = new Label();
Label focus = new Label("");
Container cnt = new Container(new BoxLayout(BoxLayout.Y_AXIS));
xname.setName("Name");
xname.getStyle().setBgTransparency(0);
xname.getStyle().setFont(Font.createSystemFont(Font.FACE_SYSTEM, Font.STYLE_BOLD, Font.SIZE_MEDIUM));
//description.setFocusable(true);
description.setName("Description");
cnt.addComponent(xname);
cnt.addComponent(description);
c.addComponent(BorderLayout.CENTER, cnt);
Button thumb = new Button(Image.createImage("/res/home-work.png"));
//Image img = Image.createImage("/res/home-work.png");
c.addComponent(BorderLayout.WEST, thumb);
return c;
}
private Hashtable[] getNotifications() {
int total = notices.length;
//System.out.println(total);
Hashtable[] data = new Hashtable[total];
//Hashtable[] data = new Hashtable[5];
/data[0] = new Hashtable();
data[0].put("Name", "Shai");
data[0].put("Surname", "Almog");
data[0].put("Selected", Boolean.TRUE);/
for (int i = 0; i < total; i++) {
data[i] = new Hashtable();
//System.out.println(notices[i].getName());
data[i].put("Name", notices[i].getName());
data[i].put("Description", notices[i].getDescription());
data[i].put("Id", Integer.toString(notices[i].getId()));
}
return data;
}
1)I had the same problem and I solved it by overriding Keyreleased of the Form not the Tab
and inside it I check for the component that is focused and if it is the Tab get "tab.selectedIndex" to detect in which Tab I am and load appropriate data .
Here is Sample code(this inside the my derived form that extends Form )
**
public void keyReleased(int keyCode) {
Component p=this.getFocused();
String str= p.getClass().getName();
if(str.toLowerCase().indexOf("radiobutton")!=-1){ // Radiobutton because when u
Here do tab specific work focus on the
tab it returns radiobutton.
lwuit understands tabs as list
of radiobuttons
}**
2)and about refreshing the data I did a solution and I don't Know if its right
I get the new data , create new List and remove the old one and attach the new one then
call Form.repaint();

Monotouch.dialog EntryElement not being updated after editing

I'm using this code to create the dialog:
SettingsDialog settingDialog = new SettingsDialog ();
RootElement dialog = settingDialog.CreateDialog ();
DialogViewController dv = new DialogViewController (dialog, true);
dv.ViewDissapearing += delegate(object sender1, EventArgs e1) {
// update the values
Config.VendorId = settingDialog.VendorId;
} ;
NavigationController.PushViewController (dv, true);
Ths is the code for the SettingsDialogClass
public class SettingsDialog
{
private EntryElement idElement;
public RootElement CreateDialog ()
{
idElement = new EntryElement ("Vendor Id", string.Empty, Config.VendorId.ToString (CultureInfo.InvariantCulture)){ KeyboardType = UIKeyboardType.NumberPad };
element = new RootElement ("Configuration"){
new Section (){
idElement
} ,
...
}
public string VendorId {
get {
return idElement.Value;
}
}
The problem is that the above property ALWAYS returns the old value, it never gets updated.
Any idea why?
Thank,
Ignacio
I found the answer to my question, this thread had the key to it
How can I pass data into MonoTouch.Dialog's delegates?
this line:
i was able to get around it by calling field.FetchValue() before trying to retrieve it
So I modified the property as
public string VendorId {
get {
idElement.FetchValue();
return idElement.Value;
}
}

Resources