difference between string and property String in tableview javafx - java

what is the difference between string and Property String in tableview javafx?
how it changes the tableview if i use data type as String or Property String ??
Can anyone give example to show this difference

Property String is different in Java. Basically you use property String when you want to observe your variable in a TableView. The reason Java does this is that Java uses an MVC Pattern (Model-View-Controller). The model is your stored data, the view is what you see like GUI and the controller is the brains and logic for everything in your application. The Model in Java is done as classes that hold properties rather than just fields. Because when you want to store data into a TableView in JavaFX the proper way is to instantiate objects from a class and the Properties defined in this class becomes the properties of this object, by then you can store the object in the TableView and put some logic to allow the tableView to go find the properties of this object and fill them in the table, if they were Strings rather than properties, JavaFX won't be able to get them and make them observable in the table. I wrote some logic below to give you an idea of how this is done. So first this is a class that acts as a Model:
public class Contact extends SQL_Objects {
private SimpleStringProperty id;
private SimpleStringProperty firstName;
private SimpleStringProperty lastName;
private SimpleStringProperty phone;
private SimpleStringProperty email;
private SimpleStringProperty unitNo;
private SimpleStringProperty street;
private SimpleStringProperty city;
private SimpleStringProperty province;
private SimpleStringProperty zipCode;
private SimpleStringProperty country;
private SimpleStringProperty gender;
private SimpleStringProperty notes;
private SimpleStringProperty relationship;
private final static String[] FIELD_NAMES = { "id", "firstName", "lastName", "phone", "email", "unitNo", "street", "city", "province", "zipCode", "country", "gender", "notes", "relationship" };
public Contact(String id, String firstName, String lastName, String phone, String email, String unitNo, String street, String city, String province, String zipCode, String country, String gender, String notes, String relationship) {
this.id = new SimpleStringProperty(id);
this.firstName = new SimpleStringProperty(firstName);
this.lastName = new SimpleStringProperty(lastName);
this.phone = new SimpleStringProperty(phone);
this.email = new SimpleStringProperty(email);
this.unitNo = new SimpleStringProperty(street);
this.street = new SimpleStringProperty(street);
this.city = new SimpleStringProperty(city);
this.province = new SimpleStringProperty(province);
this.zipCode = new SimpleStringProperty(zipCode);
this.country = new SimpleStringProperty(country);
this.gender = new SimpleStringProperty(gender);
this.notes = new SimpleStringProperty(notes);
this.relationship = new SimpleStringProperty(relationship);
}
public String getId() {
return id.get();
}
public String getFirstName() {
return firstName.get();
}
public String getLastName() {
return lastName.get();
}
public String getPhone() {
return phone.get();
}
public String getEmail() {
return email.get();
}
public String getUnitNo() {
return unitNo.get();
}
public String getStreet() {
return street.get();
}
public String getCity() {
return city.get();
}
public String getProvince() {
return province.get();
}
public String getZipCode() {
return zipCode.get();
}
public String getCountry() {
return country.get();
}
public String getGender() {
return gender.get();
}
public String getNotes() {
return notes.get();
}
public String getRelationship() {
return relationship.get();
}
public static String[] getFieldNames() {
return FIELD_NAMES;
}
Those getters and setters should follow the Standards of naming conventions in Java, so that when you insert and object into the table as i will show below, the table would use the field names and fetch for the getter for each field to get it's value and make it observable in the tabele, so below is an example of the controller to fill the columns and rows of the table:
private void fillColumns() {
try { // starting from 2 so that the id column is not included
for (int i = 2; i <= resultSet.getMetaData().getColumnCount(); i++ ) {
TableColumn column = new TableColumn(resultSet.getMetaData().getColumnName(i));
column.setCellValueFactory(new PropertyValueFactory<Contact, String>(Contact.getFieldNames()[i - 1]));
selectedTable.getColumns().add(column);
}
} catch (SQLException ex) {
Alert alert = new Alert(Alert.AlertType.ERROR, "Type:\n" + ex.getClass().getName() + "\n\nMessage: Unable to get the columns from the database\n\nDetails:\n" + ex.getMessage(), ButtonType.OK);
}
}
The next is to fill the rows, assuming i selected data from the database and stored them in a result set, i will use the next method to go through the records of the resultSet row by row, this method would return false when there is no more rows
private void fillRows() {
shownRecords = 0;
try {
while(resultSet.next()) {
Contact cont = new Contact(Integer.toString(resultSet.getInt(1)), resultSet.getString(2), resultSet.getString(3), resultSet.getString(4), resultSet.getString(5), resultSet.getString(6), resultSet.getString(7), resultSet.getString(8), resultSet.getString(9), resultSet.getString(10), resultSet.getString(11), resultSet.getString(12), resultSet.getString(13), resultSet.getString(14));
tableView.getItems().add(cont);
}
resultSet.beforeFirst();
} catch (SQLException ex) {
Alert alert = new Alert(Alert.AlertType.ERROR, "Type:\n" + ex.getClass().getName() + "\n\nMessage: Unable to get the records from the database\n\nDetails:\n" + ex.getMessage(), ButtonType.OK);
alert.show();
}
}
So as you can see, i used SimpleStringProperty rather than Strings and if u used Strings here JavaFx wouldn't be able to display the results as they somehow are not considered properties of the objects inserted into the table

Related

List is not in order

I converted UUID to string (String id) and put the conversion inside a method.
I also declared other String variables such as FirstName etc and put in on an ArrayList:
Code
The code does work. But I'm confused why the string email was showing second on the list.
public class StudentController {
#Autowired
StudentService studentService = new StudentService();
#GetMapping
public List<Student> displayStudent(){
return studentService.getStudent();
}
}
public class StudentService {
Student student = new Student();
private List<Student> studentList = Arrays.asList(
new Student(student.genID(),"Elvis" , "Presley" ,"Elvis#gmail.com")
);
public List<Student> getStudent(){
return studentList;
}
}
public class Student {
UUID uuid = UUID.randomUUID();
private String id;
private String FirstName;
private String LastName;
private String email;
public Student() {}
//Method Converting UUID into string
public String genID(){
id = uuid.toString();
return id;
}
public Student(String id) {
this.id = id;
}
public Student(String id, String firstName, String lastName, String email) {
this.id = id;
FirstName = firstName;
LastName = lastName;
this.email = email;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getFirstName() {
return FirstName;
}
public void setFirstName(String firstName) {
FirstName = firstName;
}
public String getLastName() {
return LastName;
}
public void setLastName(String lastName) {
LastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
}
Expected
I expected data to be in this order
ID , FirstName , LastName , email
Actual Output JSON
JSON is an unordered collection, as specified on https://www.json.org/json-en.html , so you don't have to worry about it. It might depend on library though.
Specify the serialized order of properties
The order of properties during serialization can be defined in Jackson.
Either at class-level specifically using annotation #JsonPropertyOrder.
Or globally for your ObjectMapper using a feature:
objectMapper.configure(MapperFeature.SORT_PROPERTIES_ALPHABETICALLY, true)
Example
In your case you can achieve expected order using the annotation on your class:
#JsonPropertyOrder({'id', 'firstName', 'lastName', 'email'})
public class Student {
// body of your class
}
Or separately with an index on your fields:
public class Student {
#JsonProperty(index=10)
private String id;
// not ordered specifically
private String firstName;
private String lastName;
#JsonProperty(index=20)
private String email;
// remainder of your class
}
See also
Jackson ObjectMapper - specify serialization order of object properties
Order of JSON objects using Jackson's ObjectMapper
Jackson JSON - Using #JsonPropertyOrder annotation to define serialized properties ordering

How should i specify the managed bean method to save the data on the directed FOREIGN KEY?

I am currently new to do website project with JSF specification. as you all know, JSF should include xhtml for the server page and managed bean to determine the class method, and I have made connection between my project and MySQL localhost.
The problem is, i created 1 main table for User categories which include common attributes such as name, gender etc. and i made other two table that specify the user for its role. The thing is that the main User table that contain user_ID as PRIMARY KEY to become the reference for the other 2 tables FOREIGN KEY ex: student, staff.
If i created a registration form on the server page, how should i determine the method to separate the data into the database from coming to the wrong table?
LoginBean.Java
private String fullName_;
private String gender_;
private String phoneNumber_;
private String IC_;
private String email_;
private String Address_;
private String password_;
public String getFullName_() {
return fullName_;
}
public void setFullName_(String fullName_) {
this.fullName_ = fullName_;
}
public String getGender_() {
return gender_;
}
public void setGender_(String gender_) {
this.gender_ = gender_;
}
public String getPhoneNumber_() {
return phoneNumber_;
}
public void setPhoneNumber_(String phoneNumber_) {
this.phoneNumber_ = phoneNumber_;
}
public String getIC_() {
return IC_;
}
public void setIC_(String IC_) {
this.IC_ = IC_;
}
public String getEmail_() {
return email_;
}
public void setEmail_(String email_) {
this.email_ = email_;
}
public String getAddress_() {
return Address_;
}
public void setAddress_(String Address_) {
this.Address_ = Address_;
}
public String getPassword_() {
return password_;
}
public void setPassword_(String password_) {
this.password_ = password_;
}
public String saveUser(LoginBean loginBean){
UserDao dao = new UserDao(); //METODE SIMPAN KE DATABASE!!!
User user = new User();
user.setFullName(loginBean.getFullName_());
user.setGender(loginBean.getGender_());
user.setPhoneNumber(Integer.parseInt(loginBean.getPhoneNumber_()));
user.setIc(loginBean.getIC_());
user.setEmail(loginBean.getEmail_());
user.setPassword(loginBean.getPassword_());
dao.saveStudent(user);//untuk menyimpan di database
Map<String,Object> sessionMapObj = FacesContext.getCurrentInstance().getExternalContext().getSessionMap();
sessionMapObj.put("msg", "Data "+user.getIc() +"successfull!");
return"/sukses.xhtml?faces-redirect=true";
}
User.java
private Integer userId;
private String fullName;
private String gender;
private Integer phoneNumber;
private String ic;
private String email;
private String address;
private String password;
private Set students = new HashSet(0);
private Set staffs = new HashSet(0);
public User() {
}
public User(String fullName, String gender, Integer phoneNumber, String ic, String email, String address, String password, Set students, Set staffs) {
this.fullName = fullName;
this.gender = gender;
this.phoneNumber = phoneNumber;
this.ic = ic;
this.email = email;
this.address = address;
this.password = password;
this.students = students;
this.staffs = staffs;
}
public Integer getUserId() {
return this.userId;
}
public void setUserId(Integer userId) {
this.userId = userId;
}
public String getFullName() {
return this.fullName;
}
public void setFullName(String fullName) {
this.fullName = fullName;
}
public String getGender() {
return this.gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Integer getPhoneNumber() {
return this.phoneNumber;
}
public void setPhoneNumber(Integer phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getIc() {
return this.ic;
}
public void setIc(String ic) {
this.ic = ic;
}
public String getEmail() {
return this.email;
}
public void setEmail(String email) {
this.email = email;
}
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
public Set getStudents() {
return this.students;
}
public void setStudents(Set students) {
this.students = students;
}
public Set getStaffs() {
return this.staffs;
}
public void setStaffs(Set staffs) {
this.staffs = staffs;
}
I suppose you want to have a look at jdbc. Java Database Connectivity allows you to create sql queries in java. However, alot of times a Java Persistence API is used (JPA) in Java EE applications. This is a specification on how you can store and retrieve Java-Objects from a database. A very common implementation of that is the hibernate framework.
If you want to enable Hibernate capabilies for your jsf project, follow this guide:
https://howtodoinjava.com/hibernate/hibernate-3-introduction-and-writing-hello-world-application/. If your project isn't build with Maven, just ignore that part of the tutorial.
With hibernate for eg. you can create a User Entity. You can follow this easy tutorial on how to create entities: https://www.baeldung.com/jpa-entities
Now let's suppose you don't want to use any of that and just want a default solution with jdbc:
import java.sql.*;
public class Userdao
{
public static void saveUser(User user)
{
try
{
value1 = user.getId();
value2 = user.getFirstName();
value3 = user.getLastName();
String myUrl = "jdbc:somesql:localhost/test";
//now we load the driver
Class.forName("oracle.jdbc.driver.OracleDriver"); //download the correct driver of your database and add as library to your project
Connection conn = DriverManager.getConnection(myUrl, "root", "");
// our SQL SELECT query.
// if you only need a few columns, specify them by name instead of using "*"
String addUserQuery = "INSERT INTO table_name (column1, column2, column3, ...) VALUES (" + value1 + ", " + value2 + ", " + value3, + "...);" //column1 could be Userid-Primarykey, 2 Name ...
Statement addSt = conn.createStatement();
addSt.executeQuery(addUserQuery)
// create the java statement for retrieving
String query = "SELECT + from table_name";
Statement st = conn.createStatement();
// execute the query, and get a java resultset
ResultSet rs = st.executeQuery(query);
// iterate through the java resultset
while (rs.next())
{
int id = rs.getInt("id");
String firstName = rs.getString("first_name"); //first_name being the column name
String lastName = rs.getString("last_name");
// print the Name
System.out.format("%s, %s\n", id, firstName, lastName);
}
st.close();
}
catch (Exception e)
{
System.err.println("Got an exception! ");
System.err.println(e.getMessage());
}
}
}
Foreign Key references are handled in the database, so for. eg. if you want to get the child objects you simply need a query that joins the tables, and then extract the corresponding values from the result set.

JavaFX tableview bag on java when i parse and input data from sql

The Tableview does not completely output data from the sql table, although there are no errors. That is, the problem is that the program outputs only part of the data, although there are some in the sheet itself
SQL query class (sqlworker)
public List<String> gettableManagmet() throws SQLException {
resSet = statmt.executeQuery("PRAGMA TABLE_INFO('Users');");
List<String> ls = new ArrayList<>();
while (resSet.next()) {
ls.add(resSet.getString("name"));
}
System.out.println(ls);
return ls;
}
public ObservableList<Users> getdatausermanagment() throws SQLException {
ObservableList<Users> res = FXCollections.observableArrayList();
resSet = statmt.executeQuery("SELECT * FROM Users");
while (resSet.next()) {
String id = String.valueOf(resSet.getInt("id"));
String Login = resSet.getString("Login");
String Pass = resSet.getString("Pass");
String Otel = resSet.getString("Otel");
String isManager = String.valueOf(resSet.getInt("isManager"));
String isAdmin = String.valueOf(resSet.getInt("isAdmin"));
String isBlocked = String.valueOf(resSet.getInt("isBlocked"));
String CauseBlocking = resSet.getString("CauseBlocking");
System.out.println(id+ Login+Pass+Otel+isManager+isAdmin+isAdmin+CauseBlocking);
res.add(new Users(id,Login,Pass,Otel,isManager,isAdmin,isBlocked,CauseBlocking));
}
for(Users s : res){
System.out.println(s);
}
return res;
}
public void adddata(TableView table) throws SQLException {
ObservableList<Users> res = FXCollections.observableArrayList();
resSet = statmt.executeQuery("SELECT * FROM Users");
while (resSet.next()) {
String id = String.valueOf(resSet.getInt("id"));
String Login = resSet.getString("Login");
String Pass = resSet.getString("Pass");
String Otel = resSet.getString("Otel");
String isManager = String.valueOf(resSet.getInt("isManager"));
String isAdmin = String.valueOf(resSet.getInt("isAdmin"));
String isBlocked = String.valueOf(resSet.getInt("isBlocked"));
String CauseBlocking = resSet.getString("CauseBlocking");
System.out.println(id+ Login+Pass+Otel+isManager+isAdmin+isAdmin+isBlocked+CauseBlocking);
table.getItems().add(new Users(id,Login,Pass,Otel,isManager,isAdmin,isBlocked,CauseBlocking));
}
}
Users class
private final String id;
private final String login;
private final String pass;
private final String otel;
private SimpleStringProperty isManager;
private final String isAdmin;
private final String isBlocked;
private final String causeBloocking;
public Users(String id, String login, String pass, String otel, String isManager, String isAdmin, String isBlocked, String causeBlocking) {
this.id = id;
this.login = login;
this.pass = pass;
this.otel = otel;
this.isManager = new SimpleStringProperty(isManager);
this.isAdmin = isAdmin;
this.isBlocked = isBlocked;
this.causeBloocking = causeBlocking;
}
public String getId() {
return id;
}
public String getLogin() {
return login;
}
public String getPass() {
return pass;
}
public String getOtel() {
return otel;
}
public String getisManager() {
return isManager.get();
}
public String getisAdmin() {
return isAdmin;
}
public String getisBlocked() {
return isBlocked;
}
public String getCauseBloocking() {
return causeBloocking;
}
Class where i parse data
public TableView table;
#Override
public void initialize(URL location, ResourceBundle resources) {
SQLWorker sqlWorker = new SQLWorker();
table.setEditable(true);
try {
for (String s: sqlWorker.gettableManagmet()) {
TableColumn<Users, String> tb = new TableColumn<>(s);
tb.setCellValueFactory(new PropertyValueFactory<>(s));
tb.setCellFactory(TextFieldTableCell.forTableColumn());
tb.setVisible(true);
table.getColumns().addAll(tb);
System.out.println(tb.getProperties());
}
System.out.println(table.getColumns().size());
sqlWorker.adddata(table);
} catch (SQLException e) {
e.printStackTrace();
}
}
fxml file
enter image description here
when programme in work
enter image description here
sql database enter image description here
The issues here are
you do not adhere to the Java naming conventions for 3 of your getters; PropertyValueFactory relies on those: the property passed to the constructor is modified by converting the first letter to upper case and then PropertyValueFactory checks for methods with that modified name prefixed with get or is. It e.g. looks for getIsManager() or isIsManager() not for getisManager(). (Note that this is much easier to read btw.)
There's a typo in one of your getter (and the corresponding field) names: It should be getCauseBlocking(), not getCauseBloocking()

Firestore Add Custom Objects with Reference Attribute

I have been adding POJOs to Firestore that automatically interprets them as JSON objects for the database. However I want to have one of my POJOs have what Firestore calls a reference type. Would the attribute type just be DocumentReference instead of a String?
I'm working on an Android project using Java.
Here is the custom object example from the Firebase Docs.
public class City {
private String name;
private String state;
private String country;
private boolean capital;
private long population;
private List<String> regions;
public City() {}
public City(String name, String state, String country, boolean capital, long population, List<String> regions) {
// ...
}
public String getName() {
return name;
}
public String getState() {
return state;
}
public String getCountry() {
return country;
}
public boolean isCapital() {
return capital;
}
public long getPopulation() {
return population;
}
public List<String> getRegions() {
return regions;
}
}
Then to add to the database
City city = new City("Los Angeles", "CA", "USA",
false, 5000000L, Arrays.asList("west_coast", "sorcal"));
db.collection("cities").document("LA").set(city);
I've done some simple testing and figured it out.
The attribute type is indeed DocumentReference for custom objects when adding directly to Firestore.
Here is an example where the creator of a Group is a reference to a user in the database:
//Class POJO that holds data
public class Group {
private String name;
private DocumentReference creator;
public Group(){}
public Group(String name, DocumentReference ref) {
this.name = name;
this.creator = ref;
}
public String getName() { return this.name; }
public DocumentReference getCreator() { return this.creator; }
}
// Add to database
String uid = FirebaseAuth.getInstance().getCurrentUser().getUid();
DocumentReference ref = db.collection("users").document(uid);
Group newGroup = new Group("My Group", ref);
db.collection("groups").document().set(newGroup);

ArrayList from user model returns null

So in the app I'm creating I have a user class defined as the following
public class User implements Serializable{
private int id;
private String username;
private String firstName;
private String lastName;
private String email;
private String password;
private String picture;
private ArrayList<String> tags;
private double rating;
private Category favorite;
private boolean star;
private Location homeLocation;
public User(int id, String username, String firstName,String lastName,String picture, ArrayList<String> tags,double rating, Category favorite, boolean star,Location homeLocation,String email,String password) {
this.id = id;
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
this.picture = picture;
this.tags = tags;
this.rating = rating;
this.favorite = favorite;
this.star = star;
this.homeLocation = homeLocation;
this.email = email;
this.password = password;
}
public int getId() {
return id;
}
public String getUsername() {
return username;
}
public String getFirstName() {
return firstName;
}
public String getLastName(){ return lastName;}
public String getPicture(){ return picture;}
public ArrayList<String> getTags() {
return tags;
}
public double getRating(){ return rating;}
public Category getFavorite(){ return favorite;}
public Boolean getStar(){ return star;}
public Location getHomeLocation(){return homeLocation;}
public String getEmail(){return email;}
public String getPassword(){return password;}
public void setId(int id){
this.id = id;
}
Now, when I create a User object I pass an ArrayList<String> tags which, when logged, shows just as intended.
List<String> listTags = Arrays.asList(DummyTags.tagsNewUser);
ArrayList<String> tags = new ArrayList<>();
tags.addAll(listTags);
Log.d("Tags",tags.toString());
user = new User(0,userName,firstName,lastName,picturePlaceHolder,tags,4,category,true,loc,email,password);
However, when I use this user object in, say a profile page, and retrieve the users tags through the getter in the class it always returns null.
user = (User) getArguments().getSerializable("User");
tags = user.getTags();
Doing this always has tags be null, no matter what ArrayList I pass when creating the user object.
I also get a warning in android studio saying that invoking user.getTags() may produce a npe. Every other part of the user model works just fine. I have tried to solve this for a while now and have not been able to find anything relating to my problem so any help would be appreciated!
Try:
Bundle bundle=new Bundle();
bundle.putStringArrayList("tags",tags);
bundle.putSerializable("User",user);
and then retrieve as:
tags = getArguments().getStringArrayList("tags");
The reason that your solution does not work is that ArrayList is not implementing Serializable interface

Categories

Resources