I have a program, but I do not understand how I can access info from one particular object in another method.
This is a minor sample of my program, I want to create this method riders in the same class(called Cyclist). I want to print out the list of riders here, but I do not understand how...
public void riders() {
//System.out.print(c1.getName())
//this does not work.
//here I want to print out all the names of the riders, i.e. c1's name, c2's name... cn...
}
public void abilities() {
//Pardilla blir til!
Cyclist c1 = new Cyclist();
c1.setName("Sergio Pardilla");
c1.setMountain(75);
c1.setTimeTrial(60);
c1.setSprint(60);
c1.setAge(30);
System.out.println(c1.getName() + "'s abilities:");
System.out.println("Mountain - " + c1.getMountain());
System.out.println("TimeTrial - " + c1.getTimeTrial());
System.out.println("Sprint - " + c1.getSprint());
System.out.println("Age - " +c1.getAge());
}
You have no visibility of c1 variable in riders() method.
c1 is declared inside abilities(), and then its local to it, only visible inside.
If you want to use a variable outside this method, you should use a field instead a local variable, or pass it as parameter to rider method.
List<Cyclist> cyclists = new ArrayList<>(); // Declared as field
public void riders() {
for (cyclist : cyclists){
System.out.print(cyclist.getName())
}
}
public void abilities() {
//Pardilla blir til!
Cyclist c1 = new Cyclist();
c1.setName("Sergio Pardilla");
c1.setMountain(75);
c1.setTimeTrial(60);
c1.setSprint(60);
c1.setAge(30);
System.out.println(c1.getName() + "'s abilities:");
System.out.println("Mountain - " + c1.getMountain());
System.out.println("TimeTrial - " + c1.getTimeTrial());
System.out.println("Sprint - " + c1.getSprint());
System.out.println("Age - " +c1.getAge());
cyclists.add(c1); //Add cyclist to cyclists list
}
Cyclist c1 is confined within the scope of the abilities method, which is why you can't access it in the riders() method.
First of all, I would keep an instance-scope ArrayList of Cyclists declared at the top of the class.
private ArrayList<Cyclist> cyclists = new ArrayList<Cyclist>();
Then, in your abilities method, you should add c1 to the ArrayList cyclists, like
cyclists.add(c1);
after you've changed c1's settings. Then, from the riders() method, you can get c1's name with
cyclists.get(0).getName();
c1 is defined locally in the abilities() method. Other methods are unable to access it. You either need abilities to return c1 so you can use it in other methods or you can declare a field in that class to store c1.
short : you cannot access objects from a method which are only declared within another method
1) let riders accept a Cyclist object, and then pass the object.
or
2) make the Cyclist class wide accessable :
public class XY {
private Cyclist c1;
public void riders() {
// show stuff
}
public void abilities() {
// init stuff
}
}
Furthermore if u want to output all Cyclists, consider using a List<Cyclist> which should store each Cyclist object.
Related
While reading (https://docs.camunda.org/manual/7.5/user-guide/process-engine/variables/) I am not sure how you retrieve a variable?
At the moment I am struggling to find out how to access previously set process variables. What I tried is:
I have a simple bpmn process in which i have start event, 1 service task and end event, I am starting my process by passing 2 variables (a&b) and my service task is implementing following java class:
public class Addition implements JavaDelegate {
public void execute(DelegateExecution exe) throws Exception {
System.out.println("Inside calculator again");
Integer x = (Integer) exe.getVariable("a");
Integer y = (Integer) exe.getVariable("b");
int add = x+y;
System.out.println("Addition of two number is"+add);
exe.setVariable("add",add);
}
I am starting my process as follows:
public void sayHello(ProcessEngine processEngine)
{
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("a", 3);
variables.put("b", 5);
ProcessInstance instance= processEngine.getRuntimeService().startProcessInstanceByKey("Process_3", variables);
}
I want to access add variable (present in Addition class) in sayHello class?
As process has been completed so I can't use runtimeService so I tried to use history service but couldn't find out any solution.
Is there any Java API which I can use or is there any other way?
If you want to get all historic variable instances use the list method in the HistoricVariableInstanceQuery.
For Example
List<HistoricVariableInstance> variables = processEngine.getHistoryService().createHistoricVariableInstanceQuery.list();
If you want to get specific variables with the given name you can use the method variableName(String)
For Example:
List<HistoricVariableInstance> variables = processEngine.getHistoryService().createHistoricVariableInstanceQuery().variableName("myVar").list();
To get the variables of a specific process instance use the method processInstanceId
For Example:
List<HistoricVariableInstance> variables = processEngine.getHistoryService().createHistoricVariableInstanceQuery().processInstanceId(processInstance.getId()).variableName("myVar").list();
See for further information the documentation of the
HistoryService and HistoricVariableInstanceQuery
for anyone struggling with the same issue the variables used to start the process are process variables, the ones we retrieve via delegate are local ones so you have to somehow get to the process instance. To make your code works I'll rewrite it as follow (will change from implementing JavaDelegate to implementing ActivityBehavior and to get the variable you have to go througth call to getParent()).
public class Addition implements ActivityBehavior{
public void execute(ActivityExecution exe) throws Exception {
System.out.println("Inside calculator again");
int x = (int) exe.getParent().getVariable("a");
int y = (int) exe.getParent().getVariable("b");
int add = x+y;
System.out.println("Addition of two number is: " + add);
exe.setVariable("add",add);
}
The sayHello method won't change
public void sayHello(ProcessEngine processEngine)
{
Map<String,Object> variables = new HashMap<String, Object>();
variables.put("a", 3);
variables.put("b", 5);
ProcessInstance instance=
processEngine.getRuntimeService().startProcessInstanceByKey("Process_3", variables);
}
I have the following code:
public void actionPerformed(ActionEvent e) {
String userInput = commandInput.getText();
if (currentLevel == 0) {
if (userInput.equals(answers.getIntroAnswers().get(0)) || userInput.equals(answers.getIntroAnswers().get(1))) {
messageDisplay.append("\n \n" + userInput + "\n");
commandInput.setText("");
messageDisplay.append("\n" + messages.getNextMessage());
currentLevel++;
getCurrentLevel();
} else {
messageDisplay.append(notValid());
}
} else if (currentLevel == 1) {
// do the same as above but with the next set of answers
}
}
What I'd like to do is somehow separate this action into it's own class and call the method /constructor within that class to do this checking else I will be stuck using nested if's and it will become very messy and hard to understand. Would I be right in thinking a method to take parameters of currentLevel and userInput in order to test the userInput against the corresponding answers based on the currentLevel? Below is a link to the rest of the classes involved:
https://github.com/addrum/TextGame.git
Would I be right in thinking a method to take parameters of currentLevel and userInput in order to test the userInput against the corresponding answers based on the currentLevel?
No. In fact, you probably want to avoid passing the current level as an explicit parameter. If you've got the level as a parameter, you will probably end up just pushing the "multiple nested ifs" into another class.
I think you need to write it like this:
InputChecker[] levelChecker = ... create an array of checker instances
....
levelChecker[currentLevel].check(userInput);
Then you need to create a class (possibly anonymous) to implement the checking for each level. Note that if you needed to you could supply the level number to a checker class via a constructor parameter and have it save it in a private instance variable.
You could expand/generalize the InputChecker interface to include other level-specific behaviour. Or indeed make this part of a Level interface.
"Is this taking the currentLevel and comparing the userInput to the current level?"
No. In my example code above it is calling a method on the InputChecker instance to do the checking. Since there are different InputChecker instances for each level, they can check different answers ... or whatever.
But if the only difference between the "input check" behaviours for each level is that they check against a different set of answers then:
levelAnswers = answers.getAnswersForLevel(currentLevel);
for (String answer : levelAnswers) {
if (userInput.equals(answer)) {
// blah blah blah
}
}
Why not create the method in the same class rather than having a different class to do that, considering other variables that method uses such as,
messageDisplay.append("\n \n" + userInput + "\n");
commandInput.setText("");
messageDisplay.append("\n" + messages.getNextMessage());
currentLevel++;
So I'd suggest creating the method in same then call it from actionPerformed
public void checks()
{
String userInput = commandInput.getText();
if (currentLevel == 0) {
if (userInput.equals(answers.getIntroAnswers().get(0)) || userInput.equals(answers.getIntroAnswers().get(1))) {
messageDisplay.append("\n \n" + userInput + "\n");
commandInput.setText("");
messageDisplay.append("\n" + messages.getNextMessage());
currentLevel++;
getCurrentLevel();
} else {
messageDisplay.append(notValid());
}
} else if (currentLevel == 1) {
// do the same as above but with the next set of answers
}
}
Then call it from actionPerformed
public void actionPerformed(ActionEvent e)
{
check():
}
So now you if's are handle in a seperate method.
To my eyes, since you are talking about levels so much, you probably should have a class that represents a level. Actually, since you obviously have more than one level, which acts slightly differently, you have two approaches.
Have a Level interface, and then make a class per level.
or
Have a Level class, with a constructor that hides the level number within the class.
After that, you can switch polymorphicly instead of nested if statements (or if's cousin, the switch statement).
Level level = currentLevel;
while (level != null) {
level.doStuff;
level = level.getNextLevel();
}
i have created a custom console for a program. I have a method that adds a message to the console called toConsole this asks for the string where it checks and adds the time to the string. it then goes to my function addConsole which checks if existing text is present if so it will then add the pre-existing text to the new text, else it just puts the new text in. so here is the error. i may also point out that if i enter text manually on the consoles input text box it does not produce this error.
Exception in thread "main" java.lang.NullPointerException
at com.michael.tech.api.console.RunConsole.addConsole(RunConsole.java:188)
at com.michael.tech.api.console.RunConsole.toConsole(RunConsole.java:204)
at com.michael.tech.api.console.RunConsole.toConsole(RunConsole.java:223)
at com.michael.tech.api.testerFile.main(testerFile.java:25)
here is the addConsole method
private static void addConsole(String s){
console.setText( ( console.getText().isEmpty()) ? s : (console.getText() + "\n" + s) );
}
the toConsole method
public static void toConsole(String s, boolean timeStamp, boolean classPath, String className){
if(s.startsWith("/")){
doCommand(s);
return;
}
Time t = new Time();
t.getSYSPrint();
String time = "[" + t.toMilitary() + "] ";
if(EchoTime || timeStamp){
addConsole(time + s);
}
else if(classPath){
addConsole(className);
}
else{
addConsole(s);
}
}
and lastly the Main method in testerFile class
public static void main(String[] args) {
RunConsole.startConsole();
RunConsole.toConsole("test");
}
Thanks in advance for any help. I assume it is some small mistake i overlooked (I hope too).
EDIT:
paste bin to see line numbers
RunConsole class
http://pastebin.com/2yUAwQc5
testerFile class
http://pastebin.com/R5ViLekp
The problem is that the JTextArea console still has its default null value as it has not been instantiated. This is because there is no instance of RunConsole created — Instead, you are accessing the methods of this class in a static way:
RunConsole.startConsole();
RunConsole.toConsole("test");
Using static methods is poor design especially since your application needs to have state. Make all static methods in RunConsole instance methods and replace the above lines with:
RunConsole runConsole = new RunConsole();
runConsole.startConsole();
runConsole.toConsole("test");
Also, when you do this, don't forget to remove your instance created in startConsole, otherwise you will not see the initial message from toConsole. Change:
new RunConsole().setVisible(true);
to
setVisible(true);
I am simply trying to set a room variable (adding the user's name to a room varible) in my UserJoinedRoomHandler:
From my JAVA extension:
public class UserJoinedRoomHandler extends BaseServerEventHandler
{
#Override
public void handleServerEvent(ISFSEvent arg0) throws SFSException
{
User user = (User) arg0.getParameter(SFSEventParam.USER);
Room room = (Room) arg0.getParameter(SFSEventParam.ROOM);
trace("add p1 = " + user.getName() + " to room=" + room.getId());
List<RoomVariable> listOfVars = new ArrayList<RoomVariable>();
listOfVars.add( new SFSRoomVariable("player1Name", user.getName()) );
((MyExtension) getParentExtension()).sfsApi.setRoomVariables(user, room, listOfVars); // NullPointerException here :(
}
}
Note, I grab the sfsAPI when in MyExtention init() function:
ISFSApi sfsApi = SmartFoxServer.getInstance().getAPIManager().getSFSApi();
To me this should work, the only thing I can think of is that the room might not have fully initialised (the user had just created the room before this event is fired). But in any case I thought this should be a trivial scenario, but it has cost me a good handful of hours already.
Cheers for any help.
The solution was to use the Api directly:
((MyExtension) getParentExtension()).getApi().setRoomVariables(user, room, listOfVars);
PS: Unfortunately there is no method to issue 1 Room Variable. You have to submit a list, even if its only 1 in length.
I have a public method (called getMusic) in a class called Favorites. getMusic has set. There are 3 sets and in each set has five words, Set getMusic(). In another class called myInterest, there is a treeSet called musicTable. I called getMusic method into myInterest class but I do not know how to iterate over so that the set of words can be added to musicTable TreeSet. I tried to use addAll but it's not working. Where I am going wrong and how do I fix this? .I don't want to use list, I've thought about for loop but not to sure how to use this or literate(). thank you
public class myInterest
{
private static TreeSet<String> musicTable = new TreeSet<String>();
public Test()
{
super();
musicTable = new TreeSet<String>();
}
public static void testOut()
{
Favorites entrainment = new Favorites();
System.out.println(" " + entrainment.getMusic());
entrainment.addAll(musicTable); //error msg "cannot find symbol - method addAll(java.util.TreeSet<java.lang.String>)
musicTable.addAll(entrainment); //also tried this way but error msg "cannot find symbol - method addAll(Favorities)
}
}
Do you mean:
musicTable.addAll(entrainment.getMusic());
?