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?
Related
I'm making a group class in java but I have a problem that If the user tries to do an operation that could violate the state of objects, I don't know how to ignore the operation
and make the application display an error message
Here is the code:
import java.util.ArrayList;
public class Group {
private static int staticNumber = 0;
private int groupNumber;
private Trainer trainer;
private String sportName;
private ArrayList<Kid> kids;
private final static int MAX_LIMIT = 10;
public Group(Trainer t, String sport) {
groupNumber = staticNumber++;
this.trainer = t;
this.sportName = sport;
kids = new ArrayList<>();
}
public static int getStaticNumber() {
return staticNumber;
}
public int getGroupNumber() {
return groupNumber;
}
public Trainer getTrainer() {
return trainer;
}
public String getSportName() {
return sportName;
}
public ArrayList<Kid> getKids() {
return kids;
}
public boolean addKid(Kid k) {
if (kids.size() < MAX_LIMIT) {
kids.add(k);
return true;
} else {
return false;
}
}
public boolean removeKid(Kid k) {
return kids.remove(k);
}
}
Adding a println() before the return will output the message in console:
public boolean addKid(Kid k) {
if (kids.size() < MAX_LIMIT) {
kids.add(k);
return true;
} else {
System.out.println("User wasn't Added Try again");
return false;
}
}
Alternatively, if you would like to throw an exception, which would terminate your run of the code:
public boolean addKid(Kid k) {
if (kids.size() < MAX_LIMIT) {
kids.add(k);
return true;
} else {
throw new ArrayIndexOutOfBoundsException("Too many Kids");
}
}
Hope this helped!
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 trying to populate a JTable with POJOS that I've extracted using Gson(). Using the debugger, or by printing the values to the console using toString(), I can see that the mapping of the objects was successful. My problem lies with populating my custom Jtable with the objects.
Problem: My GUI contains a button that takes a search field, and sends it to an API which returns a response in JSON, which I map correctly but I do not know how to get the data into the table.
What I've tried: The addFilings() and insertFilings() methods return: The method addFilings(Filing) in the type FilingsTableModel is not applicable for the arguments (ExtractorClass)
Codes
Here is the Filing Class with getters and setters and toString() method:
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class Filing {
#SerializedName("id")
#Expose
private static String id;
#SerializedName("filing_date")
#Expose
private FilingDate filingDate;
#SerializedName("accepted_date")
#Expose
private AcceptedDate acceptedDate;
#SerializedName("period_end_date")
#Expose
private PeriodEndDate periodEndDate;
#SerializedName("report_type")
#Expose
private String reportType;
#SerializedName("sec_unique_id")
#Expose
private String secUniqueId;
#SerializedName("filing_url")
#Expose
private String filingUrl;
#SerializedName("report_url")
#Expose
private String reportUrl;
public String getId() {
return id;
}
public void setId(String id) {
Filing.id = id;
}
public FilingDate getFilingDate() {
return filingDate;
}
public void setFilingDate(FilingDate filingDate) {
this.filingDate = filingDate;
}
public AcceptedDate getAcceptedDate() {
return acceptedDate;
}
public void setAcceptedDate(AcceptedDate acceptedDate) {
this.acceptedDate = acceptedDate;
}
public PeriodEndDate getPeriodEndDate() {
return periodEndDate;
}
public void setPeriodEndDate(PeriodEndDate periodEndDate) {
this.periodEndDate = periodEndDate;
}
public String getReportType() {
return reportType;
}
public void setReportType(String reportType) {
this.reportType = reportType;
}
public String getSecUniqueId() {
return secUniqueId;
}
public void setSecUniqueId(String secUniqueId) {
this.secUniqueId = secUniqueId;
}
public String getFilingUrl() {
return filingUrl;
}
public void setFilingUrl(String filingUrl) {
this.filingUrl = filingUrl;
}
public String getReportUrl() {
return reportUrl;
}
public void setReportUrl(String reportUrl) {
this.reportUrl = reportUrl;
}
public String toString() {
return "[id: " + id + ", Filing Date: " + filingDate.year + "/" + filingDate.month + "/" + filingDate.day
+ ", report_type: " + reportType + ", Report url: " + reportUrl + "]";
}
}
Here is the Extractor class to map the objects:
import java.util.List;
import com.google.gson.annotations.Expose;
import com.google.gson.annotations.SerializedName;
public class ExtractorClass {
#SerializedName("filings")
#Expose
private List<Filing> filings = null;
#SerializedName("company")
#Expose
private Company company;
#SerializedName("next_page")
#Expose
private String nextPage;
public List<Filing> getFilings() {
return filings;
}
public void setFilings(List<Filing> filings) {
this.filings = filings;
}
public Company getCompany() {
return company;
}
public void setCompany(Company company) {
this.company = company;
}
public String getNextPage() {
return nextPage;
}
public void setNextPage(String nextPage) {
this.nextPage = nextPage;
}
}
Here is the JButton in the main application window:
JButton btnNewButton = new JButton("Search");
btnNewButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
ApiClient defaultClient = Configuration.getDefaultApiClient();
ApiKeyAuth auth = (ApiKeyAuth) defaultClient.getAuthentication("ApiKeyAuth");
auth.setApiKey("API_KEY");
// String identifier = "AAPL"; // String | A Company identifier (Ticker,
// CIK, LEI, Intrinio ID)
String reportType = null; // String | Filter by report type [see -
// /documentation/sec_filing_report_types]. Separate values with commas to
// return multiple report types.
LocalDate startDate = null; // LocalDate | Filed on or after the given date
LocalDate endDate = null; // LocalDate | Filed before or after the given date
Integer pageSize = 50; // Integer | The number of results to return
String nextPage = null; // String | Gets the next page of data from a previous API call
String userInput = null;
CompanyApi companyApi = new CompanyApi();
userInput = textField.getText().trim().toUpperCase();
String identifier = userInput;
try {
ApiResponseCompanyFilings result = companyApi.getCompanyFilings(identifier, reportType, startDate,
endDate, pageSize, nextPage);
String convertedResult = new Gson().toJson(result);
ExtractorClass extractedObjects = new Gson().fromJson(convertedResult, ExtractorClass.class);
model.addFilings(extractedObjects);
} catch (ApiException e) {
System.err.println("Exception when calling CompanyApi#getCompanyFilings");
e.printStackTrace();
}
}
});
And finally here is the custom table:
import java.util.ArrayList;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import com.g4ther.SECextractor.Date;
import com.g4ther.SECextractor.Filing;
import com.g4ther.SECextractor.FilingDate;
public class FilingsTableModel extends AbstractTableModel
{
private String[] columnNames =
{
"ID",
"Filing Date",
"Report Type",
"Report URL"
};
private List<Filing> filings;
public FilingsTableModel()
{
filings = new ArrayList<Filing>();
}
public FilingsTableModel(List<Filing> filings)
{
this.filings = filings;
}
public int getColumnCount()
{
return columnNames.length;
}
public String getColumnName(int column)
{
return columnNames[column];
}
public int getRowCount()
{
return filings.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)
{
Filing filing = getFiling(row);
switch (column)
{
case 0: return filing.getId();
case 1: return filing.getFilingDate();
case 2: return filing.getReportType();
case 3: return filing.getReportUrl();
default: return null;
}
}
#Override
public void setValueAt(Object value, int row, int column)
{
Filing filing = getFiling(row);
switch (column)
{
case 0: ((Filing) filing).setId((String)value); break;
case 1: ((Filing) filing).setFilingDate((FilingDate)value); break;
case 2: ((Filing) filing).setReportType((String)value); break;
case 3: ((Filing) filing).setReportUrl((String)value); break;
}
fireTableCellUpdated(row, column);
}
public Filing getFiling(int row)
{
return filings.get( row );
}
public void addFilings(Filing filing)
{
insertFilings(getRowCount(), filing);
}
public void insertFilings(int row, Filing filing)
{
filings.add(row, filing);
fireTableRowsInserted(row, row);
}
}
Original API response:
{
"filings": [
{
"id": "fil_95GBZB",
"filing_date": {
"year": 2019,
"month": 10,
"day": 30
},
"accepted_date": {
"dateTime": {
"date": {
"year": 2019,
"month": 10,
"day": 30
},
"time": {
"hour": 16,
"minute": 30,
"second": 40,
"nano": 0
}
},
"offset": {
"totalSeconds": 0
}
},
"period_end_date": {
"year": 2019,
"month": 10,
"day": 30
},
"report_type": "8-K",
"sec_unique_id": "0000320193-19-000117",
"filing_url": "https://www.sec.gov/Archives/edgar/data/320193/000032019319000117/0000320193-19-000117-index.htm",
"report_url": "https://www.sec.gov/ix?doc\u003d/Archives/edgar/data/320193/000032019319000117/a8-kq420199282019.htm",
"instance_url": "https://www.sec.gov/Archives/edgar/data/320193/000032019319000117/aapl-20191030.xsd"
}
],
"company": {
"id": "com_NX6GzO",
"ticker": "AAPL",
"name": "Apple Inc",
"lei": "HWUPKR0MPOU8FGXBT394",
"cik": "0000320193"
},
"next_page": "MjAxOS0xMC0zMHw1NzkxNjc1"
}
After mapping it and printing the extractedObjects to the console:
[[id: null, Filing Date: 2019/10/30, report_type: 8-K, Report url: https://www.sec.gov/ix?doc=/Archives/edgar/data/320193/000032019319000117/a8-kq420199282019.htm]]
Really stuck here, can anyone help me please?
The method addFilings(Filing) in the type FilingsTableModel is not applicable for the arguments (ExtractorClass)
First of all the method name should be addFiling(...) since the parameter is a single Filing object.
Your extractor class has the following method:
public List<Filing> getFilings()
{
return filings;
}
Which returns a List of Filing objects.
So you need to iterate through the List and invoke the addFiling(...) method for each Filing object contained in the List.
I have this code:
public void addSkillXp(SkillType attribute, int value) {
final SkillDatabaseEntity skillDatabaseEntity = skillValueCache.getEntity();
switch (attribute) {
case TWO_HANDED_CRUSHING_WEAPONS:
skillDatabaseEntity.setTwoHandedCrushingWeaponsXp(value);
skillMapper.addTwoHandedCrushingWeaponsXp(userEntity.getId(), value);
break;
case ONE_HANDED_CRUSHING_WEAPONS:
skillDatabaseEntity.setOneHandedCrushingWeaponsXp(value);
skillMapper.addOneHandedCrushingWeaponsXp(userEntity.getId(), value);
break;
case TWO_HANDED_AXES:
skillDatabaseEntity.setTwoHandedAxesXp(value);
skillMapper.addTwoHandedAxesXp(userEntity.getId(), value);
break;
case ONE_HANDED_AXES:
skillDatabaseEntity.setOneHandedAxesXp(value);
skillMapper.addOneHandedAxesXp(userEntity.getId(), value);
break;
case THROWING_WEAPONS:
skillDatabaseEntity.setThrowingWeaponsXp(value);
skillMapper.addThrowingWeaponsXp(userEntity.getId(), value);
break;
case FISTFIGHT:
skillDatabaseEntity.setFistfightXp(value);
skillMapper.addFistfightXp(userEntity.getId(), value);
break;
...
}
The switch is goes on for more 20 cases. The SkillDatabaseEntity is a simple DAO class:
public class SkillDatabaseEntity {
private int twoHandedCrushingWeaponsXp;
private int oneHandedCrushingWeaponsXp;
private int twoHandedAxesXp;
private int oneHandedAxesXp;
private int throwingWeaponsXp;
private int fistfightXp;
private int longswordsXp;
private int shortswordsXp;
private int polearmsXp;
private int daggersXp;
private int longbowsXp;
private int showrtbowsXp;
private int crossbowsXp;
private int lightArmorXp;
private int heavyArmorXp;
private int robeArmorXp;
private int armorlessDefenseXp;
private int shieldDefenseXp;
private int staffsXp;
private int wandsXp;
private int spectresXp;
private int scavengingXp;
private int cookingXp;
public int getTwoHandedCrushingWeaponsXp() {
return twoHandedCrushingWeaponsXp;
}
public void setTwoHandedCrushingWeaponsXp(int twoHandedCrushingWeaponsXp) {
this.twoHandedCrushingWeaponsXp = twoHandedCrushingWeaponsXp;
}
public int getOneHandedCrushingWeaponsXp() {
return oneHandedCrushingWeaponsXp;
}
public void setOneHandedCrushingWeaponsXp(int oneHandedCrushingWeaponsXp) {
this.oneHandedCrushingWeaponsXp = oneHandedCrushingWeaponsXp;
}
public int getTwoHandedAxesXp() {
return twoHandedAxesXp;
}
public void setTwoHandedAxesXp(int twoHandedAxesXp) {
this.twoHandedAxesXp = twoHandedAxesXp;
}
public int getOneHandedAxesXp() {
return oneHandedAxesXp;
}
public void setOneHandedAxesXp(int oneHandedAxesXp) {
this.oneHandedAxesXp = oneHandedAxesXp;
}
public int getThrowingWeaponsXp() {
return throwingWeaponsXp;
}
public void setThrowingWeaponsXp(int throwingWeaponsXp) {
this.throwingWeaponsXp = throwingWeaponsXp;
}
...
}
I need to add removeSkillXp but really want to avoid this huge switch and also if I'm here I want to improve that old scwitch too. How can I do that?
What I have as a plan is to create a new class like this:
SkillModifier:
increaseExperience(UserEntity, value)
decreaseExperience(UserEntity, value)
getExperience(UserEntity, value)
getSupportedSkillType()
And create an instance of this class for every case in the switch, add the instances into a map (This can be easily done with Spring DI) and use something like this:
public void addSkillXp(SkillType attribute, int value) {
skillMap.get(attribute).increaseExperience(userEntity, value);
}
Can this work? Or is there a better pattern to do?
If you move the functionality from the code into the object, things get much easier.
For example:
enum SkillType {
TWO_HANDED_CRUSHING_WEAPONS {
#Override
void updateEntity(SkillDatabaseEntity entity, int value) {
entity.setTwoHandedCrushingWeaponsXp(value);
}
#Override
void mapSkill(SkillMapper mapper, int userId, int value) {
mapper.addTwoHandedCrushingWeaponsXp(userId, value);
}
},
ONE_HANDED_CRUSHING_WEAPONS {
#Override
void updateEntity(SkillDatabaseEntity entity, int value) {
entity.addOneHandedCrushingWeaponsXp(value);
}
#Override
void mapSkill(SkillMapper mapper, int userId, int value) {
mapper.addOneHandedCrushingWeaponsXp(userId, value);
}
},
TWO_HANDED_AXES {
#Override
void updateEntity(SkillDatabaseEntity entity, int value) {
entity.setTwoHandedAxesXp(value);
}
#Override
void mapSkill(SkillMapper mapper, int userId, int value) {
mapper.addTwoHandedAxesXp(userId, value);
}
};
abstract void updateEntity(SkillDatabaseEntity entity, int value);
abstract void mapSkill(SkillMapper mapper, int userId, int value);
}
public void addSkillXp(SkillType skill, int value) {
final SkillDatabaseEntity skillDatabaseEntity = skillValueCache.getEntity();
skill.updateEntity(skillDatabaseEntity, value);
skill.mapSkill(skillMapper, userEntity.getId(), value);
}
Here addSkillXp has become just three lines of code.
Another elegant benefit to this is that all of the skill-reelated code is in the same enum.
The whole switch seems redundant because each case does the same thing. Why not create an abstract class weapon which has a method increaseXP and is extended by each weapon class (2h etc.).
In this way the implementation is in the abstract class and the other sub-classes just call .increaseXP. By the way the database class seems unnecessary, just keep a list / array of weapons for each player.
Some more background info see:
https://sourcemaking.com/refactoring/replace-conditional-with-polymorphism
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