replacing the content of a jtable - java

I have a desktop application in swing with NetBeans IDE
the application has a JTable that displays
data from a lucene search operation.
Any time a new search is made ,
the table appends the new search results to
the previous search result. What I
want is for the table to replace any exiting
search results with the new search results. In order
words for the table to refresh and display the new
search results.
Any suggestions available
this is the code snippet for the datamodel
public class MyTableModel extends AbstractTableModel {
private Vector<Vector<String>> dataList = new Vector<>();
private String[] header = { "ID","SUBJECT","LETTTER FROM","LETTER DATE","DATE RECEIED",
"REMARKS","DATE DISPATCHED","DESTINATION OFFICE"};
public Vector<Vector<String>> getDataList() {
return dataList;
}
public void setDataList(Vector<Vector<String>> dataList) {
this.dataList = dataList;
fireTableDataChanged();
}
public void setHeader(String[] header) {
this.header = header;
}
public String[] getHeader() {
return header;
}
#Override
public int getRowCount() {
return dataList.size();
}
#Override
public int getColumnCount() {
return header.length;
}
#Override
public String getColumnName(int col) {
return header[col];
}
#Override
public Object getValueAt(int row, int col) {
return dataList.get(row).get(col);
}
}
this code passes the search result to the data model class
private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {
try {
searchField = searchTextField.getText();
if(!searchField.isEmpty())
{
matrix = dbs.searchDatabase(searchField + "*");
myModel.setDataList(matrix);
}
} catch (CorruptIndexException ex) {
Logger.getLogger(GNSSJFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (LockObtainFailedException ex) {
Logger.getLogger(GNSSJFrame.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException | ParseException ex) {
Logger.getLogger(GNSSJFrame.class.getName()).log(Level.SEVERE, null, ex);
}
}

If your table model is in this way,
class AllTableModel extends AbstractTableModel {
// Suppose this is the data list table is using,
List<TableData> tableData = new ArrayList<TableData>();
// Override methods goes here.
public void setTableData(List<TableData> tableData) {
this.tableData = tableData;
fireTableDataChanged();
}
}
Now, set the new data to the list using the table model instance.
allTableModel.setTableData(/* Set new search results to the list.*/);

Related

How to remove row from table after deleting the the product?

Hello when I delete a product from database through a table using a popupMenu (Right click Button) the row still shows up in the table list, the insertProduct method is working fine and inserts the row to table but the removeProduct method doesn't work can you tell me where is the problem in my code please ?
ProductTable.java:
public class ProductTable extends AbstractTableModel {
ProductsDao pd = new ProductsDao();
private final List<Products> products;
public ProductTable() throws Exception {
this.patients = (ArrayList<Products>) pd.getProductsList();
}
private String[] columnNames = {"PRODUCT NAME", "PRODUCT CATEGORY", "PRODUCT PRICE"};
#Override
public int getColumnCount() {
return columnNames.length;
}
#Override
public String getColumnName(int column) {
return columnNames[column];
}
#Override
public int getRowCount() {
return products.size();
}
#Override
public Object getValueAt(int row, int column) {
Products p = products.get(row);
switch (column)
{
case 0: return p.getProductName();
case 1: return p.getProductCategory();
case 2: return p.getProductPrice();
}
}
#Override
public void setValueAt(Object value, int row, int column) {
Products p = products.get(row);
switch (column) {
case 0: p.setProductName((String)value); break;
case 1: p.setProductCategory((Date)value); break;
case 2: p.setProductPrice((int)value); break;
}
fireTableCellUpdated(row, column);
}
public Products getProduct(int row) {
return products.get(row);
}
public void addProduct(Products p) {
insertProduct(getRowCount(), p);
}
public void insertProduct(int row, Products p) {
products.add(row, p);
fireTableRowsInserted(row, row);
}
public void deleteProduct(Products p) {
removeProduct(getRowCount(), p);
}
public void removeProduct(int row, Products p) {
products.remove(row);
fireTableRowsDeleted(row, row);
}
}
JFrame :
public void popupTable() {
JPopupMenu popupMenu = new JPopupMenu();
JMenuItem menuItem1 = new JMenuItem("Delete", new ImageIcon(getClass().getResource("")));
menuItem1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
int row = jTable1.getSelectedRow();
String cell = jTable1.getModel().getValueAt(row, 0).toString();
Products p = new Products();
p.setId(cell);
try {
int count = ProductsDao.getInstance().delete(p);
if (count == 1) {
removeRowFromTable(p);
JOptionPane.showMessageDialog(null, "Deleted");
} else {
JOptionPane.showMessageDialog(null, "Faild");
}
} catch (Exception ex) {
Logger.getLogger(AddNewPatient.class.getName()).log(Level.SEVERE, null, ex);
}
});
popupMenu.add(menuItem1);
jTable1.setComponentPopupMenu(popupMenu);
}
public static void removeRowFromTable(Products data) {
ProductTable t = (ProductTable) jTable1.getModel();
t.deleteProduct(data);
}
ProductsDao.java:
#Override
public List<Products> getProductsList() throws Exception {
Connection con = null;
PreparedStatement ps = null;
ResultSet rs = null;
ArrayList<Products> products = new ArrayList<Products>();
try {
con = getConnection();
String sql = "SELECT * FROM products ORDER BY PRODUCT_ID DESC";
ps = con.prepareStatement(sql);
rs = ps.executeQuery();
while (rs.next()) {
Products product = new Products();
product.setProductName(rs.getString("PRODUCT_NAME"));
product.setProductCategory(rs.getString("PRODUCT_CATEGORY"));
product.setProductPrice(rs.getInt("PRODUCT_PRICE"));
products.add(product);
}
} catch (Exception ex) {
JOptionPane.showMessageDialog(null, ex.getMessage());
} finally {
rs.close();
ps.close();
closeConnection(con);
}
return products;
}
These methods don't make sense I'm afraid:
public void deleteProduct(Products p) {
removeProduct(getRowCount(), p);
}
public void removeProduct(int row, Products p) {
products.remove(row);
fireTableRowsDeleted(row, row);
}
since you never really use the Products parameter, p, in any useful way to identify where it is in the table model. Also, I'm not really sure why you have two methods, and what they are each supposed to represent.
Instead, assuming that products in your TableModel is an ArrayList<Products>, and assuming that you've overridden Products equals and hashCode methods appropriately, you need to find the index of the selected item in the list and then remove it from the list and notify the listeners that this has been performed. Something like:
public void deleteProduct(Products p) {
int row = products.indexOf(p);
products.remove(row);
fireTableRowsDeleted(row, row);
}
This will only work if you override equals and hashCode correctly for Products.

JTable printing through a custom Printable Class

I have a JTable that is used to capture user input which later will be printed upon hitting the Print button. I have an image that I would want to be the header and another one to be a footer.an image showing this can be found here. I have followed the example that I found from oracle documents here. I want it exactly the way it is done in TablePrintdemo3 here.
Allow me to post the classes here.
Here is my first class:
public class Product {
String productDescription;
Double productPrice;
//dummy properties
Integer productQuantity;
Double productTotalAmount;
public Product() {
this.productDescription = "";
this.productPrice = 0.0;
this.productTotalAmount = 0.0;
this.productQuantity = 0;
}//getters and setters here
}
The second class is a custom model as shown here:
public class ProductTableModel extends AbstractTableModel {
private final List<String> columnNames;
private final List<Product> products;
public ProductTableModel() {
String[] header = new String[] {
"Quantity",
"Description",
"Unity Price",
"Total Price"
};
this.columnNames = Arrays.asList(header);
this.products = new ArrayList<>();
}
#Override
public Class<?> getColumnClass(int columnIndex) {
switch (columnIndex) {
case 0: return Integer.class;
case 1: return String.class;
case 2: return Double.class;
case 3: return Double.class;
default: throw new ArrayIndexOutOfBoundsException(columnIndex);
}
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
Product product = this.getProduct(rowIndex);
switch (columnIndex) {
case 0: return product.getProductQuantity();
case 1: return product.getProductDescription();
case 2: return product.getProductPrice();
case 3: return product.getProductTotalAmount();
default: throw new ArrayIndexOutOfBoundsException(columnIndex);
}
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return true;
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
if (columnIndex < 0 || columnIndex >= getColumnCount()) {
throw new ArrayIndexOutOfBoundsException(columnIndex);
} else {
Product product = this.getProduct(rowIndex);
switch (columnIndex) {
case 0: product.setProductQuantity((Integer)aValue); break;
case 1: product.setProductDescription((String)aValue); break;
case 2: product.setProductPrice((Double)aValue); break;
case 3: product.setProductTotalAmount((Double)aValue); break;
}
fireTableCellUpdated(rowIndex, columnIndex);
}
}
#Override
public int getRowCount() {
return this.products.size();
}
#Override
public int getColumnCount() {
return this.columnNames.size();
}
#Override
public String getColumnName(int columnIndex) {
return this.columnNames.get(columnIndex);
}
public void setColumnNames(List<String> columnNames) {
if (columnNames != null) {
this.columnNames.clear();
this.columnNames.addAll(columnNames);
fireTableStructureChanged();
}
}
public List<String> getColumnNames() {
return Collections.unmodifiableList(this.columnNames);
}
public void addProducts(Product product) {
int rowIndex = this.products.size();
this.products.add(product);
fireTableRowsInserted(rowIndex, rowIndex);
}
public void addProducts(List<Product> productList) {
if (!productList.isEmpty()) {
int firstRow = this.products.size();
this.products.addAll(productList);
int lastRow = this.products.size() - 1;
fireTableRowsInserted(firstRow, lastRow);
}
}
public void addEmptyRow(){
products.add(new Product());
this.fireTableRowsInserted(products.size()-1, products.size()-1);
}
public void insertProduct(Product product, int rowIndex) {
this.products.add(rowIndex, product);
fireTableRowsInserted(rowIndex, rowIndex);
}
public void deleteProduct(int rowIndex) {
if (this.products.remove(this.products.get(rowIndex))) {
fireTableRowsDeleted(rowIndex, rowIndex);
}
}
public Product getProduct(int rowIndex) {
return this.products.get(rowIndex);
}
public List<Product> getProducts() {
return Collections.unmodifiableList(this.products);
}
public void clearTableModelData() {
if (!this.products.isEmpty()) {
int lastRow = products.size() - 1;
this.products.clear();
fireTableRowsDeleted(0, lastRow);
}
}
}
The third class is my is as follows:
public class NiceTablePrinting extends MainClass{
#Override
protected JTable initializeTable(TableModel model) {
return new NicePrintingJTable(model);
}
private static class NicePrintingJTable extends JTable {
public NicePrintingJTable(TableModel model) {
super(model);
}
/**
* Overridden to return a fancier printable, that wraps the default.
* Ignores the given header and footer. Renders its own header.Always
* uses the page number as the footer.
*/
#Override
public Printable getPrintable(PrintMode printMode,
MessageFormat headerFormat,
MessageFormat footerFormat) {
MessageFormat pageNumber = new MessageFormat("- {0} -");
/* Fetch the default printable */
Printable delegate = per.getPrintable(printMode,null,pageNumber);
/* Return a fancy printable that wraps the default */
return new NicePrintable(delegate);
}
}
private static class NicePrintable implements Printable {
Printable delegate;
//
BufferedImage header;
BufferedImage footer;
//
boolean imagesLoaded;
{
try{
header=ImageIO.read(getClass().getResource("images/header.PNG"));
footer=ImageIO.read(getClass().getResource("images/footer.PNG"));
imagesLoaded=true;
}
catch(IOException ex)
{
ex.printStackTrace();
}
imagesLoaded=false;
}
public NicePrintable(Printable delegate) {
this.delegate = delegate;
}
#Override
public int print(Graphicsg,PageFormatpf,intpi)throwsPrinterException
{
if(!imagesLoaded){
return delegate.print(g, pf, pi);
}
//top origin
int x=(int)pf.getImageableX();
int y=(int)pf.getImageableY();
//
int iw=(int)pf.getImageableWidth();
int ih=(int)pf.getImageableHeight();
//image header
int hh= header.getHeight();
int hw=header.getWidth();
//image footer
int fh=footer.getHeight();
int fw=footer.getWidth();
int fY=ih-fh-10;
int fX=x;
//calculating the area to print the table
int tableX=10;
int tableY=hh +10;
int tableW=iw-20;
int tableH=ih-hh-10-fh-10;
/* create a new page format representing the shrunken area to print the table into */
PageFormat format = new PageFormat() {
#Override
public double getImageableX() {return tableX;}
#Override
public double getImageableY() {return tableY;}
#Override
public double getImageableWidth() {return tableW;}
#Override
public double getImageableHeight() {return tableH;}
};
/*
* We'll use a copy of the graphics to print the table to. This protects
* us against changes that the delegate printable could make to the graphics
* object.
*/
Graphics gCopy = g.create();
/* print the table into the shrunken area */
int retVal = delegate.print(gCopy, format, pi);
/* if there's no pages left, return */
if (retVal == NO_SUCH_PAGE) {
return retVal;
}
/* dispose of the graphics copy */
gCopy.dispose();
//draw the images
g.drawImage(header, x, y, hw, hh, null);
g.drawImage(footer, fX, fY, fw, fh, null);
return Printable.PAGE_EXISTS;
}
}
}
The fourth class is as follows:
public class MainClass {
private JTable table;
JFrame frame;
JButton print;
JScrollPane sp;
ProductTableModel model;
public MainClass(){
frame= new JFrame("Test Printing");
frame.setLayout(new java.awt.BorderLayout());
frame.setVisible(true);
///create table
model=new ProductTableModel();
table=this.initializeTable(model);
model.addEmptyRow();
table.setPreferredScrollableViewportSize(newjava.awt.Dimension(300,300));
sp= new javax.swing.JScrollPane(table);
frame.add(sp);
//button
print= new JButton("Print");
frame.add(print,BorderLayout.SOUTH);
frame.pack();
print.addActionListener((ActionEvent e) -> {
try {
printTable();
} catch (PrinterException ex) {
Logger.getLogger(MainClass.class.getName()).log(Level.SEVERE, null, ex);
}
});
}
protected JTable initializeTable(TableModel model) {
return new JTable(model);
}
public void printTable() throws PrinterException {
table.print(JTable.PrintMode.NORMAL, null, null, true, null, true);
}
public static void main(String [] args){
MainClass cl= new MainClass();
}
}
I would want to set my things the way it is done in TablePrintdemo3. Now I cannot see where I have gone wrong. Please assist.
The problem is it is printing only the table -no header and footer images.

Add Mouse Listener to Table Model Class

I am developing a desktop application with in Java and with the NetBeans 8.0 IDE
there is a JTable that uses a custom table model that extends anAbstractTableModel. Is it possible to implement a mouse listener in the table model class by implementing the MouseListener interface?
I have tried to do that but looks like am stuck for now. And I do not want to use the JTable class.
Any advice. the code snippet for the table model is given below.
public class CourseTableModel extends AbstractTableModel implements TableModelListener ,
MouseListener {
private List<List<Object>> dataList = new ArrayList<>();
private String[] header = { "ID","COURSE","YEAR GRADUATED "};
private int minRowCount = 5;
public Object rawData = null;
Object[] cl = null;
public CourseTableModel()
{ super(); }
public List<List<Object>> getDataList() {
return dataList;
}
public void setDataList(List<List<Object>> dataList) {
this.dataList = dataList;
fireTableDataChanged();
fireTableStructureChanged();
}
#Override
public int getRowCount() {
return Math.max(minRowCount, dataList.size());
}
#Override
public int getColumnCount() {
return header.length;
}
public void setHeader(String[] header) {
this.header = header;
}
public String[] getHeader() {
return header;
}
#Override
public Object getValueAt(int row, int col) {
if(row < dataList.size())
{rawData = dataList.get(row).get(col);}
return rawData;
}
#Override
public void setValueAt(Object value, int row, int col) {
int x = 0;
for(List<Object> lo : dataList)
{
if(x == row)
lo.set(col, value);
}
fireTableCellUpdated(row, col);
}
#Override
public String getColumnName(int col) {
return header[col];
}
#Override
public Class<?> getColumnClass(int column)
{
for (int row = 0; row < getRowCount(); row++)
{
Object o = getValueAt(row, column);
if (o != null)
{
return o.getClass();
}
}
return Object.class;
}
#Override
public boolean isCellEditable(int row, int col) {
return col != 1;
}
#Override
public void tableChanged(TableModelEvent e) {
int row = e.getFirstRow();
int column = e.getColumn();
TableModel model = (TableModel)e.getSource();
String columnName = model.getColumnName(column);
Object data = model.getValueAt(row, column);
System.out.println(" this is cell value " + data);
}
public void fillCourseDialogue()
{ cl = new Object[dataList.get(0).size()];
int x = 0;
for (List<Object> dl : dataList) {
cl[x] = dl.get(1);
x++;
}
}
#Override
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
JTable target = (JTable)e.getSource();
int row = target.getSelectedRow();
int col = target.getSelectedColumn();
if(row > -1 && col > 0)
{
JOptionPane.showInputDialog(null, "SELECT A COURSE","COURSE",JOptionPane.PLAIN_MESSAGE ,
null,cl, cl[1]);
}
}
}
#Override
public void mousePressed(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of
generated
methods, choose Tools | Templates.
}
#Override
public void mouseReleased(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated
methods, choose Tools | Templates.
}
#Override
public void mouseEntered(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated
methods, choose Tools | Templates.
}
#Override
public void mouseExited(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated
methods, choose Tools | Templates.
}
}

