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 ?
Related
Anybody help me? I want to change row color in TableView depending on value.
For example: i want to change row color to green color when value in column colType is equal to "good"
This is my method where Im filling TableView with data from database:
public void setCustomers() {
List<Customer> list = customer.getTable(); //getting results from database
data = FXCollections.observableArrayList();
Integer count = 1;
for (Customer customer1 : list) {
data.add(new CustomerObj(count++, customer1.getId(), customer1.getName(),
form.formatDate(customer1.getBorn().toString()), customer1.getStreet(),
customer1.getCity(), customer1.getIdCustomerType().getPhrase()));
}
tblCustomer.setItems(data);
tblCustomer.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
colID.setCellValueFactory(cell -> cell.getValue().getPropertyId());
colName.setCellValueFactory(cell -> cell.getValue().getPropertyName());
colBorn.setCellValueFactory(cell -> cell.getValue().getPropertyBorn());
colAddr.setCellValueFactory(cell -> cell.getValue().getPropertyAddr());
colCity.setCellValueFactory(cell -> cell.getValue().getPropertyCity());
colType.setCellValueFactory(cell -> cell.getValue().getPropertyType());
rowOptions.setCellValueFactory(new PropertyValueFactory<>("Button"));
editCust(); //just filling TableCell with Button
rowOptions1.setCellValueFactory(new PropertyValueFactory<>("Button"));
deleteCust(); //just filling TableCell with Button
}
And this is the CustomerObj class:
package sk.evka.fp.obj;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
public class CustomerObj {
private SimpleIntegerProperty id;
private SimpleIntegerProperty idDB;
private SimpleStringProperty name;
private SimpleStringProperty born;
private SimpleStringProperty addr;
private SimpleStringProperty city;
private SimpleStringProperty type;
public CustomerObj(Integer i, Integer id, String n, String b, String a, String c, String t) {
this.id = new SimpleIntegerProperty(i);
this.idDB = new SimpleIntegerProperty(id);
this.name = new SimpleStringProperty(n);
this.born = new SimpleStringProperty(b);
this.addr = new SimpleStringProperty(a);
this.city = new SimpleStringProperty(c);
this.type = new SimpleStringProperty(t);
}
public Integer getId() {
return id.get();
}
public Integer getIdDB() {
return idDB.get();
}
public String getName() {
return name.get();
}
public String getBorn() {
return born.get();
}
public String getAddr() {
return addr.get();
}
public String getCity() {
return city.get();
}
public String getType() {
return type.get();
}
public void setId(Integer i) {
this.id = new SimpleIntegerProperty(i);
}
public void setIdDB(Integer i) {
this.idDB = new SimpleIntegerProperty(i);
}
public void setName(String n) {
name = new SimpleStringProperty(n);
}
public void setBorn(String b) {
born = new SimpleStringProperty(b);
}
public void setAddr(String a) {
addr = new SimpleStringProperty(a);
}
public void setCity(String c) {
city = new SimpleStringProperty(c);
}
public void setType(String t) {
type = new SimpleStringProperty(t);
}
public SimpleIntegerProperty getPropertyId() {
return id;
}
public SimpleIntegerProperty getPropertyIdDB() {
return idDB;
}
public SimpleStringProperty getPropertyName() {
return name;
}
public SimpleStringProperty getPropertyBorn() {
return born;
}
public SimpleStringProperty getPropertyAddr() {
return addr;
}
public SimpleStringProperty getPropertyCity() {
return city;
}
public SimpleStringProperty getPropertyType() {
return type;
}
public void setPropertyId(SimpleIntegerProperty i) {
this.id = i;
}
public void setPropertyIdDB(SimpleIntegerProperty i) {
this.idDB = i;
}
public void setPropertyName(SimpleStringProperty n) {
name = n;
}
public void setPropertyBorn(SimpleStringProperty b) {
born = b;
}
public void setPropertyAddr(SimpleStringProperty a) {
addr = a;
}
public void setPropertyCity(SimpleStringProperty c) {
city = c;
}
public void setPropertyType(SimpleStringProperty t) {
type = t;
}
}
i havent found an answer to this nowhere.
If you want to color the whole row, use a rowFactory that changes the color of the TableRows it creates according to item property.
Furthermore you better use JavaFX properties appropriately:
Properties are not meant to be replaced themselfs. The property getter should always return the same property instance or at least instances that store listeners in a common data structure; Otherwise the value could be modified without the possibility of being notified of that fact (replacing the property with a property containing a new value).
public static class Item {
// property only assigned once
private final StringProperty type;
public Item(String type) {
this.type = new SimpleStringProperty(type);
}
// getter for value wrapped in property
public final String getType() {
return this.type.get();
}
// setter for value wrapped in property
public final void setType(String value) {
this.type.set(value);
}
// property getter
public final StringProperty typeProperty() {
return this.type;
}
}
public static Color typeToColor(String type) {
if (type == null) {
return Color.WHITESMOKE;
}
switch (type) {
case "bad":
return Color.RED;
case "good":
return Color.LIME;
default:
return Color.WHITESMOKE;
}
}
TableView<Item> table = new TableView<>(FXCollections.observableArrayList(
new Item("ok"),
new Item("bad"),
new Item("good")));
TableColumn<Item, String> typeColumn = new TableColumn<>("type");
typeColumn.setCellValueFactory(new PropertyValueFactory<>("type"));
table.setRowFactory(tv -> {
TableRow<Item> row = new TableRow<>();
StringBinding typeBinding = Bindings.selectString(row.itemProperty(), "type");
row.backgroundProperty().bind(Bindings.createObjectBinding(()
-> new Background(new BackgroundFill(typeToColor(typeBinding.get()), CornerRadii.EMPTY, Insets.EMPTY)), typeBinding));
return row;
});
table.getColumns().add(typeColumn);
Finally I have done this thing:
Callback<TableColumn<CustomerObj, String>, TableCell<CustomerObj, String>> cellFactory
= new Callback<TableColumn<CustomerObj, String>, TableCell<CustomerObj, String>>() {
public TableCell call(TableColumn p) {
TableCell cell = new TableCell<CustomerObj, String>() {
#Override
public void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
CustomerObj obj = this.getTableView().getItems().get(getIndex());
setText(obj.getType());
switch (obj.getType()) {
case "good":
setStyle("-fx-background-color: rgba(71, 209, 71, .7)");
break;
case "problem":
setStyle("-fx-background-color: rgba(255, 51, 51, .7)");
break;
case "ViP":
setStyle("-fx-background-color: rgba(255, 219, 25 .7)");
break;
default:
break;
}
} else {
setText(null);
}
}
private String getString() {
return getItem() == null ? "" : getItem().toString();
}
};
return cell;
}
};
colType.setCellFactory(cellFactory);
Works fine and looks so much better, but thanks it brought me closer to the solution.
I have a client/server program built. The object of the program is to send an array of data across to the client using sockets, display the data into a table then be able to edit it and send it back for the server to store. The program compiles fine but when run the client doesn't output the array to the table. It displays an error:
Exception in thread "AWT-EventQueue-0" java.lang.ClassCastException: java.lang.String cannot be cast to client.Network
at client.MyTableModel.getValueAt(MyTableModel.java:77)
MyTableModel class:
package client;
import java.util.ArrayList;
import javax.swing.table.AbstractTableModel;
public class MyTableModel extends AbstractTableModel {
void setData(ArrayList<Network> serversArray) {
data = serversArray;
System.out.print(this.data +"\n");
System.out.print(serversArray + "\n");
}
ArrayList<Network> data = new ArrayList();
String[] headers = {"NetworkID","Nodes","Hubs","Switches","Structure","Country","Status"};
#Override
public int getColumnCount() {
return headers.length;
}
#Override
public int getRowCount() {
return data.size();
}
#Override
public void setValueAt(Object value, int row, int col) {
switch (col) {
case 0:
data.get(row).setNetworkID((int) value);
break;
case 1:
data.get(row).setNodes((int) value);
break;
case 2:
data.get(row).setHubs((int) value);
break;
case 3:
data.get(row).setSwitches((int) value);
break;
case 4:
data.get(row).setStructure("");
break;
case 5:
data.get(row).setCountry("");
break;
case 6:
data.get(row).setStatus("");
break;
}
fireTableCellUpdated(row, col);
}
#Override
public String getColumnName(int col)
{ return headers[col]; }
#Override
public Object getValueAt(int row, int col) {
switch (col) {
case 0:
return data.get(row).getNetworkID();
case 1:
return data.get(row).getNodes();
case 2:
return data.get(row).getHubs();
case 3:
return data.get(row).getSwitches();
case 4:
return data.get(row).getStructure();
case 5:
return data.get(row).getCountry();
case 6:
return data.get(row).getStatus();
}
return 0;
}
}
Network class:
public class Network implements Serializable{
private int NetworkID;
private int Nodes;
private int Hubs;
private int Switches;
private String Structure;
private String Country;
private String Status;
public int getNetworkID(){
System.out.println(this.NetworkID);
return this.NetworkID;
}
public int getNodes(){
return this.Nodes;
}
public int getHubs(){
return this.Hubs;
}
public int getSwitches(){
return this.Switches;
}
public String getStructure(){
return this.Structure;
}
public String getCountry(){
return this.Country;
}
public String getStatus(){
return this.Status;
}
public void setNetworkID(int networkID){
this.NetworkID = networkID;
System.out.print(this.NetworkID);
}
public void setNodes(int nodes){
this.Nodes = nodes;
}
public void setHubs(int hubs){
this.Hubs = hubs;
}
public void setSwitches(int switches){
this.Switches = switches;
}
public void setStructure(String structure){
this.Structure = structure;
}
public void setCountry(String country){
this.Country = country;
}
public void setStatus(String status){
this.Status = status;
}
}
Any assistance would be much appreciated!
update:
private void displayNetworksActionPerformed(java.awt.event.ActionEvent evt) {
pw.println("SendCSV");
// receieve data array from server
try {
serversArray = (ArrayList<Network>)ois.readObject();
System.out.print(serversArray);
statusBar.setText("Object Recieved from Server!");
} catch (ClassNotFoundException ex) {
statusBar.setText("Didnt Recieve Object");
} catch (IOException ex) {
statusBar.setText("Unable to Request");
}
// 4. update jtable
this.myTableModel.setData(serversArray);
this.myTableModel.fireTableDataChanged();
}
Update:
I am still having an issue with this, is there any chance someone could assist with a solution?
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
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);
}
}