Passing a String to another class [duplicate] - java

This question already has answers here:
Pass a class variable to another class
(3 answers)
Closed 4 years ago.
I'm stuck on a simple problem that I just can't solve.
I have two classes (Fruits.java with main and FruitDetails.java).
Fruits.java is a small program with tons of stuff, really. It has a ComboBox and I need to transfer its currently selected option to FruitDetails.
The problem is... my understanding of setters and getters seems to be very flawed. I've researched it online for the last 2 hours and this is the closest I could get to something. I'm really tight on time and I can't help but ask you now...
Inside class Fruits.java
public void selectedFruit() {
currentFruit = (String) fruitList.getSelectedItem();
}
public String getSelectedFruit() {
return currentFruit;
}
Inside class FruitDetails.java
public void fruitChoice() {
Fruits fruitChoice = new Fruits();
String chosenFruit = fruitChoice.getSelectedFruit();
System.out.println(chosenFruit);
// Rest of the code
}
Not only this opens another copy of my program(which I really don't want), system prints out "null" for the result.
I really need to get this working and hopefully it'll help fix my understanding of encapsulation a bit. There's a ton of online resources I've found, but using them seems to be too hard for the thick head of mine.
Thanks in advance for any help.

public void fruitChoice() {
Fruits fruitChoice = new Fruits();
String chosenFruit = fruitChoice.getSelectedFruit();
System.out.println(chosenFruit);
// Rest of the code
}
In second line you are creating new object that's why you are getting null when you try to get the value of currentFruit.

it looks like you method selectedFruit() sets currentFruit but your not actually calling selectedFruit()?
Unless your missing some code above that calls selectedFruit() elsewhere?
Try calling selectedFruit() after instantiating your Fruit object.

This is because you have not actually linked your currentFruit to your combo box. You need to do two things - call selectedFruit when you first populate the combo box, then attach a listener that calls selectedFruit everytime the combo box selection changes.
If you are using JComboBox, insert this code after you have created the JComboBox.
combo.addActionListener (new ActionListener () {
public void actionPerformed(ActionEvent e) {
selectedFruit();
}
})
selectedFruit();

Related

Execute selenium click with ID based on different classes in Java

I have two selenium elements where i need to click. But these elements are with a different id.
findElement(By.id(ID_1)).click();
findElement(By.id(ID_2)).click();
findElement(By.id(ID_1)).click() should be clicked if the Class_1 is executed, if Class_2 is called, then findElement(By.id(ID_2)).click() should be clicked.
I am trying to avoid duplicate code because these above 2 find elements are inside one method which is called Class_1 and Class_2.
I tried something like this but it didn't solve my issue
if (Class_1.class)
{
findElement(By.id(ID_1)).click();
}
else if (Class_2.class)
{
findElement(By.id(ID_2)).click();
}
I am getting "Type mismatch: cannot convert from Class<Class_1> to boolean". I mean I am trying to do like this. If this is class_1, then run this, else run else if part.
Thanks for any guidance in advance.
You schouldn't separate your test into two (or more) different classes.
Instead use one class and parametrize your method:
public void myTestMethod(String ipAdress) {
if (ipAdress.equals("FOO_IP")) {
findElement(By.id("FOO_ID")).click();
}
else if (ipAdress.equals("BAR_IP")) {
findElement(By.id("BAR_ID")).click();
}
else {
// code for uknown ip adress
}
}
and simply call the method with desired argument:
myTestMethod("FOO_IP");
myTestMethod("BAR_IP");

How do I store information in a method so I can use it in a different method later?

I am very new to Java, so sorry if this is stupid and obvious or worded poorly. I don't really know enough yet to know what I don't know.
So I decided that since I have to learn Java, I'd just jump in head first and try to figure it out as I go. So far, it's worked decently. I'm trying to reinforce some basic concepts I already know by writing small programs that do trivial stuff.
I decided I'd write a little text based adventure game and it's working well so far. I'm using Scanners and Switches to call methods that use Scanners and Switches to call other methods. That's all working fine.
So far it's a very linear straight line, like an old choose your own adventure book. But, I wanted to add a player inventory. I have a very vague idea of how to do it, but I have a pretty solid idea of what I want it to do.
So, basically I want to store a piece of information that says the player has a specific item. I want to be able to test for the presence of more than one item at once. And I want to be able to tell the player what items he has at any point in the game.
I don't really know how to ask the question better.
My best guess is doing something like
int key, potion;
key = 0
potion = 2
and then testing the values of each one
if (key = 0) {
System.out.println("you don't have the key ");
}
if (key > 0) {
System.out.prinln("You unlock the door");
}
I'm doing each new room as a separate method, so the whole game is just a big chain of methods. So my hope is that the information about items can be stored in a separate method that I can access through switches or if/else in the current room method the player is in. So, the player is unlocking a door in room2, which is its own method, and he picked up the key in room1, which is its own method, and the key is stored as an integer in the inventory method. But the key was one use, so the key integer is set to 0 and the method room3 starts. If that makes any sense.
Again, sorry if this is really stupid basic stuff. I'm very new to programming.
No problem and I applaud you for choosing to learn programming. This is basic data structures. If you want to hold a value, in most programming languages, you'll have an array. I think breaking your logic down is a good idea i.e., (store an item, test for > 1, list items). The first step is making this as simple as possible and than maybe adding getters/setters later through refactors. Ultimately, your goal is to make the most basic code work first (like this) and than refactoring towards an object oriented class with getters/setters and/or a HashMap.
1:
public class PlayerInventory
{
private String[] inventoryStr = new String[20]; // basic implementation
inventoryStr[0] = "Phone";
inventoryStr[0] = "Book";
}
2:
int arrayLength = inventoryStr.length;
3:
for(int i=0; i < inventoryStr.length; i++) {
System.out.println( inventoryStr[i] );
}
Refactor (after you write unit tests for this)
1*: (with a list)
import java.util.*;
import java.util.*;
public class CollectionGetterSetter {
private List<String> playerInventory;
public void setPlayerInventory(List<String> inv) {
this.playerInventory = inv;
}
public List<String> getPlayerInventory() {
return this.playerInventory;
}
public static void main(String[] args) {
CollectionGetterSetter app = new CollectionGetterSetter();
List<String> PlayerInventory = new ArrayList();
PlayerInventory.add("phone");
PlayerInventory.add("book");
PlayerInventory.add("glasses");
PlayerInventory.add("nav");
app.setPlayerInventory(PlayerInventory);
System.out.println("Player 1: " + PlayerInventory);
List<String> PlayerInventory2 = new ArrayList();
PlayerInventory2.add("cap");
PlayerInventory2.add("gown");
PlayerInventory2.add("foo");
PlayerInventory2.add("bar");
}
}

How to deal with history-sensitivity?

So I have written a Java program that has a function handInExam() that may not be called twice in a row, thus the program is history-sensitive. The problem that then occurs is that I need a variable canHandInExam to check whether this method has already been called and update this variable in each method, which leads to very poor maintainability. Below is a code snippet to show the problem.
public class NotAllowedException extends Exception {
public NotAllowedException(String message) {
super(message);
}
}
import java.util.Scanner;
public class Exam {
String[] exam;
String[] answers;
boolean canHandInExam;
public Exam(String[] questions) {
exam = questions;
answers = new String[exam.length];
canHandInExam = false;
}
// This method may only be called once in a row
public void handInExam throws NotAllowedException() {
if (canHandInExam) {
// Send exam to teacher
canHandInExam = false;
} else {
throw new NotAllowedException("You may not hand in this exam!");
}
}
public void otherMethod() {
// Do something
canHandInExam = true;
}
}
In this small example it is feasible to slightly adapt each method, however if you would have lots of methods you would need to adapt all of them. Since after all these methods you may again call handInExam() thus the variable canHandInExam would need to be set to true.
Is there a way to solve this problem in a way that is more maintainable? I am open to other possible programming languages that are not OO, but at this point I am unsure of what would be suitable.
I have considered using functional programming (e.g. Haskell) as those languages are not history-sensitive, however I did not know how to limit that you may only call a function once in a row. I tried searching for how to limit a function call to n times in a row both in Java and Haskell, but this ended up with only references to how to call a function n times.
If you speak about handing in an exam, than this doesn't mean that something is done with that exam, but that there is some entity to which the exam is given. So instead of storing within the exam whether it was handed in or can be handed in, something like this would be more appropriate:
//or whatever you call this
public interface Institution {
void handInExam(Exam exam) throws DuplicateExamException;
boolean isHandedIn(Exam exam);
}
Implementations of Institution store the exams that were handed in (possibly using a Set).

Updating JTable from a different JFrame

Actually, I have a JFrame(the main window) with a JTable in it. And couple of buttons, like Add,Delete,Refresh.
Refresh uses the function(updateTable) that has the following code below and works fine:
try
{
ResultSet R = Home.getStatement().executeQuery("Select * from Schooldata");
int count =0;
while(R.next()) { count++; }
school_data = new String[count][6];
R = Home.getStatement().executeQuery("Select Schoolname,city,ProgramOpted,coordinator_name,Trainers,contactnum from Schooldata");
count =0;
while(R.next())
{
for(int i=0;i<6;i++)
{ school_data[count][i]= R.getString(i+1);
System.out.println(R.getString(i+1));
}
count++;
}
}
catch(SQLException S) {JOptionPane.showMessageDialog(null,S);}
jTable1.setModel(new DefaultTableModel(school_data,new String [] {
"School Name", "City", "Program", "Coordinator", "Trainers", "Contact Number"
}));
When I click on "Add, another JFrame window appears and asks for Details that is further saved to Database and shows a confirmation message and refreshes the table(on a different JFrame i.e the main Window) using above function.
The Issue is, I'm calling the same function but from an another JFrame.Expecting the changes to be reflected in the main JFrame.
Using the method,new Main().updateTable(); in the below code.It's just not working.
try
{
int confirm = Home.getStatement().executeUpdate(Query);
if(confirm == 1)
{
JOptionPane.showMessageDialog(null,"Record Added","Saved",1);
new Main().updateTable();
}
else JOptionPane.showMessageDialog(null,"There is some Error.....","Error",0);
}
catch(SQLException S)
{
JOptionPane.showMessageDialog(null,S,"Error",0);
}
Your problem I believe is here (it's hard to tell without a minimal example program:
int confirm = Home.getStatement().executeUpdate(Query);
if(confirm == 1)
{
JOptionPane.showMessageDialog(null,"Record Added","Saved",1);
new Main().updateTable(); // ****** HERE ******
}
You're creating a completely new Main object, changing its state, and hoping that this will change the state of the visualized Main object, but you're finding out that no, it won't.
Instead you need to pass a reference of the visualized Main object into the code above, and then call methods on it, not on a newly created completely unique object.
Whatever you do, don't try solving this by making fields or methods static. Yes, that might work, but it breaks OOPs and makes your program difficult to test or extend.
As an aside, that second dependent window should not be another JFrame, and in fact likely should be a modal JDialog. For if you use a JDialog, then there would be no need for the dialog code to push information into the calling window. Rather the calling code will know when you're done dealing with the dialog, and so at this point if the dialog's state is good (if you didn't say cancel it with no changes), then the calling code can easily pull information from the dialog code. For a concrete example of what I"m talking about, please look at my answer to a similar question about passing information between two windows here.
Also a similar problem and solution can be found here.
See weather you are disposing the main or not. If not then try creating object of Main frame and try accessing it to refresh table. You can also add import for Main Frame .java file in your refresh dialog file and try refreshing the table. Also check if your table is public static or not so that to access it from another frame. If you create a refresh function for this purpose then it will be best. My code for function goes as -
import package.mainframe;
or
MainFrame mainframe = new MainFrame();
try
{
int confirm = Home.getStatement().executeUpdate(Query);
if(confirm == 1)
{
JOptionPane.showMessageDialog(null,"Record Added","Saved",1);
mainframe.updateTable(); //or mainframe.functioncall();
}
else JOptionPane.showMessageDialog(null,"There is some Error.....","Error",0);
}
catch(SQLException S)
{
JOptionPane.showMessageDialog(null,S,"Error",0);
}

Modifying boolean value in Action Listeners [duplicate]

This question already has answers here:
The final local variable cannot be assigned
(6 answers)
Closed 8 years ago.
Code:
final boolean saveedit = true;
btnSaveEdit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (saveedit) {
// save function
if (txtMessage.getText().length() != 0) {
message = txtMessage.getText();
}
// show popup
JOptionPane.showMessageDialog(frmEventsAndProperties,
"Your last message is: " + message, "Message",
JOptionPane.PLAIN_MESSAGE);
btnSaveEdit.setText("Edit");
txtMessage.setEnabled(false);
saveedit = false;
} else {
// edit function
}
}
});
Error:
'The final local variable saveedit cannot be assigned, since it is defined in an enclosing type'.
Question:
I have seen other solutions for similar same errors, yet there must be a simple way to implement it - probably as simple as defining something earlier or moving it around.
I would appreciate any help.
Wherenver you want to use a variable inside an inner class (here ActionListener), you have two choices (regarding how you want to use it, modify(mutate) or access):
Using the final keyword with a local variable (it is not recommended for your case, since you want to modify your variable inside the inner class, not access only)
Using a field vairable, that need not be final (it is recommended)
As I mentioned, the seconed solution is feasible for you, since you want to do saveedit = false; which is mutating.
I completely agree with sager89. But i want to add one thing here which is.
If the keyword final is used for an instance variable, Then the final variable can be assigned only once and at the time of declaration or you will have to assign it in each and every constructor once.
This question is not a duplicate, the answer is for anyone wondering to simply move
final boolean saveedit = true;
to inbetween these lines:
btnSaveEdit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
That way it is not defined in an enclosing type :)

Categories

Resources