I keep getting nullpointer exception for jtable getrowcount() method

I am trying to create a table that can be filtered but I keep getting a null pointer exception for the getRowCount() method in my table model class.
HomePagePanel(where my table is)
public class homepagePanel extends JPanel implements ActionListener {
private JButton uploadEmail, viewEmail, logout, delete;
private JLabel userLog;
private JLabel tableLabel;
private JScrollPane scrollPane;
private EmailTableListener emailTableListener;
//private EmailTablePanel EmailPanel;
private HomePagePanelListener homepagePanelListener;
private List<Item> dc;
private Controller controller;
private JTable table;
private EmailTableModel emailModel;
private JPopupMenu popup;
private JTextField filterText;
private JLabel filterLabel;
private TableRowSorter<EmailTableModel> sorter;
public homepagePanel() {
controller = new Controller();
userLog = new JLabel("Logged in:");
uploadEmail = new JButton("Upload");
viewEmail = new JButton("View");
delete = new JButton("Delete");
logout = new JButton("Log Out");
tableLabel = new JLabel("Emails stored");
//Email stuff
emailModel = new EmailTableModel();
sorter = new TableRowSorter<EmailTableModel>(emailModel);
table = new JTable(emailModel);
table.setRowSorter(sorter);
//
filterLabel = new JLabel("Filter Text: ", SwingConstants.TRAILING);
filterText = new JTextField(10);
filterLabel.setLabelFor(filterText);
//documenet listener
filterText.getDocument().addDocumentListener(new DocumentListener(){
#Override
public void changedUpdate(DocumentEvent e) {
// TODO Auto-generated method stub
newFilter();
}
#Override
public void insertUpdate(DocumentEvent e) {
// TODO Auto-generated method stub
newFilter();
}
#Override
public void removeUpdate(DocumentEvent e) {
// TODO Auto-generated method stub
newFilter();
}
});
// Adds the table to a scrollpane
scrollPane = new JScrollPane(table);
scrollPane
.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
scrollPane
.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_ALWAYS);
popup = new JPopupMenu();
JMenuItem removeItem = new JMenuItem("Delete row");
popup.add(removeItem);
//adds mouse listener to show
table.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e) {
int row = table.rowAtPoint(e.getPoint());
table.getSelectionModel().setSelectionInterval(row, row);
if(e.getButton() == MouseEvent.BUTTON3){
popup.show(table, e.getX(), e.getY());//shows popup
}
}
});
//removeitem actionlistener
removeItem.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
int row = table.getSelectedRow();
if(emailTableListener != null){
emailTableListener.rowDeleted(row);
emailModel.fireTableRowsDeleted(row, row);
}
}
});
// EmailPanel = new EmailTablePanel();
layoutComponents();
viewEmail.addActionListener(this);
uploadEmail.addActionListener(this);
logout.addActionListener(this);
private void newFilter(){
RowFilter<EmailTableModel, Object> rf = null;
try{
rf = RowFilter.regexFilter(filterText.getText());
}catch(java.util.regex.PatternSyntaxException e){
return;
}
sorter.setRowFilter(rf);
}
TableModel
package view;
import java.util.List;
import javax.swing.table.AbstractTableModel;
import model.Item;
public class EmailTableModel extends AbstractTableModel {
private List<Item> dc;
private String[] colNames = {"ID", "To", "From", "Subject", "Topic", "Message Content", "Comments", "Attachments"};
public EmailTableModel(){
//System.out.println(dc.size());
}
public String getColumnName(int column) {
// TODO Auto-generated method stub
return colNames[column];
}
public void setData(List<Item> dc){
this.dc = dc;
}
#Override
public int getColumnCount() {
// TODO Auto-generated method stub
return 8;
}
#Override
public int getRowCount() {
// TODO Auto-generated method stub
return dc.size();
}
#Override
public Object getValueAt(int row, int column) {
Item item = dc.get(row);
switch(column){
case 0:
return item.getId();
case 1:
return item.getTo();
case 2:
return item.getFrom();
case 3:
return item.getSubject();
case 4:
return item.getTopic();
case 5:
return item.getMessageContent();
case 6:
return item.getComments();
case 7:
return item.getAttachments();
}
return null;
}
public Class getColumnClass(int column) {
Class returnValue;
// Verifying that the column exists(index > 0 && index < number of
// columns
if ((column >= 0) && (column < getColumnCount())) {
returnValue = getValueAt(0, column).getClass();
} else {
// Returns the class for the item in the column
returnValue = Object.class;
}
return returnValue;
};
}
database class(retriving data for jtable)
public void loadItems() throws SQLException {
//connects to the database
getConnected();
Items.clear();//clears the linked list
String sql = "Select Id, Reciever, Sender, Subject, topic, Email_Content, Comments, Attachments from item order by Id";//querly for select statement
Statement selectStatement = con.createStatement();
ResultSet results = selectStatement.executeQuery(sql);
while (results.next()) {
int id = results.getInt("Id");
String To = results.getString("Reciever");
String From = results.getString("Sender");
String Subject = results.getString("Subject");
String topic = results.getString("topic");
String Email_Content = results.getString("Email_Content");
String Comments = results.getString("Comments");
String Attachments = results.getString("Attachments");
Item item = new Item(id, To, From, Subject, topic, Email_Content,
Comments, Attachments);
Items.add(item);//add item to linked list
}
}
mainframe(where I set the data
loadItems(); //method used to load the data from the database
HomepagePanel.setData(controller.getItems());//sets data
Here:
public class HomePagePanel { // note code conventios!
...
public HomePagePanel() {
...
emailModel = new EmailTableModel();
sorter = new TableRowSorter<EmailTableModel>(emailModel);
table = new JTable(emailModel);
...
}
}
You don't call emailModel.setData() right before creating the table. It means your table model's data never is initialized and dc still being null at this point. Consequently when getRowCount() method is called during JTable creation it throws the NPE you're facing.
IMHO you should consider remove setData() method and add the items list to the EmailTableModel constructor instead, and better organize your code to avoid this kind of situation:
Do database call and get items list
Create a new table model
Create new JTable
Edit
"Should i just call fireTableDataChanged when I insert or delete an
item?"
No, you just need to provide methods to add/delete items to your table model and then notify TableModelListeners about such events. For instance:
public class EmailTableModel extends AbstractTableModel {
...
public void addRow(Item item) {
int rowIndex = dc.size();
dc.add(item);
fireTableRowsInserted(rowIndex, rowIndex);
}
...
public void deleteRow(Item item) {
int rowIndex = dc.indexOf(item);
if(rowIndex > -1) {
dc.remove(item);
fireTableRowsDeleted(rowIndex, rowIndex);
}
}
...
}
See AbstractTableModel API:
fireTableRowsInserted(int firstRow,int
lastRow)
fireTableRowsDeleted(int firstRow, int
lastRow)

jtable refresh in setModel

I'm following this example code to create my own tableModel class to display data from a db using cachedRowSet, and use rowSetEvent to refresh the table when insert a row and delete a row to the cachedRowSet.
https://github.com/abissell/jdbctutorial/blob/master/src/com/oracle/tutorial/jdbc/CoffeesTableModel.java
public void rowChanged(RowSetEvent event) {
try {
tm.rs.moveToCurrentRow();
tm = new MyTableModel(tm.rs); // to get right row nums
table.setModel(tm);
} catch (SQLException er) {
er.printStackTrace();
}
}
public class MyTableModel extends AbstractTableModel {
CachedRowSet rs;
ResultSetMetaData meta;
int cols, rows;
public MyTableModel(CachedRowSet r) {
rs = r;
try {
meta = rs.getMetaData();
cols = meta.getColumnCount();
rs.beforeFirst();
rows = 0;
while (rs.next()) {
rows++;
}
rs.beforeFirst();
} catch(SQLException e) {
e.printStackTrace();
}
}
public void insert(String[] info) {
try {
rs.moveToInsertRow();
for(int i = 0;i < cols;i++) {
rs.updateString(i+1, info[i]);
}
rs.insertRow();
rs.moveToCurrentRow();
} catch(SQLException e) {
e.printStackTrace();
}
}
public void delete(int id) {
try {
rs.beforeFirst();
while(rs.next()) {
if(Integer.parseInt(rs.getString(1))==id) {
rs.deleteRow();
break;
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
#Override
public int getRowCount() {
return rows;
}
#Override
public int getColumnCount() {
return cols;
}
#Override
public String getColumnName(int col) {
try {
return meta.getColumnLabel(col + 1);
} catch (SQLException e) {
return e.toString();
}
}
#Override
public Class<?> getColumnClass(int columnIndex) {
return String.class;
}
#Override
public boolean isCellEditable(int rowIndex, int columnIndex) {
return false;
}
#Override
public Object getValueAt(int rowIndex, int columnIndex) {
try {
if (!rs.absolute(rowIndex + 1)) {
return null;
}
rs.absolute(rowIndex + 1);
Object o = rs.getObject(columnIndex + 1);
if (o == null) {
return null;
} else {
return o.toString();
}
} catch (SQLException e) {
e.printStackTrace();
return e.toString();
}
}
#Override
public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
}
#Override
public void addTableModelListener(TableModelListener l) {
}
#Override
public void removeTableModelListener(TableModelListener l) {
}
}
con = DriverManager.getConnection(url);
st = con.prepareStatement("SELECT id,name,sex,age,cell FROM PATIENTS");
rs = st.executeQuery();
crs = new CachedRowSetImpl();
crs.setType(ResultSet.TYPE_SCROLL_SENSITIVE);
crs.setConcurrency(ResultSet.CONCUR_UPDATABLE);
crs.populate(rs);
tm is the tableModel.
The table will refresh immediately after a row deleted from the cachedRowSet, but when i insert a new row into cachedRowSet, then the table can't show the newly added row immediately. And i checked the rowChanged() been called and the row inserted inside the db.
Even tried to refetch the table data each time or repaint() still not working. I couldn't figure out why.
Maybe cause swing process racing then it can't refresh immediately? I just opened another JFrame to fill out the data and then insert.
Also, what if i use the resultSet directly inside the model? Will the table automatically updated when you insert a row in the db if i didn't close the connection. Or it's just used to get the initial data and you have to run query again to refresh.
Thank you
=================update==================
I tried to change the table model to use ArrayList to store and update db results, then the insert will be update the table immediately. Maybe cause cachedRowSet update slower?
Confused, don't know why.

Categories