i want to update my database using jtable, table r disply but not update please provide mi solution for it
i am doing following code but it cant update my database and how can fire query for that my database contain id,name,password,email,phone_no
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import javax.swing.JFrame;
import javax.swing.JTable;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableCellEditor;
public class JtExample extends JFrame {
JTable tbldetails;
DefaultTableModel dtm ;
public int editcol1;
public int editrow;
public JtExample() {
setVisible(true);
setSize(500,500);
setTitle("login Frame");
setLocationRelativeTo(null);
setLayout(null);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
dtm = new DefaultTableModel(); //dtm consiste row and clonum
String rowheader[] = {"ID","Name" ,"Password", "Email","phn_no"};
dtm.addColumn("ID");
dtm.addColumn("Name");
dtm.addColumn("address");
dtm.addColumn("Email");
dtm.addColumn("phn_no");
dtm.addRow(rowheader);
add();
dtm.addTableModelListener(new TableModelListener ()
{
#Override
public void tableChanged(TableModelEvent arg0) {
int editcol1 =tbldetails.getEditingColumn();
int editrow =tbldetails.getEditingRow();
TableCellEditor tce = tbldetails.getCellEditor(editrow , editcol1);
System.out.println(tce.getCellEditorValue());
}
});
tbldetails = new JTable(dtm);
tbldetails.setBounds(100,100,500,200);
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://Localhost:3306/mydata","root","root");
PreparedStatement ps=con.prepareStatement(" update employee set editcol1=? where editrow=?");
int editcol1 = 0;
String tce = null;
ps.setString(editcol1, tce);
int i=ps.executeUpdate();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
add(tbldetails);
}
public void add()
{
try {
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://Localhost:3306/mydata","root","root");
Statement st = con.createStatement();
ResultSet rs = st.executeQuery("select *from employee");
while(rs.next())
{
dtm.addRow(new Object[]{rs.getString(1), rs.getString(2), rs.getString(3), rs.getString(4), rs.getString(5)});
}
con.close();
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void main(String args[])
{
new JtExample();
}
}
public static void main(String args[])
{
new JtExample();
}
}
Note: There is more then one way to skin this cat
My first thought is, don't use a DefaultTableModel, instead, use a AbstractTableModel, this will give you greater control of the model and changes to its state.
Start by defining a Plain Old Java Object (POJO) which represents your data. Personally I prefer to start with an interface, this allows me to define mutable and non-mutable versions depending on my requirements
Something like...
public class Employee {
private String id; //??
private String name;
private String password; // Probably should be a char[]
private String email;
private String phoneNumber;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public Employee(String id, String name, String password, String email, String phoneNumber) {
this.id = id;
this.name = name;
this.password = password;
this.email = email;
this.phoneNumber = phoneNumber;
}
}
...for example
Next, you need to define a TableModel which is capable of supporting this data...
public class EmployeeTableModel extends AbstractTableModel {
private String columnNames[] = {"ID","Name" ,"Password", "Email","phn_no"};
private List<Employee> employees;
public EmployeeTableModel() {
employees = new ArrayList<Employee>(25);
}
public EmployeeTableModel(List<Employee> employees) {
this.employees = employees;
}
public void add(Employee employee) {
employees.add(employee);
fireTableRowsInserted(employees.size() - 1, employees.size() - 1);
}
public void remove(Employee employee) {
int index = employees.indexOf(employee);
employees.remove(employee);
fireTableRowsDeleted(index, index);
}
#Override
public int getRowCount() {
return employees.size();
}
#Override
public int getColumnCount() {
return columnNames.length;
}
#Override
public String getColumnName(int column) {
return columnNames[column];
}
public Employee getEmployeeAt(int row) {
return employees.get(row);
}
#Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Employee emp = getEmployeeAt(rowIndex);
Object value = null;
switch (columnIndex) {
case 0:
value = emp.getId();
break;
case 1:
value = emp.getName();
break;
case 2:
value = emp.getPassword();
break;
case 3:
value = emp.getEmail();
break;
case 4:
value = emp.getPhoneNumber();
break;
}
return value;
}
}
We're going to add to this later, but for now, this gives us the basics we need...
When you load the data from the database, you could use something like...
EmployeeTableModel model = new EmployeeTableModel();
try (ResultSet rs = st.executeQuery("select *from employee")) {
while(rs.next())
{
model.add(new Employee(
rs.getString(1),
rs.getString(2),
rs.getString(3),
rs.getString(4),
rs.getString(5)));
}
} finally {
tbldetails.setModel(model);
}
So, now we have a self contained unit of work, in our Employee class, a TabelModel which can support it and a means by which you can load the data, now, you need some way to intercept the changes to the data and update the database.
To this end, we're going to update the EmployeeTableModel
public class EmployeeTableModel extends AbstractTableModel {
//...
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return columnIndex > 0; // id should not be editable here...
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
Employee emp = getEmployeeAt(rowIndex);
switch (columnIndex) {
case 1:
emp.setName(aValue.toString());
break;
case 2:
emp.setPassword(aValue.toString());
break;
case 3:
emp.setEmail(aValue.toString());
break;
case 4:
emp.setPhoneNumber(aValue.toString());
break;
}
update(emp);
fireTableCellUpdated(rowIndex, columnIndex);
}
This will call the update method every time a cell is updated. To this, we pass the Employee object. Based on the value of the id property, you will either need to update or insert a new record.
This is a very simple example, because of the nature of JDBC, the JDBC call could take a period of time to execute. I might be tempted to have some kind of (blocking) queue, onto which I could add Employee objects.
This queue would be processed by another Thread (or SwingWorker or some such), which would pop off the next object and process it, triggering an event callback (to which the TableModel would be listening) with the updated data. The TableModel would then be able to update itself accordingly...
Another idea is to simply have a "save" button, which the user can click. You would then simply iterate through the list of Employees and update them. For this, I would have a simple boolean flag for each object, which would be set to true whenever any of the set methods are called
public class Employee {
private boolean changed = false;
public boolean hasChanged() {
return changed;
}
public void setName(String name) {
this.name = name;
changed = true;
}
Take a closer look at How to Use Tables for moe details
Related
I want to populate jTable from database I used a code that a member on stackoverflow proposed for me here is the code
UsersTableModel.java:
import com.home.user.db.vo.UsersVo;
import java.sql.Date;
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
public class DefaultTableModel extends AbstractTableModel{
private String[] columnNames =
{
"FIRST NAME",
"LAST NAME",
"AGE"
}
private List<UsersVo> users;
public DefaultTableModel()
{
users = new ArrayList<UsersVo>();
}
public DefaultTableModel(List<UsersVo> users)
{
this.users = users;
}
#Override
public int getColumnCount()
{
return columnNames.length;
}
#Override
public String getColumnName(int column)
{
return columnNames[column];
}
#Override
public int getRowCount()
{
return users.size();
}
#Override
public Class getColumnClass(int column){
switch (column)
{
case 2: return Date.class;
default: return String.class;
}
}
#Override
public boolean isCellEditable(int row, int column){
switch (column)
{
case 2: return true; // only the birth date is editable
default: return false;
}
}
#Override
public Object getValueAt(int row, int column){
UsersVo users = getUserVo(row);
switch (column)
{
case 0: return users.getFirstName();
case 1: return users.getLastName();
case 2: return users.getAge();
;
default: return null;
}
}
#Override
public void setValueAt(Object value, int row, int column){
UsersVo users = getUserVo(row);
switch (column)
{
case 0: users.setFirstName((String)value); break;
case 1: users.setLastName((String)value); break;
case 2: users.setAge((Date)value); break;
}
fireTableCellUpdated(row, column);
}
public UsersVo getUserVo(int row){
return users.get( row );
}
public void addUserVo(UsersVo user){
insertUsersVo(getRowCount(), user);
}
public void insertUsersVo(int row, UsersVo user){
users.add(row, user);
fireTableRowsInserted(row, row);
}
}
this is the usersVo.java :
public class UsersVo {
private String firstName;
private String lastName;
private Date age;
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Date getAge() {
return birthdate;
}
public void setAge(Date age) {
this.birthdate = birthdate;
}
UsersDao.java: (Implementation the abstract method from DaoList)
public class UsersDao extends Dao implements DaoList<UsersVo>{
private static UsersDao userDao;
private Object users;
private UsersDao(){
}
public static UsersDao getInstance(){
if(userDao == null){
userDao = new usersDao();
}
return usersDao;
}
private Object usersModel;
#Override
public UsersVo getData(UsersVo uv) throws Exception {
Connection con = null;
UsersVo userVo = null;
ResultSet rs = null;
PreparedStatement ps = null;
try{
con = getConnection();
String sql = "SELECT * FROM USERS";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while(rs.next()){
userVo = new UsersVo();
userVo.setFirstName(rs.getString("FIRST_NAME"));
userVo.setLastName(rs.getString("LAST_NAME"));
userVo.setBirthDate(rs.getDate("BIRTH_DATE"));
usersModel.addUserVo(userVo);
}
}catch(Exception ex){
JOptionPane.showMessageDialog(null,ex.getMessage());
}finally{
rs.close();
ps.close();
closeConnection(con);
}
return userVo;
}
DaoList interface :
public interface DaoList<T> {
public List<T>
loadAll() throws Exception;
public int insert(T t) throws Exception;
public int update(T t) throws Exception;
public int delete(T t) throws Exception;
public T getData(T t) throws Exception;
public T getDataById(int id) throws Exception;
}
UserView.java:
public class UsersView extends javax.swing.JFrame {
UsersTableModel utm = new UsersTableModel();
public UsersView() {
initComponents();
this.setLocationRelativeTo(null);
jTable1.setModel(utm);
}
.
.
.
I only get the column names in the table without data from database can you tell me where is the problem please ?
I'm new to java. I'm following a tutorial to retrieve images and other data from db to a jTable. Data will retrieve to an ArrayList first, and I get this error saying array required but object found. I have added all my code. The error is in the TheModel.java file. Any help would be appreciated.
Course.java
package my.welcomescreen;
public class Course {
private int id;
private String name;
private byte[] imag;
private String desc;
public Course(){}
public Course(int Id, String Name, byte[] image, String description){
this.id = Id;
this.name = Name;
this.imag = image;
this.desc = description;
}
public int getID(){
return id;
}
public void setID(int ID){
this.id = ID;
}
public String getName(){
return name;
}
public void setName(String Name){
this.name = Name;
}
public byte[] getImage(){
return imag;
}
public String getDesc(){
return desc;
}
public void setDesc(String Description){
this.desc = Description;
}
}
MainQuery.java
package my.welcomescreen;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
public class MainQuery {
public ArrayList<Course> BindTable(){
ArrayList<Course> list = new ArrayList<Course>();
db databaseCon = new db();
Connection dbconnect = db.dbconnect();
Connection con = databaseCon.dbconnect();
Statement st;
ResultSet rs;
try{
st = con.createStatement();
String sql = "select id,name,img,description from courses";
rs = st.executeQuery(sql);
Course c;
while(rs.next()){
c = new Course(
rs.getInt("id"),
rs.getString("name"),
rs.getBytes("img"),
rs.getString("description")
);
}
} catch (SQLException ex) {
Logger.getLogger(Admin_Panel.class.getName()).log(Level.SEVERE, null, ex);
}
return list;
}
}
TheModel.java
package my.welcomescreen;
import javax.swing.Icon;
import javax.swing.table.AbstractTableModel;
public class TheModel extends AbstractTableModel {
private String[] columns;
private Object[] rows;
public TheModel(){}
public TheModel(Object[][] data, String[] columnName){
this.rows = data;
this.columns = columnName;
}
public Class getColumnClass(int Column){
if(Column == 2){
return Icon.class;
} else {
return getValueAt(0,Column).getClass();
}
}
public int getRowCount() {
return this.rows.length;
}
public int getColumnCount() {
return this.columns.length;
}
public Object getValueAt(int rowIndex, int columnIndex) {
return this.rows[rowIndex][columnIndex]; //this is the error line : array required but object found
}
public String getColumnName(int col){
return this.columns[col];
}
}
Main Method
public void displayJTable(){
MainQuery mq = new MainQuery();
ArrayList<Course> list = mq.BindTable();
String[] columnName = {"Id","Course Name","Image","Description"};
Object[][] rows = new Object[list.size()][3];
for(int i = 0; i < list.size(); i++){
rows[i][0] = list.get(i).getID();
rows[i][1] = list.get(i).getName();
if(list.get(i).getImage() != null){
ImageIcon image = new ImageIcon(new ImageIcon(list.get(i).getImage()).getImage()
.getScaledInstance(150, 120, Image.SCALE_SMOOTH) );
rows[i][2] = image;
}
rows[i][3] = list.get(i).getDesc();
}
TheModel model = new TheModel(rows, columnName);
jTable1.setModel(model);
jTable1.setRowHeight(120);
jTable1.getColumnModel().getColumn(3).setPreferredWidth(150);
}
In TheModel, it should be
public class TheModel extends AbstractTableModel {
private String[] columns;
private Object[][] rows; //since data is 2 dimensional array
..//rest of code
}
rows is an Object array in your case, but you need an array of arrays of Objects
Object[] -> Object[][]
Your TableModel is wrong. Don't:
Use an Array to hold the Course objects, because you don't know how big to make the Array to hold all the objects.
Use a 2D Array as a parameter to construct the class.
Instead:
Use an ArrayList to hold the Course objects. The ArrayList size will increase automatically as more space is needed to hold all the objects.
Pass in the ArrayList as a parameter when you create the model.
See Row Table Model for a step by step example on how to create a custom TableModel for a custom Object.
I got a tableview with a tablecolumn ("ID").
How can i link the ID to show the value?
For example: ID 90 has to be "Shop" and ID 91 has to be "Wallmart"..
I'm using 2 tables:
Person(id, personName, personShopID)
Items(id, shopName)
PersonShopID links to ITEMS id and i have to show the shopName instead of the ID..
Note: I'm using JavaFX and i'm getting data from mysql database and i'm using tcShopName.setCellValueFactory(new PropertyValueFactory<>("personShopID"));
kind regards !
package databag;
import java.sql.Timestamp;
import java.sql.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import vivesgoal.controller.CustomDate;
/**
*
* #author Lowie Menu
*/
public class PersoonBag {
private int id;
private String naam;
private String voornaam;
private Date geboortedatum;
private String opmerking;
private boolean isTrainer;
private int ploeg_id;
public PersoonBag(int id, String naam, String voornaam, Date geboortedatum, String opmerking,boolean isTrainer, int ploeg_id){
this.id=id;
this.naam=naam;
this.voornaam=voornaam;
this.geboortedatum=geboortedatum;
this.opmerking=opmerking;
this.isTrainer=isTrainer;
this.ploeg_id=ploeg_id;
}
public PersoonBag()
{
}
public int getId() {
return id;
}
public String getNaam() {
return naam;
}
public String getVoornaam() {
return voornaam;
}
public Date getGeboortedatum() {
return geboortedatum;
}
public String getGeboortedatumAlter(){
DateFormat df = new SimpleDateFormat("dd-MM-yyyy");
String datum = df.format(geboortedatum);
return datum;
}
public CustomDate getMyDate(){
return new CustomDate(geboortedatum.getTime());
}
public java.util.Date getGeboortedatumUtil(){
return geboortedatum;
}
public String getOpmerking() {
return opmerking;
}
public boolean isIsTrainer() {
return isTrainer;
}
public int getPloeg_id() {
return ploeg_id;
}
public void setId(int id) {
this.id = id;
}
public void setNaam(String naam) {
this.naam = naam;
}
public void setVoornaam(String voornaam) {
this.voornaam = voornaam;
}
public void setGeboortedatum(Date geboortedatum) {
this.geboortedatum =geboortedatum;
}
public void setOpmerking(String opmerking) {
this.opmerking = opmerking;
}
public void setIsTrainer(boolean isTrainer) {
this.isTrainer = isTrainer;
}
public void setPloeg_id(int ploeg_id) {
this.ploeg_id = ploeg_id;
}
}
and class Team (dutch ploeg)
package databag;
/**
*
* #author Lowie Menu
*/
public class PloegBag {
private int id;
private String naam;
private String niveau;
private int trainer_id;
public PloegBag(int id, String naam, String niveau, int trainer_id){
this.id = id;
this.naam = naam;
this.niveau = niveau;
this.trainer_id = trainer_id;
}
public PloegBag(){
}
public void setId(int id) {
this.id = id;
}
public void setNaam(String naam) {
this.naam = naam;
}
public void setNiveau(String niveau) {
this.niveau = niveau;
}
public void setTrainer_id(int trainer_id){
this.trainer_id=trainer_id;
}
public int getId() {
return id;
}
public String getNaam() {
return naam;
}
public String getNiveau() {
return niveau;
}
public int getTrainer_id(){
return trainer_id;
}
}
Note: i'm trying to link ploeg_id from PersoonBag to the name of PloegBag(ploegnaam).
This sql code gets me the name of the club matching the id
select * from persoon AS p INNER JOIN ploeg AS ploeg ON p.ploeg_id =ploeg.id where ploeg.naam=?"
Update: no value in ploeg.naam? maybe issue here
p
ublic ArrayList<PersoonBag> zoekAlleSpelers() throws DBException, ApplicationException {
ArrayList<PersoonBag> pb = new ArrayList<>();
try (Connection conn = ConnectionManager.getConnection();) {
try(PreparedStatement stmt = conn.prepareStatement(
"select * from persoon inner join ploeg where persoon.ploeg_id = ploeg.id");) {
// execute voert elke sql-statement uit, executeQuery enkel de eenvoudige
stmt.execute();
// result opvragen (en automatisch sluiten)
try (ResultSet rs = stmt.getResultSet()) {
// van alle rekennigen uit de database,
// RekeningBag-objecten maken en in een RekeningVector steken
while (rs.next()) {
PersoonBag p = new PersoonBag();
PloegBag ploeg = new PloegBag();
// ploeg.setId(rs.getInt("id"));
ploeg.setNaam(rs.getString("naam"));
p.setId(rs.getInt("id"));
p.setNaam(rs.getString("naam"));
p.setVoornaam(rs.getString("voornaam"));
p.setGeboortedatum(rs.getDate("geboortedatum"));
p.setOpmerking(rs.getString("opmerking"));
p.setIsTrainer(rs.getBoolean("isTrainer"));
p.setPloeg_id(ploeg);
pb.add(p);
}
return pb;
} catch (SQLException sqlEx) {
throw new DBException(
"SQL-exception in zoekAlleRekeningen - resultset");
}
} catch (SQLException sqlEx) {
throw new DBException(
"SQL-exception in zoekAlleRekeningen - statement");
}
} catch (SQLException sqlEx) {
throw new DBException(
"SQL-exception in zoekAlleRekeningen - connection");
}
}
Still have'nt found the issue.. this is function to store the data from the sql query in the table note: this works only ploegname isn't showing
PersoonDB pdb = new PersoonDB();
ArrayList<PersoonBag> persoonbag = new ArrayList<>();
try {
ArrayList<PersoonBag> spelersLijst = pdb.zoekAlleSpelers();
for (PersoonBag r : spelersLijst) {
PersoonBag speler = new PersoonBag(r.getId(),r.getNaam(), r.getVoornaam(),r.getMyDate(),r.getOpmerking(), r.isIsTrainer(),r.getPloeg_id());
persoonbag.add(speler);
}
ObservableList<PersoonBag> spelers = FXCollections.observableArrayList(persoonbag);
taSpelers.setItems(spelers);
Cell items:
#FXML
private TableView<PersoonBag> taSpelers;
#FXML
private TableColumn tcFamilienaam;
#FXML
private TableColumn tcVoornaam;
#FXML
private TableColumn tcOpmerking;
#FXML
private TableColumn<PersoonBag, CustomDate> tcGeboortedatum;
#FXML
private TableColumn<PersoonBag, PloegBag> tcPloeg;
#Override
public void initialize(URL url, ResourceBundle rb) {
tcFamilienaam.setCellValueFactory(new PropertyValueFactory<>("naam"));
tcVoornaam.setCellValueFactory(new PropertyValueFactory<>("voornaam"));
tcGeboortedatum.setCellValueFactory(new PropertyValueFactory<PersoonBag, CustomDate>("geboortedatum"));
tcOpmerking.setCellValueFactory(new PropertyValueFactory<>("opmerking"));
tcPloeg.setCellValueFactory(new PropertyValueFactory<>("ploeg"));
tcPloeg.setCellFactory(tc -> new TableCell<PersoonBag, PloegBag>() {
#Override
public void updateItem(PloegBag ploeg, boolean empty) {
if (empty || ploeg ==null){
setText("");
} else{
setText(ploeg.getNaam());
}
}
});
UPDATE!!! i'm almost there! It's getting the 'naam' data from persoon instead of 'naam' from ploeg!
issue:
while (rs.next()) {
PloegBag ploeg = new PloegBag();
ploeg.setId(rs.getInt("id"));
ploeg.setNaam(rs.getString("naam"));
PersoonBag p = new PersoonBag();
p.setId(rs.getInt("id"));
p.setNaam(rs.getString("naam"));
p.setVoornaam(rs.getString("voornaam"));
p.setGeboortedatum(rs.getDate("geboortedatum"));
p.setOpmerking(rs.getString("opmerking"));
p.setIsTrainer(rs.getBoolean("isTrainer"));
p.setPloeg(ploeg);
pb.add(p);
}
when i'm putting niveau instead of 'naam' it's get me the correct matching result! now i need the name..!
Instead of storing the id of the linked item, store a reference to the item itself. So your PersoonBag class will look like:
public class PersoonBag {
private int id;
private String naam;
private String voornaam;
private Date geboortedatum;
private String opmerking;
private boolean isTrainer;
private PloegBag ploeg;
public PersoonBag(int id, String naam, String voornaam, Date geboortedatum, String opmerking,boolean isTrainer, PloegBag ploeg){
this.id=id;
this.naam=naam;
this.voornaam=voornaam;
this.geboortedatum=geboortedatum;
this.opmerking=opmerking;
this.isTrainer=isTrainer;
this.ploeg=ploeg;
}
public PersoonBag()
{
}
public PloegBag getPloeg() {
return ploeg ;
}
public void setPloeg(PloegBag ploeg) {
this.ploeg = ploeg ;
}
// other get/set methods ...
}
Now you can load everything at once using an inner join in the SQL:
String sql = "select * from persoon inner join ploeg where persoon.ploeg_id = ploeg.id";
PreparedStatement statement = connection.prepareStatement(sql);
ResultSet rs = statement.executeQuery();
List<Persoon> persoonList = new ArrayList<>();
while (rs.next()) {
PloegBag ploeg = new PloegBag();
// populate ploeg with data from rs...
PersoonBag persoon = new PersoonBag();
persoon.setPloeg(ploeg);
// populate persoon with remaining data from rs...
persoonList.add(persoon);
}
(Obviously you can modify the SQL code, e.g. to retrieve specific items from the database, or just generally to improve it, etc.)
Now your JavaFX code looks like:
TableView<PersoonBag> persoonTable = new TableView<>();
TableColumn<PersoonBag, PloegBag> tcPloeg = new TableColumn<>("Ploeg");
tcPloeg.setCellValueFactory(new PropertyValueFactory<>("ploeg"));
// other columns...
To get the cells to display the value you need from the PloegBag, there are two ways. The "quick and dirty" way is just to define a toString() method in the PloegBag class:
public class PloegBag {
// ...
#Override
public String toString() {
return naam ;
}
}
This isn't very satisfactory, though, as you might want to toString() method to do something else for other reasons in your application. The "proper" way is to use a cell factory:
tcPloeg.setCellFactory(tc -> new TableCell<PersoonBag, PloegBag>() {
#Override
public void updateItem(PloegBag ploeg, boolean empty) {
if (empty || ploeg == null) {
setText(null);
} else {
setText(ploeg.getNaam());
}
}
});
1) establish a Connection to your database from your Java-program by using JDBC:
private static Connection getDBConnection() {
Connection connection = null;
try {
Class.forName("com.mysql.jdbc.Driver");
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/myDatabase?autoReconnect=true&user=myUser&password=myPass");
} catch (ClassNotFoundException | SQLException e) {
System.out.println("Error on getDBCOnnection "+e.toString());
}
return connection;
}
2) Query your Items table in a query like this:
SELECT shopName FROM Items WHERE ID = 90
Java:
public static ResultSet runQuery(String query) {
if(conn == null){
conn = getDBConnection();
}
Statement stmt;
ResultSet rs;
try {
stmt = conn.createStatement();
rs = stmt.executeQuery(query);
return rs;
} catch (SQLException e) {
System.out.println(e + " " + e.getMessage());
return null;
}
}
3) Read the result
ResultSet rs = runQuery(query);
String result = rs.getString(1);
Hibernate could do it all for you, including queries... just saying... Although steep learning curve if doing it for the first time... You need to model your container object to have these fields, for example person would have:
class Person{
long id;
String name;
String shopName;
...
}
Then in your data service (provider of data) you would query for that, lets say:
SELECT p.id, p.name, s.name
FROM person p, shop s
WHERE p.shopId = s.shopId;
and provide simple rowmapper
#Ovrride
public Person mapRow(ResultSet rs, int rowNum) throws SQLException {
Person person = new Person(rs.getInt("personId"), rs.getString("personName"), rs.getString("shopName"));
return person;
}
You end up with list of Persons, which you can operate on within app. As someone mentioned earlier, you would want to do this, beforehand. Every time you need that list you would hit a local cache, instead of going back to DB. You could set a policy to refresh cache if needed.
can you please help me rectify the code below, I'm trying to create a populated drop down list in struts 2 in Eclipse as my IDE. This is my first time to use 'STRUTS' as well as 'IDE ECLIPSE'.
To be specific by the SELECT statement I do not know how to write the code that, when a user selects the 'Make' of the car, the database extracts the different 'Models' of that make. But other select items like 'Color', should be optional in that a user can proceed to search for the 'Make' minus choosing an option from them.
Please help I'm new in ActionClass and DataBase. Thanx in advance.
package drive;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import com.opensymphony.xwork2.ActionSupport;
public class CarSearch extends ActionSupport {
private String model;
private String modification;
private String engine;
private String color;
private String bodyType;
private String minPrice;
private String maxPrice;
private String mileage;
private int minYear;
private int maxYear;
private String make;
public String execute () {
String ret = NONE;
Connection conn = null;
try {
String URL = "jdbc:mysql://localhost/Cars";
Class.forName("com.mysql.jdbc.Driver");
conn = DriverManager.getConnection(URL, "root", "$jademedia247");
String sql = "SELECT make FROM type WHERE";
sql+=" model = ? AND modification = ? ";
PreparedStatement ps = conn.prepareStatement (sql);
ps.setString(1, model);
ps.setString(2, modification);
ResultSet rs = ps.executeQuery();
while (rs.next()){
make = rs.getString(1);
ret = SUCCESS;
}
} catch (Exception e) {
ret = ERROR;
} finally {
if (conn != null) {
try {
conn.close();
} catch (Exception e) {
}
}
}
return ret;
}
public String getModel() {
return model;
}
public void setModel(String model) {
this.model = model;
}
public String getModification() {
return modification;
}
public void setModification (String modification) {
this.modification = modification;
}
public String getEngine() {
return engine;
}
public void setEngine (String engine) {
this.engine = engine;
}
public String getColor() {
return color;
}
public void setColor (String color) {
this.color = color;
}
public String getBodyType() {
return bodyType;
}
public void setBodyType(String bodyType) {
this.bodyType = bodyType;
}
public String getMinPrice() {
return minPrice;
}
public void setMinPrice(String minPrice) {
this.minPrice = minPrice;
}
public String getMaxPrice () {
return maxPrice;
}
public void setMaxPrice (String maxPrice) {
this.maxPrice = maxPrice;
}
public String getMileage () {
return mileage;
}
public void setMileage (String mileage) {
this.mileage = mileage ;
}
public int getMinYear() {
return minYear;
}
public void setMinYear(int minYear) {
this.minYear = minYear;
}
public int getMaxYear() {
return maxYear;
}
public void setMaxYear(int maxYear) {
this.maxYear = maxYear;
}
public String getMake() {
return make;
}
public void setMake(String make){
this.make = make;
}
}
PreparedStatement ps = conn.prepareStatement ("SELECT field_name FROM table_name WHERE model = ? AND modification = ? ");
ps.setString(1, model);
ps.setString(2, modification);
ResultSet rs = ps.executeQuery();
//it will help you
What is the proper relationship, in code, between a table model and the actual database queries?
Inside the addRow() method in the table model, should I place a further call to my database class, which in turn inserts the row into the database? I've illustrated this in the below code snippets.
public class MainPanel extends JPanel
{
...
public MainPanel()
{
personTableModel = new PersonTableModel();
personTable = new JTable(personTableModel);
...
insertButton = new JButton("Insert");
insertButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e)
{
String name = nameTextBox.getText();
String address = addressTextBox.getText();
Object[] row = { name, address };
personTableModel.addRow(row); // <--- Add row to model
}
});
}
}
public class PersonTableModel extends AbstractTableModel
{
private List<Object[]> data;
private List<String> columnNames;
PersonDB personDB = new PersonDB();
...
public void addRow(Object[] row)
{
// insert row into 'data'
personDB.addPerson(row); // <---- Call the personDB database class
}
...
}
public class PersonDB
{
public PersonDB()
{
// establish database connection
}
public addPerson(Object[] row)
{
// code that creates a SQL statement based on row data
// and inserts new row into database.
}
...
}
Whether or not you should directly make an insert call depends on some aspects:
Do you want other processes to access the data immediately?
Do you fear that your program crashes and you lose important information?
Can you ensure that any data persisted during addRow is meaningful (the program could terminate directly after the insert)?
Than of course it may be a good idea to directly insert the data into the backing Database.
You should however watch out, that there are two variants of addRow and two variants of insertRow. DefaultTableModel directs calls internally through insertRow(int, Vector), which would probably be the only function to overwrite, if you want to immediately persist data.
If you like the proposed idea of DTOs the examples below may help you.
The Idea is to represent "Entities" or table rows as classes in Java. A DTO is the simplest representation and normally only contains fields with respective getter and setter.
Entities can generically be persisted and loaded through ORM libraries like EclipseLink or Hibernate. Additionally for this table-application the use of DTOs provide a way of storing data not shown to the user in a clean and typed way.
DTO:
public class PersonDto {
private Long id;
private String name;
private String street;
public PersonDto() {
}
public PersonDto(Long id, String name, String street) {
this.id = id;
this.name = name;
this.street = street;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public static class NameColumn extends DtoTableModel.ColumnProvider<PersonDto, String> {
public NameColumn() {
super("Name", String.class);
}
#Override
public String getValue(PersonDto dto) {
return dto.getName();
}
#Override
public void setValue(PersonDto dto, Object value) {
dto.setName((String) value);
}
}
public static class StreetColumn extends DtoTableModel.ColumnProvider<PersonDto, String> {
public StreetColumn() {
super("Street", String.class);
}
#Override
public String getValue(PersonDto dto) {
return dto.getStreet();
}
#Override
public void setValue(PersonDto dto, Object value) {
dto.setStreet((String) value);
}
}
}
DTO based TableModel:
import javax.swing.table.AbstractTableModel;
import java.util.ArrayList;
public class DtoTableModel<T> extends AbstractTableModel {
private final ArrayList<T> rows;
private final ArrayList<ColumnProvider<T, ?>> columns;
protected DtoTableModel() {
rows = new ArrayList<T>();
columns = new ArrayList<ColumnProvider<T, ?>>();
}
#Override
public int getRowCount() {
return rows.size();
}
#Override
public int getColumnCount() {
return columns.size();
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
return columns.get(columnIndex).getValue(rows.get(rowIndex));
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
final ColumnProvider<T, ?> column = columns.get(columnIndex);
column.setValue(rows.get(rowIndex), aValue);
this.fireTableCellUpdated(rowIndex, columnIndex);
}
#Override
public String getColumnName(int column) {
return columns.get(column).getTitle();
}
public void addColumn(ColumnProvider<T, ?> column) {
this.columns.add(column);
this.fireTableStructureChanged();
}
public void addRow(T row) {
this.rows.add(row);
this.fireTableRowsInserted(this.rows.size() - 1, this.rows.size() - 1);
}
#Override
public Class<?> getColumnClass(int columnIndex) {
return this.columns.get(columnIndex).getValueClass();
}
public static abstract class ColumnProvider<T, V> {
private String title;
private final Class<V> valueClass;
protected ColumnProvider(String title, Class<V> valueClass) {
this.title = title;
this.valueClass = valueClass;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Class<V> getValueClass() {
return valueClass;
}
public abstract V getValue(T dto);
public abstract void setValue(T dto, Object value);
}
}
Example-"Application":
import javax.swing.*;
import java.awt.*;
public class JTableTest extends JFrame {
private final JTable jTable;
public JTableTest() throws HeadlessException {
super("JFrame test");
this.setDefaultCloseOperation(DISPOSE_ON_CLOSE);
final GridBagLayout layout = new GridBagLayout();
final Container contentPane = this.getContentPane();
contentPane.setLayout(layout);
final GridBagConstraints gridBagConstraints = new GridBagConstraints();
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
final DtoTableModel<PersonDto> dm = new DtoTableModel<PersonDto>();
jTable = new JTable(dm);
dm.addColumn(new PersonDto.NameColumn());
dm.addColumn(new PersonDto.StreetColumn());
dm.addRow(new PersonDto(1L, "Paul", "Mayfairy Street"));
dm.addRow(new PersonDto(2L, "Peter", "Ferdinand Street"));
JScrollPane scrollpane = new JScrollPane(jTable);
contentPane.add(scrollpane, gridBagConstraints);
this.pack();
}
public static void main(String[] args) {
final JTableTest jTableTest = new JTableTest();
jTableTest.setVisible(true);
}
}