I'm learning OOP in Java. I'll explain my problem first, code below.
I have 3 seperate file (User.java, UserGUI.java and UserStart.java).
User.java has the code containing the User class with the default getters and setters.
UserGUI.java only exists out of items creating the GUI. UserStart.java has the code containing the main to run the program.
Now I'm trying to select a UserID in the JList in UserGUI.java and I want to show the surname and name in the JTextField below the JList.
User instances are made in UserStart.java and I'm stumped how to access them in UserGUI.java...
Is there anyone wanting to help me with this? Thank you in advance!
Below is the class of User.java:
public class User {
private String userId;
private String surname;
private String name;
public User(String userId, String surname, String name) {
this.userId = userId;
this.surname = surname;
this.name = name;
}
public String getuserId() {
return userId;
}
public void setuserId(String userId) {
this.userId = userId;
}
public String getsurname() {
return surname;
}
public void setsurname(String surname) {
this.surname = surname;
}
public String getname() {
return name;
}
public void setname(String name) {
this.name = name;
}
}
Below is a piece of code from the userGUI.java:
final JList<?> userList= new JList<Object>(addresses);
userList.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if(!e.getValueIsAdjusting()) {
String userId = (String) userList.getSelectedValue();
System.out.println(userId);
}
}
});
JTextField userText = new JTextField(10);
userText.setEditable(false);
Below is the file UserStart.java:
public class UserStart {
public static void main(String[] args) {
String userId, surname, name;
String[] userIds = {"a206", "a207", "a208", "a209"};
User u1 = new User(userIds[0], "a", "w");
User u2 = new User(userIds[1], "b", "x");
User u3 = new User(userIds[2], "c", "y");
User u4 = new User(userIds[3], "d", "z");
}
}
the simple way (which will suffice) is to pass the 'data' to the GUI on construction
class UserGui
{
private User[] user;
public UserGui(User[] users)
{
this.user = user;
initializeComponents();
}
// ...
}
then in your main
public static void main(String[] args)
{
User[] user = new User[10];
// setup user array ...
UserGui gui = new UserGui(user);
}
for larger more complicated programs/applications you should look in to using MVC as an approach which allows you decouple UI from Data.
For example in the User.java class you can create a static verctor with all users created (add each user there in the constructor):
import java.util.Vector;
public class User {
private String userId;
private String surname;
private String name;
public static Vector<User> users=new Vector<User>();
public User(String userId, String surname, String name){
this.userId=userId;
this.surname=surname;
this.name=name;
User.users.add(this);
}
}
then you can access any created user in any class like this:
User.users.get(i).getname();
depending on your problem, you should note the index somehow. the first created user will be 0: users.get(0), second one will be 1, and so on
for example if you want to display all users, then in a loop like this:
String name=null, surname=null;
for(int i=0;i<User.users.size();i++){
name=User.users.get(i).getname();
surname=User.users.get(i).getsurname();
//do something with you data before moving to next user
}
First of all, your constructor should have the same name as the class. Something like this:
public User(String userId, String surname, String name) {
this.userId = userId;
this.surname = surname;
this.name = name;
}
If you want to add the text to a JTextBox
if you have 1 textbox:
textbox1.setText(""+userList.getSelectedValue().getName() + ""+userList.getSelectedValue().getSurname())
if you have 2:
textbox1.setText(""+userList.getSelectedValue().getName());
textbox2.setText(""+userList.getSelectedValue().getSurname());
I haven't tested it, but it should work.
Related
class Client {
public static void AddList(User user) {
}
static class User {
public String name;
public String age;
public String mail;
public User(String name, String age, String mail) {
this.name = name;
this.age = age;
this.mail = mail;
}
}
static ArrayList<Object> list = new ArrayList<>();
public void AddList(String name, String age, String mail) {
list.add(new User(name, age, mail));
}
}
public class Main {
public static void main(String[] args) {
System.out.println("Give info plz");
Scanner scanner = new Scanner(System.in);
String name = scanner.nextLine();
String age = scanner.nextLine();
String mail = scanner.nextLine();
Client.AddList(new Client.User(name,age,mail));
Client.list.add("dqdqd");
Client.list.add(1);
for(Object s : Client.list) {
System.out.println(s);
}
}
}
This is a line when it doesn’t work for me, the program should take values and put them in an Arraylist, in general, the program should work like a database, take values and put them in an Arraylist, but this line does not work for me, please help.
public void AddList(String name, String age, String mail) {
list.add(new User(name, age, mail));
}
}
enter image description here as you can see in the screenshot, the data entered is simply lost
This is because you haven't implemented the AddList(User user) method. You've only implemented the AddList(String name, String age, String mail)
public static void AddList(User user) {
}
Should be something like
public static void AddList(User user) {
list.add(user);
}
To print the object you will need to create a toString() method for your object.
static class User {
public String name;
public String age;
public String mail;
public User(String name, String age, String mail) {
this.name = name;
this.age = age;
this.mail = mail;
}
public String toString() {
return name + ", " + age + ", " + mail;
}
}
You have two AddList(User) methods - one is a class method (i.e. static) and the other is an instance method. You are calling the class method which has no body. Since you never instantiate an instance of Client there is no purpose to the instance method. Move the body from the instance method to the class method and remove the instance method.
class Client {
static ArrayList<Object> list = new ArrayList<>();
public static void AddList(User user) {
list.add(new User(name, age, mail));
}
static class User {
public String name;
public String age;
public String mail;
public User(String name, String age, String mail) {
this.name = name;
this.age = age;
this.mail = mail;
}
}
}
In this I have tried the Registration Form in Model View Control architecture. I am unable to Store the User Data In Another class. In that the Registration field Has to be stored in the Registration Database Class and Contact information has to be stored in the Contact Information Class.
Then how Should I frame Main method
public class RegistrationData {
private String username;
private String password;
private Contact contact;
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public Contact getContact() {
return contact;
}
public void setContact(Contact contact) {
this.contact = contact;
}
public RegistrationData(String username, String password, Contact contact) {
this.username = username;
this.password = password;
this.contact = contact;
}
}
public class Contact {
private String name;
private String phoneNumber;
private String emailId;
public Contact(String name, String phoneNumber, String emailId) {
this.name = name;
this.phoneNumber = phoneNumber;
this.emailId = emailId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getEmailId() {
return emailId;
}
public void setEmailId(String emailId) {
this.emailId = emailId;
}
}
public class Registration {
Scanner scanner = new Scanner(System.in);
void Registration(RegistrationData registrationData,Contact contact){
System.out.println("Username : ");registrationData.setUsername(scanner.next());
System.out.println("Password : ");registrationData.setPassword(scanner.next());
System.out.println("Name : ");contact.setName(scanner.next());
System.out.println("PhoneNumber : ");contact.setPhoneNumber(scanner.next());
System.out.println("Email id :");contact.setEmailId(scanner.next());
}
}
//Data Base Class
import java.util.ArrayList;
import java.util.List;
public class RegistrationDatabase {
List<RegistrationData> registrationData = new ArrayList<>();
public void storeData(RegistrationData registrationData){
this.registrationData.add(registrationData);
System.out.println(this.registrationData);
}
}
import java.util.LinkedList;
import java.util.List;
public class ContactDatabase {
List<Contact> contacts = new LinkedList<>();
public void addContact(Contact contact){
this.contacts.add(contact);
}
}
Correct me If I am wrong in interpreting you question
Assumption 1 :
You want to Store registration data to RegistrationInformation table from Contact Information class as well as from RegistrationInformation class
Solution 1:
As I can see there is one to one relation between Contact and registration,so You can add a association in ContactInformation class as well as you have done in RegisterInformation class
public class Contact {
//one to one relation
private RegistrationData registrationData;
.
.
.
.
and use this to store registration from Contact
Assumption 2 :
You have seperate database for Contact and Registration
Solution 2:
In that case Create a POJO class for Registration form(same as RegistrationData,but will be used to capture data from view) and then create two classes RegistrationData and Contact class and then Use the POJO to retrieve and store the information in both the database.
How can we create constructor, to set different values that are from same data type?
Its impossible two create two identical constructors:
public User(int age, String name){
}
public User(int age, String surname){
}
User user1 = new User(33, Jack);
User user2 = new User(33, Sparrow);
Since both name and surname are from same data type, its impossible to know which value the user has meant to set.
We can create a constructor that has all the properties and then pass null for unset arguments.
public User(int age, String name, String surname){
}
User user1 = new User(33, Jack);
User user2 = new User(33, null, Sparrow);
There is a way to make it, using HashMap imitating the javascript object literal.
package javaapplication;
import java.awt.Color;
import java.util.HashMap;
public class JavaApplication {
public static class User {
public int age;
public String name;
public String surname;
public Color hairColor;
public User(HashMap<String, Object> arguments) {
if (arguments.containsKey("hairColor")) {
this.hairColor = (Color) arguments.get("hairColor");
}
if (arguments.containsKey("name")) {
this.name = (String) arguments.get("name");
}
if (arguments.containsKey("surname")) {
this.surname = (String) arguments.get("surname");
}
if (arguments.containsKey("age")) {
this.age = (int) arguments.get("age");
}
}
}
public static void main(String[] args) {
User jack1 = new User(new HashMap<String, Object>() {
{
put("hairColor", Color.RED);
put("name", "Jack");
put("age", 33);
}
});
System.out.println(jack1.hairColor); // java.awt.Color[r=255,g=0,b=0]
System.out.println(jack1.surname); // null
System.out.println(jack1.name); // Jack
System.out.println(jack1.age); // 33
User jack2 = new User(new HashMap<String, Object>() {
{
put("hairColor", Color.RED);
put("surname", "Sparrow");
put("age", 33);
}
});
System.out.println(jack2.hairColor); // java.awt.Color[r=255,g=0,b=0]
System.out.println(jack2.surname); // Sparrow
System.out.println(jack2.name); // null
System.out.println(jack2.age); // 33
}
}
Is there a more elegant way to do it?
The typical ways of doing this are with static creation methods or a builder object.
Static creation methods are the way to go if there are distinctive patterns of usage. For your example (where this perhaps isn't the case).
public static User ageName(int age, String name) {
...
}
public static User ageSurname(int age, String surname) {
...
}
...
In general it's a good idea to avoid any overloading. With constructors Java rather forces you into it, but sometimes you have to break free.
Builder may go something like:
public class UserBuilder { // This could be made a nested class of User
private int age = -1;
private String name;
private String surname;
private Color hairColor;
public UserBuilder age(int age) {
this.age = age;
return this;
}
// ... other properties ...
public User build() {
// Or return new User(this)
return new User(age, name, surname, hairColor);
}
}
This uses the typical Java dirty hack of returning this in a builder so you can build a train wreck.
User user1 = new UserBuilder().age(33).name("Jack").build();
You really need real examples of usage to see how it should fit in.
You are over-complicating things by using a HashMap here. Instead you could make use of the Builder Pattern for the same.
class User {
// required parameters
private int age;
// optional parameters
private String name;
private String surname;
public int getAge() {
return age;
}
public String getName() {
return name;
}
public String getSurname() {
return surname;
}
private User(UserBuilder userBuilder) {
this.age = userBuilder.age;
this.name = userBuilder.name;
this.surname = userBuilder.surname;
}
public static class UserBuilder {
// required parameters
private int age;
// optional parameters
private String name;
private String surname;
public UserBuilder setName(String name) {
this.name = name;
return this;
}
public UserBuilder setSurname(String surname) {
this.surname = surname;
return this;
}
public UserBuilder(int age) {
this.age = age;
}
public User build() {
return new User(this);
}
}
}
Now you can use it :
User user1 = new User.UserBuilder(12).setName("Jack").build();
User user2 = new User.UserBuilder(12).setSurname("Sparrow").build();
This assumes that age is a mandatory field, name and surname are optional fields for creating an object of User. You can tweak it as per your requirement accordingly.
I am a beginner using Java and I don't find the solution for this:
public class Company{
private String name;
private int age;
public Company(String n, int a){
name = n;
age = a;
}
/*get and set*/
public static void main(String[] args) {
ArrayList<Company> comp = new ArrayList<Company>();
comp.add(new Company("Tom", 23));
comp.add(new Company("John", 43));
comp.add(new Company("Charles", 25));
}
}
I would like to add parameters in a for, like email, address, etc. But .add is for new elements, no parameters.
Extend the Company class with the email, address fields (1), update the constructor (2), and pass the arguments you want (3).
public class Company {
...
private final String address; // 1
private final String email;
public Company(String n, int a, String address, String email) { // 2
...
this.address = address;
this.email = email;
}
public static void main(String[] args) {
...
comp.add(new Company("Charles", 25, "street", "charles#gmail.com")); // 3
}
}
If you already have an array filled with information for a specific field, you can use a for:
final List<String> emails = Arrays.asList("first#gmail.com", "second#gmail.com");
for (final String email : emails) {
comp.add(new Company(..., ..., ..., email));
}
You need to read about class members.
public class Company{
private String name;
private int age;
private String email;
private String address;
public Company(String n, int a, String e, String addr){
name = n;
age = a;
email = e;
address = addr;
}
First, you need to add variables to your class (that is the place where it will be stored per each class instance, as well as name or age are at the moment
Than you have to modify constructor (or create another one) to be able take these parameters, and also it is good idea to make getters and setters to get or set these parameters individually, so it can looks like this
public class Company{
private String name;
private int age;
private String email;
private String address;
public Company(String n, int a){
name = n;
age = a;
}
public Company(String n, int a,String email, String address){
name = n;
age = a;
this.email = email; //class instance object email is set to email from method parameter
this.address = address;
}
/*get and set*/
public void setEmail(String email){
this.email=email; //explicit setter
}
public String getEmail(){
return this.email;
}
public static void main(String[] args) {
ArrayList<Company> comp = new ArrayList<Company>();
comp.add(new Company("Tom", 23)); //will work, because I let your constructor
comp.add(new Company("John", 43));
comp.add(new Company("Charles", 25));
Company compToAdd= new Company("preparedFoo",22);
compToAdd.setEmail("fooomail"); //will work because setter
comp.add(compToAdd);
comp.add(new Company("FooName", 30,"fooMail","FooAddress")); //will work because new constructor
}
}
Assume I have an User object:
public class User {
private Long id;
private String name;
private String surname;
// getters + setters
}
When creating a User through SOAP, I want the user to input only the name and surname but not the id. In this case, should I create something like UserDTO object? For example:
public class UserDTO {
private String name;
private String surname;
// getters + setters
}
In my service bean, I will have the following method:
public void updateUser (Long id, UserDTO dto) {
User user = new User(id, dto.getName(), dto.getSurname());
service.updateUser(user);
}
Will this be a correct approach to my question? Thank you
I'm not sure if I understand your question right but why don't you just provide second constructor for your User class?
It will be:
public class User {
private Long id;
private String name;
private String surname;
//in case of creating user manually
public User(Long id, String name, String surname) {
this.id = id;
this.name = name;
this.surname = surname;
}
//in case of creating user via soap:
public User(String name, String surname) {
this.id = generateId(); //or some other logic to specify users id
this.name = name;
this.surname = surname;
}
}