I'm trying to make a quiz in Java but I'm having trouble accessing the array list data from the tester class and therefore my question text isn't showing up. I have three classes; tester, quiz interface and quiz set up. I've been playing around with it for a while and I'm pretty sure I'm starting to make things worse so I thought I'd post on here.
The questions are added to the array list in the Tester file but I can't seem to access this in the set up class for this method:
public void setQuestion(int randIndex) {
qi.getQuText().setText(getQuestionList().get(randIndex).getQuestionText());
}
Expected output was to take a random question from the array list and display the question text but instead nothing appears and it is blank.
I'm fairly new to Java and programming so any detailed answers are welcome! Thanks in advance.
import java.util.ArrayList;
public class QuizTester {
private static ArrayList<Question> questions; //declares arrayList to holds the questions
public static void main(String[] args) {
QuizSetUp theQuiz = new QuizSetUp();
questions = new ArrayList<Question>(); //constructor
questions.add(new FillInBlank("____________ is the ability of an object to take many forms.", "Polymorphism"));
questions.add(new FillInBlank("The process where one object acquires the properties of another is called __________", "inheritance"));
questions.add(new FillInBlank("The ___________ keyword is used by classes to inherit from interfaces", "implements"));
questions.add(new MultipleChoice("Which programming technique can be used to prevent code and data from being randomly accessed by other code defined outside the class?",
"Polymorphism", "Encapsulation", "Inheritance", "Construction", "Encapsulation"));
theQuiz.pickQuestion();
}
public ArrayList<Question> getQuestionList() {
return this.questions;
}
}
////////////////////////quiz set up file.
public class QuizSetUp {
private QuizInterface qi;
private QuizTester test;
//private ArrayList<Question> questions; //declares arrayList to holds the questions
private int counter = 1;
Random random;
int randIndex;
public QuizSetUp() {
setInterface();
//questions = new ArrayList<Question>(); //constructor
}
private enum QuAnswer { CORRECT,INCORRECT }
public void setInterface() {
qi = new QuizInterface();
test = new QuizTester();
//add action listeners to each of the buttons
ActionListener cl = new ClickListener();
qi.getNextBtn().addActionListener(cl);
qi.getStartQuizBtn().addActionListener(cl);
//allows users to press enter to start quiz rather than having to click quiz button
KeyListener ent = new KeyBoardListener();
qi.getUName().addKeyListener(ent);
qi.getUPassword().addKeyListener(ent);
}
public void pickQuestion() {
randQuestion();
setQuestion(randIndex);
//setAnswer("A", randIndex);
//setAnswer("B", randIndex);
//setAnswer("C", randIndex);
//setAnswer("D", randIndex);
//setCorrectAnswer(randIndex);
//qi.resetTimer();
}
public void setQuestion(int randIndex) {
qi.getQuText().setText(getQuestionList().get(randIndex).getQuestionText());
}
public void setNextQuestion() {
//qi.getTimer().cancel();
//qi.cancelInterval();
if (counter < 5) { //users must answer five questions to complete quiz
pickQuestion();
} else {
//JOptionPane.showMessageDialog(qi.getPanels(), "End of quiz");
//switch to end panel to show results of quiz
}
}
public int randQuestion() {
random = new Random();
randIndex = random.nextInt(questions.size());
return randIndex;
}
//inner listener class for buttons
private class ClickListener implements ActionListener {
public void actionPerformed(ActionEvent evt) {
if (evt.getSource() == qi.getStartQuizBtn()) {
qi.setEnteredName(qi.getUName().getText());
qi.setEnteredPass(qi.getUPassword().getPassword());
validateInput();
} else if (evt.getSource() == qi.getNextBtn()) {
counter++;
if (counter == 5) {
qi.getNextBtn().setText("Finish Quiz"); //changes next button text on final question
}
if (counter < 6) {
qi.getQuProgress().setText(counter + " of 5");
} else {
//shuffle to end panel
}
}
}
}
//inner listener class for key presses
private class KeyBoardListener implements KeyListener {
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_ENTER) {
qi.setEnteredName(qi.getUName().getText());
qi.setEnteredPass(qi.getUPassword().getPassword());
validateInput();
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
//method to validate input by user to log in
public void validateInput() {
//presence check on username
if (qi.getEnteredName().length() > 0) {
//presence check on password
if (qi.getEnteredPass().length > 0) {
//ensures password is at least 6 char long
if(qi.getEnteredPass().length > 5) {
qi.getCards().next(qi.getPanels()); //getPanels() == cardPanel
} else {
JOptionPane.showMessageDialog(null,
"Your password must be at least six characters long.",
"Password Violation", JOptionPane.WARNING_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(null,
"Your did not enter a password.",
"Password Violation", JOptionPane.WARNING_MESSAGE);
}
} else {
JOptionPane.showMessageDialog(null,
"You did not enter a username. Please try again.",
"Username Violation", JOptionPane.WARNING_MESSAGE);
}
}
}
After some alterations, I was able to get your code running. But I have to warn you, there are quite some changes:
QuizTester now only has a main method to start the program. It will initialize and fill the list with questions and then pass it to the QuizSetUp instance
I didn't have your Question class, so I reduced it to an ArrayList<String> (just to make sure, that the questions could be passed)
And I didn't hvae your QuizInterface class so I helped myself with a small implementation that would simply print out the question when a new question gets set
QuizInterface (small helper class)
public class QuizInterface {
private String text;
public QuizInterface() {
}
public String getText() {
return text;
}
public void setText(String text) {
this.text = text;
System.out.println("question text = "+this.text); // this is just to make sure it worked
}
}
QuizSetUp (heavily reduced)
public class QuizSetUp {
private QuizInterface qi;
private ArrayList<String> questions; // uncommented, it's needed now
private int counter = 1;
Random random;
int randIndex;
// I chose to pass the list with the constructor but the setQuestions() will do as well
public QuizSetUp(ArrayList<String> questions) {
this.questions = questions;
setInterface();
}
// NEW method – but it's not needed
public ArrayList<String> getQuestions() {
return questions;
}
// NEW method – but it's not needed
public void setQuestions(ArrayList<String> questions) {
this.questions = questions;
}
private enum QuAnswer {
CORRECT, INCORRECT
}
public void setInterface() {
qi = new QuizInterface();
// test = new QuizTester(); // this is no longer needed since QuizTester is only used to start the program
}
public void pickQuestion() {
randQuestion();
setQuestion(); // randIndex is already a global variable in this class, no need to pass with the method call
}
public void setQuestion() {
// QuizInterface has a new method now called "setText()"
// so here we access the list "questions" (it is already initialized, because we pass it to this class when constructing it)
// this.randIndex is global, so we can use it directly in this method as an index to the questions list (as you already did it)
qi.setText(this.questions.get(this.randIndex));
}
public void setNextQuestion() {
//qi.getTimer().cancel();
//qi.cancelInterval();
if (counter < 5) { //users must answer five questions to complete quiz
pickQuestion();
} else {
//JOptionPane.showMessageDialog(qi.getPanels(), "End of quiz");
//switch to end panel to show results of quiz
}
}
public int randQuestion() {
random = new Random();
randIndex = random.nextInt(questions.size());
return randIndex;
}
// .... the rest I left out here because it is not needed for this little test
}
QuizTester (only needs the main method)
public class QuizTester {
public static void main(String[] args) {
ArrayList<String> questions = new ArrayList<>(); //as you can see I replaced the List with a list of Strings (because I didn't have your Question class)
// so these are only strings...
questions.add("____________ is the ability of an object to take many forms.");
questions.add("The process where one object acquires the properties of another is called __________");
questions.add("The ___________ keyword is used by classes to inherit from interfaces");
questions.add("Which programming technique can be used to prevent code and data from being randomly accessed by other code defined outside the class?");
// here I create the QuizSetUp instance and pass the list right with the constructor
QuizSetUp theQuiz = new QuizSetUp(questions);
// if everything works out, calling this method
// should pick a new question, set it to the QuizInterface
// and the QuizInterface (the helper version I made) will print it out
theQuiz.pickQuestion();
}
}
Those three classes can compile as they are and when I ran the program I got this output
question text = The ___________ keyword is used by classes to inherit from interfaces
I know this is a lot different from what you have, the only big change I did was passing the newly create questions list directly to the QuizSetUp instance – so no accessing any static lists.
Looking at this line:
qi.getQuText().setText(getQuestionList().get(randIndex).getQuestionText());
where is the getQuestionList() implemented? It looks like a method call, except that QuizSetUp doesn't declare a getQuestionList() method. It is in a different class.
Conclusion: the code that you've shown us in the question won't even compile.
I should point that this (in QuezSetup) is very bad style, dnd liable to cause confusion.
private static ArrayList<Question> questions;
public ArrayList<Question> getQuestionList() {
return this.questions;
}
While this.questions looks like it is referring to an instance variable, it is actually referring to a static variable. The this is misleading.
Related
I'm using RxVertx which is a sort of RxJava along with Java8 and I have a compilation error.
Here is my code:
public rx.Observable<Game> findGame(long templateId, GameModelType game_model, GameStateType state) {
return context.findGame(templateId, state)
.flatMap(new Func1<RxMessage<byte[]>, rx.Observable<Game>>() {
#Override
public Observable<Game> call(RxMessage<byte[]> gameRawReply) {
Game game = null;
switch(game_model) {
case SINGLE: {
ebs.subscribe(new Action1<RxMessage<byte[]>>() {
#Override
public void call(RxMessage<byte[]> t1) {
if(!singleGame.contains(0) {
game = new Game(); // ERROR is at this line
singleGames.put(0, game);
} else {
game = singleGames.get(0); // ERROR is at this line
}
}
});
}
}
return rx.Observable.from(game);
}
});
}
The compilation error is:
"Local variable game defined in an enclosing scope must be final or effectively final"
I cannot define 'game' as final since I do allocation\set and return it at the end of the function.
How can I make this code compile??
Thanks.
I have a Holder class that I use for situations like this.
/**
* Make a final one of these to hold non-final things in.
*
* #param <T>
*/
public class Holder<T> {
private T held = null;
public Holder() {
}
public Holder(T it) {
held = it;
}
public void hold(T it) {
held = it;
}
public T held() {
return held;
}
public boolean isEmpty() {
return held == null;
}
#Override
public String toString() {
return String.valueOf(held);
}
}
You can then do stuff like:
final Holder<Game> theGame = new Holder<>();
...
theGame.hold(myGame);
...
{
// Access the game through the `final Holder`
theGame.held() ....
Since you need to not modify the reference of the object you can wrap the Game in something else.
The quickest (but ugly) fix is to use an array of size 1, then set the content of the array later. This works because the the array is effectively final, what is contained in the array doesn't have to be.
#Override
public Observable<Game> call(RxMessage<byte[]> gameRawReply) {
Game[] game = new Game[1];
switch(game_model) {
case SINGLE: {
ebs.subscribe(new Action1<RxMessage<byte[]>>() {
#Override
public void call(RxMessage<byte[]> t1) {
if(!singleGame.contains(0) {
game[0] = new Game();
singleGames.put(0, game[0]);
} else {
game[0] = singleGames.get(0);
}
}
});
}
}
return rx.Observable.from(game[0]);
}
Another similar option is to make a new class that has a Game field and you then set that field later.
Cyclops has Mutable, and LazyImmutable objects for handling this use case. Mutable is fully mutable, and LazyImmutable is set once.
Mutable<Game> game = Mutable.of(null);
public void call(RxMessage<byte[]> t1) {
if(!singleGame.contains(0) {
game.mutate(g -> new Game());
singleGames.put(0, game.get());
} else {
game[0] = game.mutate(g->singleGames.get(0));
}
}
LazyImmutable can be used to set a value, lazily, once :
LazyImmutable<Game> game = LazyImmutable.def();
public void call(RxMessage<byte[]> t1) {
//new Game() is only ever called once
Game g = game.computeIfAbsent(()->new Game());
}
You cant. At least not directly. U can use a wrapper class however: just define a class "GameContainer" with game as its property and foward a final reference to this container instead.
#dkatzel's suggestion is a good one, but there's another option: extract everything about retrieving/creating the Game into a helper method, and then declare final Game game = getOrCreateGame();. I think that's cleaner than the final array approach, though the final array approach will certainly work.
Although the other approaches look acceptable, I'd like to mention that you can't be sure subscribing to ebs will be synchronous and you may end up always returning null from the inner function. Since you depend on another Observable, you could just simply compose it through:
public rx.Observable<Game> findGame(
long templateId,
GameModelType game_model,
GameStateType state) {
return context.findGame(templateId, state)
.flatMap(gameRawReply -> {
switch(game_model) {
case SINGLE: {
return ebs.map(t1 -> {
Game game;
if (!singleGame.contains(0) {
game = new Game();
singleGames.put(0, game);
} else {
game = singleGames.get(0);
}
return game;
});
}
}
return rx.Observable.just(null);
});
}
I'm trying to create a guitar program. I have a guitar amp class that has a sound object I'm trying to access in my pickup class. My goal is to set the sound property in my pickup class the same as my sound property in the GuitarAmp class so I can then set all the sound properties of my strings. I'm not really sure how to go about doing this and the articles I've read about gets and sets in Java have been no help. I have my two classes listed below, any help with the get and set would be appreciated.
public class GuitarAmp
{
// This is what I want to get from this class
public GuitarAmpSound sound;
public GuitarAmp(GuitarAmpSound sound, int volume, int distortSetting) {
sound = new GuitarAmpSound();
sound.setVolume(64);
sound.setDistortSetting(GuitarAmpSound.JAZZ);
}
public void changeVolume(int newVolume)
{
sound.setVolume(newVolume);
}
}
Here is the pickup class.
public class GuitarPickup {
public GuitarAmpSound pickupSound;
public void Connect(GuitarString strings[], GuitarAmp amp)
{
pickupSound = new GuitarAmpSound();
//This is where I need to set it
for(int i = 1; i <= 6; i++)
{
strings[i].setSound(pickupSound);
}
}
}
You need to declare a field (a variable belonging to a particular instance of a class) to hold each piece of information for that object. The pickupSound field on GuitarPickup is an example.
It is strong convention in Java to use the same name for the field as for the getters and setters. In the case of your volume, for example, the relevant part of the code would look like this:
public class GuitarAmpSound {
private int sound = 0;
public void setSound(int sound) {
this.sound = sound; // "this.sound" means the sound field, not the parameter
}
public int getSound() {
return sound; // or this.sound
}
}
If you want to implement the necessary code for your for loop, your GuitarString class needs a GuitarAmpSound field of its own named sound and a corresponding getter and setter.
As a note, the conditions in your for loop have a number of problems. Arrays in Java are zero-based (so the strings on a 6-string guitar would go from 0 to 5), and you should never hard-code array sizes in a loop but should use strings.length instead. Finally, Java has a more convenient syntax if you just want to retrieve each element in an array (or collection):
for(GuitarString string : strings) {
string.setSound(pickupSound);
}
Your code makes no sense, replace the GuitarAmp class by this:
public class GuitarAmp {
//This is what I want to get from this class
private GuitarAmpSound sound;
public GuitarAmp() {
sound = new GuitarAmpSound();
sound.setVolume(64);
sound.setDistortSetting(GuitarAmpSound.JAZZ);
}
public void changeVolume(int newVolume){
sound.setVolume(newVolume);
}
public GuitarAmpSound getSound() {
return sound;
}
public void setSound(Sound sound) {
this.sound = sound;
}
}
for get and set the rule is simple:
public YourClassName getYourObjectName() {
return yourObjectName;
}
public void setYourObjectName(YourClassName yourObjectName) {
this.yourObjectName = yourObjectName;
}
it's really complicated understand what you really wanna..take a look some change..but
I think you need to reestructure the objects. what you wanna do? can you explain better?
public class GuitarAmp {
//This is what I want to get from this class
public GuitarAmpSound sound;
--> the sound you pass before call the constructor
sound.setVoolume(x);
sound.setDistortSetting(Y)
so you pass the object sound with the attributes full of information
public GuitarAmp(GuitarAmpSound sound){
this.sound = sound;
}
public void changeVolume(int newVolume){
this.sound.setVolume(newVolume);
}
}
Here is the pickup class.
public class GuitarPickup {
public GuitarAmpSound pickupSound;
public void Connect(GuitarString strings[], GuitarAmp amp)
{
pickupSound = new GuitarAmpSound();
//This is where I need to set it
for(int i = 0; i<strings.length; i++)
{
amp.setSound(strings[i].getSound());
}
}
}
Conceptually, there is little point in saving the same Sound value to each GuitarString.
I'm a newbie in java and I have a small problem. I want to access a variable in one class from another. I have three classes and I want to be able to access a variable in the main class to enable me read the array.
The error I am getting is
java.lang.SecurityException: MIDlet not constructed by createMIDlet
Please see the example below. Please bear in mind they're all in the same package.
package tungPackage;
import com.sun.lwuit.*;
import com.sun.lwuit.animations.CommonTransitions;
import com.sun.lwuit.events.ActionEvent;
import com.sun.lwuit.events.ActionListener;
import javax.microedition.midlet.MIDlet;
public class TungMidlet extends MIDlet implements ActionListener {
private Command back = new Command("Back");
private Command ok = new Command("Ok");
public ActionListener commandlistListener = new ActionListener() {
public void actionPerformed(ActionEvent cmd) {
// check which command cliked
if (cmd.getCommand() == back) {
// go back to previous form
mainForm.show();
} else if (cmd.getCommand() == ok) {
// go forward
}
}
};
private List list;
private Form mainForm;
private Label promptLabel;
private housesClass houseClassObject = new housesClass();
public int counter; //this is the variable I want to access in a class called calculate class object.
private int sumAmmt;
public TungMidlet tungMidletObject;
public calculateClass calculateClassObject;
public TungMidlet() {
Display.init(this);
}
private ActionListener applistListener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if(list.getSelectedIndex()==0){
counter++;
if (counter>5)
{
//check sum price.
sumAmmt = calculateClassObject.calculateSum();
Dialog x = new Dialog("info");
Label label = new Label("Maximum reached.");
Label label2 = new Label("Sum ammt = "+sumAmmt);
x.addComponent(label);
x.addComponent(label2);
x.addCommand(ok);
x.show();
}
else
{
//calculate the price
String info = houseClassObject.randomHouse();
Dialog x = new Dialog("info");
Label label = new Label(info);
x.addComponent(label);
x.addCommand(ok);
x.show();
}
}
}
};
public void startApp() {
//calculateClassObject = new calculateClass();
//sumAmmt = calculateClassObject.calculate(sumAmmt);
mainForm = new Form("Investment Categories");
promptLabel = new Label("choose category");
list = new List();
list.addItem("House");
list.addItem("Cars");
list.addItem("Schools");
list.addItem("Schools");
list.addItem("Supermarkets");
list.addItem("Stocks");
list.addItem("Land");
list.addActionListener(applistListener);
mainForm.addComponent(promptLabel);
mainForm.addComponent(list);
mainForm.addCommand(back);
mainForm.addCommandListener(commandlistListener);
mainForm.setTransitionInAnimator(CommonTransitions.createSlide(CommonTransitions.SLIDE_HORIZONTAL, true, 1000));
mainForm.show();
}
public void pauseApp() {}
public void destroyApp(boolean unconditional) {}
public void actionPerformed(ActionEvent ae) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
The class I want to access the "counter" variable using is shown below.
package tungPackage;
import java.util.Random;
public class housesClass {
public Random generator = new Random();
public String[] houseArray = new String[5];
public housesClass housesClassObject;
public calculateClass calcobj;// = new calculateClass();
public housesClass()
{
}
public String randomHouse() {
housesClassObject = new housesClass();
houseArray[0] = "Bungalow - 20,000,000 Shillings";
houseArray[1] = "Microhouse - 10,000,000 Shillings";
houseArray[2] = "Flat - 200,000,000 shillings";
houseArray[3] = "Garage apartment - 7,000,000 shillings";
houseArray[4] = "Studio apartment - 13,000,000 shillings";
int rnd = generator.nextInt(houseArray.length);
housesClassObject.housePrices(rnd);///noma
String house = houseArray[rnd];
return house;
}
void housePrices(int houseNumber) {
calcobj = new calculateClass();
TungMidlet tungmidobj = new TungMidlet();
int counter = tungmidobj.counter;
int[] housePriceArray = new int[5];
housePriceArray[0] = 20000000;
housePriceArray[1] = 10000000;
housePriceArray[2] = 200000000;
housePriceArray[3] = 7000000;
housePriceArray[4] = 13000000;
int price = housePriceArray[houseNumber];
calcobj.storePrice(counter,price);
}
}
The other supporting class is shown below.
package tungPackage;
public class calculateClass {
int[] storeArray = new int[5];
public calculateClass()
{
}
public void storePrice(int counter, int number2)
{
storeArray[counter] = number2;
}
public int calculateSum()
{
int sum =0;
for(int i=1; i<6; i++){
sum= sum+storeArray[i];
}
return sum;
}
}
Are you getting an error? It looks like your access code should work.
I can't seem to find anywhere that you actually initialise counter though, so maybe your problem is that you need to put counter = 0; somewhere in your code.
Java is also object oriented so you should avoid accessing like the above and make some 'getter and setter' methods:
public int getCounter() {
return counter;
}
and then call int counter = tungmidobj.getCounter();
remove TungMidlet constructor. If there was something useful to do there, you could also declare it protected - but this is not the case with your code snippet, see below.
Wherever you try to invoke that constructor directly, remove code that does this and find another way to do what you need. If needed, study code examples provided in LWUIT Tutorial - Introduction for how typical things are done in LWUIT.
put statement Display.init() in the beginning of the startApp method,
just like it is done in LWUIT Tutorial - Hello, LWUIT! example code
The reason why you are getting SecurityException is because you invoke TungMidlet constructor directly. Don't do that.
MIDP API documentation for MIDlet constructor states:
Throws:
SecurityException - unless the application management software is creating the MIDlet.
one way is
TungMidlet tungMidlet=new TungMidlet();
System.out.println(tungMidlet.counter);
but know encapsulation
second way is
you can make counter private variable and provide setter and getters.
private int counter;
public void setCounter(int counter){
this.counter=counter;
}
public int getCounter(){
return counter;
}
second way is preferred way as it achieves encapsulation
I have a Register class contains 8 sets& gets methods
using:
public class Register {
public Register(String Username) {
JFrame myFrame = new JFrame();
}
public void setUname() {
JoptionPane.showInputDialog(myFrame, "Enter Username");
}
public String getUname() {
return Uname;
}
}
There are other methods, 8 in total all requiring user input as String or double.
How in another class, can I import the methods into an ArrayList?
public class RegisterApp {
public addUser() {
ArrayList<Register> MyReg = new Arraylist<Register>();
myReg.add(Class Register);
}
}
Uncertain really of what goes after myReg.add
You need to add a reference to a Register.
public class RegisterApp {
public addUser() {
ArrayList<Register> MyReg = new Arraylist<Register>();
//Make an instance of Register and add it to the list
myReg.add(new Register("Me"));
}
}
You also mention adding methods to the list. What do you mean by that? What else are you trying to do? Do you want to call those methods on the instances in the list? You can do that like this:
for (Register reg : myReg) {
System.out.println(reg.getUname());
}
Note:
Your set method doesn't actually save the value anywhere. You are not storing the result in uname (which should be lowecase u). In general, setters are written so they are passed the new value in. This way you are not tied to using an input dialog anytime you change the name. That is a UI decision and should not effect the data model.
public void setUname(String uname) {
this.usname = uname;
}
I have made a multiple entry-point project, where App2 is set to autorun and App1 runs on user request.
I am trying to invoke a global event from App1, received by App2.
public class App2 implements GlobalEventListener {
static public int counter = 0;
public static final long countId = 0x1251402f595f81a5L;
public static final long eventId = 0xba4b84944bb7429eL;
private App2() {
Application.getApplication().addGlobalEventListener(this);
}
public static App2 waitForSingleton() {
counter = 2; // Added the counter in Runtime store in a similar way as
// added in eventOccured method
// Deleted some unuseful code
}
public void eventOccurred(long guid, int data0, int data1, Object object0,
Object object1) {
if (guid == eventId) {
callMethodOnOccuranceOfEvent();
}
}
public void callMethodOnOccuranceOfEvent() {
counter++;
RuntimeStore store = RuntimeStore.getRuntimeStore();
Object obj = store.get(countId);
if (obj == null) {
store.put(countId, new Integer(counter));
} else {
store.put(countId, new Integer(counter));
}
}
}
Then in other class I tried like
public class App1 extends MainScreen {
public App1() {
}
protected void makeMenu(Menu menu, int instance) {
super.makeMenu(menu, instance);
menu.add(new MenuItem("Call", 20, 10) {
public void run() {
callMethodonclick();
}
});
}
public void callMethodonclick() {
ApplicationManager.getApplicationManager().postGlobalEvent(App2.eventId);
RuntimeStore store = RuntimeStore.getRuntimeStore();
Integer c = (Integer) store.get(App2.countId);
add(new RichTextField("Event Recived#counter#" + c));
}
}
If I invoke the event for three times
Event Recived#counter#2
Event Recived#counter#2
Event Recived#counter#2
while the Expected result is
Event Recived#counter#3
Event Recived#counter#4
Event Recived#counter#5
which I guess suggests that object for App2 in not null but eventOccurred never invoked.
the output clearly suggests that callMethodonclick is not able to post Global event,even though globalEventListener was added in constructor.
Must be like this.
if (obj == null) {
store.put(countId, new Integer(counter));
} else {
store.replace(countId, new Integer(counter));
}
store.put() throw an IllegalArgumentException, because there is something in a store(see API Reference), but this Exception is handled by some system thread, that invokes eventOccured() method and show nothing about this Exception. It is one of the various Blackberry bug.
You are not updating the text in the RichTextField. It only gets added to the screen when there is no runtimestorage object associated with App2.RTSID_MY_APP.
Your code needs to keep a handle on the RichTextField by putting it into a field of the App1 object. Then update the text in the run() method.
I edited your code, adding braces to the if statement, which makes this more clear.