jTable right-click popup menu - java

I have a SQL database and I am working on a program that will allow me to add/delete/modify records. I already managed to add records I am working on editing/deleting them.
I want to display the existing records in a table so I am using jTable. I found some code online and modified it to pull the records and display them in a jtable but i dont know how to code the rightclick and display a popup menu.
In that popup menu I want to display options such as delete record and modify record.
This is the code I am using the make the jTable and display the data:
private void menuDeleteAuthorActionPerformed(java.awt.event.ActionEvent evt) {
TableFromDatabase deleteAuthor = new TableFromDatabase();
deleteAuthor.pack();
deleteAuthor.setVisible(true);
Vector columnNames = new Vector();
Vector data = new Vector();
try
{
Connection connection = DriverManager.getConnection( url, user, password );
// Read data from a table
String sql = "SELECT * FROM Authors";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery( sql );
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
// Get column names
for (int i = 1; i <= columns; i++)
{
columnNames.addElement( md.getColumnName(i) );
}
// Get row data
while (rs.next())
{
Vector row = new Vector(columns);
for (int i = 1; i <= columns; i++)
{
row.addElement( rs.getObject(i) );
}
data.addElement( row );
}
rs.close();
stmt.close();
connection.close();
}
catch(Exception e)
{
System.out.println( e );
}
// Create table with database data
JTable table = new JTable(data, columnNames)
{
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;
}
};
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
JPanel buttonPanel = new JPanel();
getContentPane().add( buttonPanel, BorderLayout.SOUTH );
}
I am new to Java so please be kind in your responses. Thank you all in advance for any assistance!

Here is an example on how to do that. The easiest way to achieve this, is to set a JPopupMenu on the JTable directly.
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.Vector;
import javax.swing.JFrame;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
public class TestTableRightClick {
protected void initUI() {
final JFrame frame = new JFrame(TestTableRightClick.class.getSimpleName());
Vector<String> columns = new Vector<String>(Arrays.asList("Name", "Age"));
Vector<Vector<String>> data = new Vector<Vector<String>>();
for (int i = 0; i < 50; i++) {
Vector<String> row = new Vector<String>();
for (int j = 0; j < columns.size(); j++) {
row.add("Cell " + (i + 1) + "," + (j + 1));
}
data.add(row);
}
final JTable table = new JTable(data, columns);
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem deleteItem = new JMenuItem("Delete");
deleteItem.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(frame, "Right-click performed on table and choose DELETE");
}
});
popupMenu.add(deleteItem);
table.setComponentPopupMenu(popupMenu);
frame.add(new JScrollPane(table), BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new TestTableRightClick().initUI();
}
});
}
}
In case you want to automatically select the row where the right-click was made, add the following snippet:
popupMenu.addPopupMenuListener(new PopupMenuListener() {
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
if (rowAtPoint > -1) {
table.setRowSelectionInterval(rowAtPoint, rowAtPoint);
}
}
});
}
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
#Override
public void popupMenuCanceled(PopupMenuEvent e) {
// TODO Auto-generated method stub
}
});

A problem with a JTable is that the right click does not change the row selection. So you if have an Action that works on a specific row you need to left click the row first before right clicking to have the popup menu displayed.
If you want the row to be selected where your right click then you can use code like the following:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TableRightClick extends JFrame implements ActionListener
{
JPopupMenu popup;
public TableRightClick()
{
popup = new JPopupMenu();
popup.add( new JMenuItem("Do Something1") );
popup.add( new JMenuItem("Do Something2") );
popup.add( new JMenuItem("Do Something3") );
JMenuItem menuItem = new JMenuItem("ActionPerformed");
menuItem.addActionListener( this );
popup.add( menuItem );
JTable table = new JTable(50, 5);
table.addMouseListener( new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
System.out.println("pressed");
}
public void mouseReleased(MouseEvent e)
{
if (e.isPopupTrigger())
{
JTable source = (JTable)e.getSource();
int row = source.rowAtPoint( e.getPoint() );
int column = source.columnAtPoint( e.getPoint() );
if (! source.isRowSelected(row))
source.changeSelection(row, column, false, false);
popup.show(e.getComponent(), e.getX(), e.getY());
}
}
});
table.setPreferredScrollableViewportSize(table.getPreferredSize());
getContentPane().add( new JScrollPane(table) );
}
public void actionPerformed(ActionEvent e)
{
Component c = (Component)e.getSource();
JPopupMenu popup = (JPopupMenu)c.getParent();
JTable table = (JTable)popup.getInvoker();
System.out.println(table.getSelectedRow() + " : " + table.getSelectedColumn());
}
public static void main(String[] args)
{
TableRightClick frame = new TableRightClick();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
}

Unfortunately, none of these solutions worked for me on both Macs and PC's. Not sure why. But this worked on both:
#Override
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {
int row = table.rowAtPoint(SwingUtilities.convertPoint(popup, 0, 0, table));
if (row > -1)
table.setRowSelectionInterval(row, row);
}
The main problem with my solution is that it doesn't show that the row is selected until after the user chooses one of the menu options.

Another issue is that context menus are dynamic, your solution does not deal with changing the menu depending on the clicked row
popupMenu.addPopupMenuListener(new PopupMenuListener()
{
#Override
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
int rowAtPoint = table.rowAtPoint(SwingUtilities.convertPoint(popupMenu, new Point(0, 0), table));
generateTablePopupMenu(rowAtPoint); // here
SwingUtilities.invokeLater(new Runnable()
...

Related

Java: How to use an object from one mouseListener to another class?

I need to use the object 'urObjectInCell' in mouseListener of 'table' to another class BtnDelete1.
Here's my Mouse Listener Code:
JTable table;
public FirstSwingApp(){
super();
table = new JTable(model);
table.addMouseListener(new MouseAdapter() {
public void mouseClicked(final MouseEvent e) {
if (e.getClickCount() == 1) {
final JTable target = (JTable)e.getSource();
final int row = target.getSelectedRow();
final int column = 1;
// Cast to ur Object type
urObjctInCell = target.getValueAt(row, column);
}
}
});
friendNo = urObjctInCell.toString();
I tried storing the object in friendNo string which has been declared earlier. But I don't think the friendNo is taking the value of the object.
Here's my Class BtnDelete1 code:
public class BtnDelete1 implements ActionListener {
public void actionPerformed(ActionEvent e) {
String fnumber = friendNo;
CallableStatement dstmt = null;
CallableStatement cstmt = null;
ResultSet rs;
try {
conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/Contact_Manager?user=root");
String SQL = "{call delete_contact (?)}";
String disQuery = "select * from FRIEND";
dstmt = conn.prepareCall(disQuery);
cstmt = conn.prepareCall(SQL);
cstmt.setString(1, fnumber);
cstmt.executeQuery();
rs = dstmt.executeQuery();
ResultSetMetaData metaData = rs.getMetaData();
// names of columns
Vector<String> columnNames = new Vector<String>();
int columnCount = metaData.getColumnCount();
for (int column = 1; column <= columnCount; column++) {
columnNames.add(metaData.getColumnName(column));
}
// data of the table
Vector<Vector<Object>> data = new Vector<Vector<Object>>();
while (rs.next()) {
Vector<Object> vector = new Vector<Object>();
for (int columnIndex = 1; columnIndex <= columnCount; columnIndex++) {
vector.add(rs.getObject(columnIndex));
}
data.add(vector);
}
// It creates and displays the table
model.setDataVector(data, columnNames);
// Closes the Connection
dstmt.close();
System.out.println("Success!!");
} catch (SQLException ex) {
System.out.println("Error in connection: " + ex.getMessage());
}
}
}
The value of urObjectInCell object obtained from mouseListener is to be used to delete a row in the Jtable 'table'.
I think that you may be thinking this out wrong. Rather than trying to mix a MouseListener and an ActionListener in some unholy matrimony, why not instead simply get the selected cell from the JTable when the ActionListener is notified?
You could do this by giving the JTable-holding class a method for extracting a reference to the selected JTable cell, give the ActionListener a reference to this class, and have the ActionListener call this method when it has been notified and its callback method called.
For example say you have a JTable held in a GUI called NoMouseListenerNeeded:
import java.awt.BorderLayout;
import javax.swing.*;
import javax.swing.table.DefaultTableModel;
#SuppressWarnings("serial")
public class NoMouseListenerNeeded extends JPanel {
private static final Integer[][] DATA = { { 1, 2, 3 }, { 4, 5, 6 }, { 7, 8, 9 } };
private static final String[] COLS = { "A", "B", "C" };
private DefaultTableModel tblModel = new DefaultTableModel(DATA, COLS);
private JTable table = new JTable(tblModel);
public NoMouseListenerNeeded() {
JPanel btnPanel = new JPanel();
btnPanel.add(new JButton(new MyButtonListener(this)));
setLayout(new BorderLayout());
add(new JScrollPane(table));
add(btnPanel, BorderLayout.PAGE_END);
}
// get data held by selected cell in JTable
// returns null if no cell selected
public Object getSelectedCell() {
int col = table.getSelectedColumn();
int row = table.getSelectedRow();
if (col < 0 || row < 0) {
return null; // no selection made, return null
} else {
return table.getValueAt(row, col);
}
}
private static void createAndShowGui() {
NoMouseListenerNeeded mainPanel = new NoMouseListenerNeeded();
JFrame frame = new JFrame("NoMouseListenerNeeded");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}
You could use an ActionListener (or AbstractAction) to get the selected cell by passing the GUI into the listener, and calling the GUI's method that returns the selected data:
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.AbstractAction;
import javax.swing.JOptionPane;
#SuppressWarnings("serial")
public class MyButtonListener extends AbstractAction {
private NoMouseListenerNeeded mainGui;
public MyButtonListener(NoMouseListenerNeeded mainGui) {
super("Press Me");
putValue(MNEMONIC_KEY, KeyEvent.VK_P);
this.mainGui = mainGui;
}
#Override
public void actionPerformed(ActionEvent e) {
Object cell = mainGui.getSelectedCell();
if (cell != null) {
String message = "Selection is: " + cell;
JOptionPane.showMessageDialog(mainGui, message, "Selection", JOptionPane.PLAIN_MESSAGE);
}
}
}

How to get the value of a JTable cell with a right mouse click

I have a JTable in my Java Swing application and everything works fine in general. I have added a MouseListener on my JTable, so whenever I try right clicking on a row in the table, I can capture the event and run a method. However, what I'd like to do is to
Select the cell
Get it's value
Then call the method.
To do this, I must currently left click on the row, then also do a right click on it. Is it possible to select the row/cell right away with only a single click of the right mouse button?
Here is my code so far:
public class MyMouseAdapterTableArticoli extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
JTable t = (JTable)me.getSource();
JMenuItem menuItem;
rowPopUp = t.rowAtPoint(me.getPoint());
if ((me.getClickCount() == 2) && (me.getButton() == MouseEvent.BUTTON1)) {
pulisciTableArtRappre();
if((listaMagazzino != null) && (listaMagazzino.size() > 0)) {
pulisciTableArtMagazzino();
}
popolaCampi(rowPopUp);
} else if (me.getButton() == MouseEvent.BUTTON3) {
JPopupMenu popup = new JPopupMenu();
menuItem = new JMenuItem("Mostra Prezzi di Acquisto");
menuItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
mostraPrezziAcquisto(rowPopUp);
}//fine metodoVoid
});//fine actionlistener
popup.add(menuItem);
MouseListener popupListener = new PopupListener(popup);
table.addMouseListener(popupListener);
}//fine else e if
}
public void mousePressed(MouseEvent e) {
JTable source = (JTable)e.getSource();
int row = source.rowAtPoint(e.getPoint());
int column = source.columnAtPoint(e.getPoint());
if (!source.isRowSelected(row)) {
source.changeSelection(row, column, false, false);
}
}
table.addMouseListener( new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
JTable source = (JTable)e.getSource();
int row = source.rowAtPoint( e.getPoint() );
int column = source.columnAtPoint( e.getPoint() );
if (! source.isRowSelected(row))
source.changeSelection(row, column, false, false);
}
});
Edit:
Create a simple example when learning a new concept. For example:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class SSCCE extends JPanel
{
public SSCCE()
{
JTable table = new JTable(15, 5);
add( new JScrollPane(table) );
table.addMouseListener( new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
JTable source = (JTable)e.getSource();
int row = source.rowAtPoint( e.getPoint() );
int column = source.columnAtPoint( e.getPoint() );
if (! source.isRowSelected(row))
source.changeSelection(row, column, false, false);
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame("SSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new SSCCE(), BorderLayout.NORTH);
frame.setLocationByPlatform( true );
frame.pack();
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowGUI();
}
});
}
}

how to get the value at specific column and specific row in jtable by a mouse clicked

hey here i stuck in my program.Actually i have a jtable and i want to select the value of specific row and specific coloumn every time when a mouse is clicked over the row of jtable...
here is my class which i am using:
import java.awt.event.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.sql.*;
import java.util.*;
import javax.swing.*;
import javax.swing.table.*;
import javax.swing.JFrame;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
public class jtable extends JFrame implements MouseListener
{
PdfViewer3 pdfViewer3;
String value;
JTable table;
//Vector dataVector;
public jtable() throws ClassNotFoundException
{
ArrayList columnNames = new ArrayList();
ArrayList data = new ArrayList();
// Connect to an MySQL Database, run query, get result set
String url = "jdbc:mysql://localhost:3306/search_imgr_data";
String userid = "root";
String password = "root";
String sql = "SELECT * FROM mission_db limit 70060,5";
// Java SE 7 has try-with-resources
// This will ensure that the sql objects are closed when the program
// is finished with them
try {
Class.forName("com.mysql.jdbc.Driver");
Connection connection = DriverManager.getConnection( url, userid, password );
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery( sql );
ResultSetMetaData md = rs.getMetaData();
int columns = md.getColumnCount();
// Get column names
for (int i = 1; i <= columns; i++)
{
columnNames.add( md.getColumnName(i) );
}
// Get row data
while (rs.next())
{
ArrayList row = new ArrayList(columns);
for (int i = 1; i <= columns; i++)
{
row.add( rs.getObject(i) );
}
data.add( row );
}
}
catch (SQLException e)
{
System.out.println( e.getMessage() );
}
// Create Vectors and copy over elements from ArrayLists to them
// Vector is deprecated but I am using them in this example to keep
// things simple - the best practice would be to create a custom defined
// class which inherits from the AbstractTableModel class
Vector columnNamesVector = new Vector();
Vector dataVector = new Vector();
for (int i = 0; i < data.size(); i++)
{
ArrayList subArray = (ArrayList)data.get(i);
Vector subVector = new Vector();
for (int j = 0; j < subArray.size(); j++)
{
subVector.add(subArray.get(j));
}
dataVector.add(subVector);
}
for (int i = 0; i < columnNames.size(); i++ )
columnNamesVector.add(columnNames.get(i));
// Create table with database data
table = new JTable(dataVector, columnNamesVector)
{
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;
}
public boolean isCellEditable(int rowIndex, int colIndex) {
return false;
}
};
table.addMouseListener(new MouseAdapter(){
public void MouseClicked(MouseEvent e) {
System.out.println("IN listener");
table.setRowSelectionAllowed(true);
table.setColumnSelectionAllowed(true);
if (e.getClickCount() != 0)
{
JTable target = (JTable)e.getSource();
int row = target.getSelectedRow();
int column = 1;
value = (String)target.getValueAt(row, column);
//value= ((Vector)rowData.elementAt(row)).elementAt(column);
Thread runner = new Thread(){
public void run(){
//pdfViewer3 = new PdfViewer3();
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
pdfViewer3.setVisible(true);}});
pdfViewer3.initComponents1(value);
}
};runner.start();
}
}
});
JScrollPane scrollPane = new JScrollPane( table );
getContentPane().add( scrollPane );
JPanel buttonPanel = new JPanel();
getContentPane().add( buttonPanel, BorderLayout.SOUTH );
}
public static void main(String[] args) throws ClassNotFoundException
{
jtable frame = new jtable();
frame.setDefaultCloseOperation( EXIT_ON_CLOSE );
frame.pack();
frame.setVisible(true);
}
public void mousePressed(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseReleased(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseEntered(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseExited(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
public void mouseClicked(MouseEvent e) {
throw new UnsupportedOperationException("Not supported yet.");
}
}
read Oracle tutorial How to use Tables, becase there are a few mistakes
MouseEvents are very good described in part Specifying Tool Tips for Cells, incl working code example
Why would you read the data from the database into an ArrayList and then copy the data to a Vector? Just load the data directly into a Vector.
table.setRowSelectionAllowed(true);
table.setColumnSelectionAllowed(true);
The above code does not look correct. I would get rid of it. At the very least is should NOT be in the MouseListener. If this really is the behaviour you want, then those statements should be executed when you create the table, otherwise I would guess that when you change the selection properties AFTER you click on a cell, then you would lose the last selection values.
public void MouseClicked(MouseEvent e)
Or maybe the problem is simple that you use "M" on the mouseClicked method. It should be "m". You should use the #Override annotation when overriding methods to make sure you don't make typing mistakes.
#Override
public void mouseClicked(MouseEvent e)

Issue after filtering JTable

I have an issue with a program I am working on. To briefly explain, I have a JTable with multiple columns and rows. Particular columns have editable fields when upon changing the value other column values change according to the inputted data. Everything works well however when I've added a filter option to the JTable, changes made to an editable column won't change the values of other columns as intended after applying the filter. I've attached a couple of images to show the problem.
The first image shows the unfiltered table working correctly. Changing a Discount column value will reduce the corresponding price stored in the GPL column by the percent the inputted discount and displayed in the corresponding row in the SP column. Changing a Quantity column value will multiply the corresponding SP column price with the inputted quantity and displayed in the corresponding row in the Total column.
The second image shows the filtered table not working as intended. Changing a value in either Discount or Quantity columns will not change the intended columns.
I've added the SSCCE code below which contains 2 classes. First is the table itself and the second is the listener for the table.
EDIT I've changed the code of the class according to camickr's answer and now fully works.
TableCellChange class
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.math.BigDecimal;
import java.math.MathContext;
import java.text.DecimalFormat;
import java.util.Locale;
import javax.swing.AbstractAction;
import javax.swing.Action;
import javax.swing.DefaultCellEditor;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.RowFilter;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
public final class TableCellChange extends JPanel {
private static JFrame frameTableCellChange;
private JPanel panelTable, panelButtons;
private JButton buttonResetDiscounts, buttonResetQuantities, buttonExit;
private JTextField textFilterBox, quantityField, discountField;
private JLabel labelFilter;
private DefaultTableModel tableModel;
private JTable table;
private TableRowSorter<DefaultTableModel> sorter;
private TableColumn columnDiscount, columnTotal, columnQuantity;
private TableCellListener tableCellListener;
private String checkForNull;
private DecimalFormat decimalFormatUS;
private Locale localeUSFormat;
private BigDecimal valueDiscount, valueGPL, resultDiscount, resultSP, resultTotal,
backupDiscount = new BigDecimal("0");
private int selectedColumnIndex, selectedRowIndex, valueQuantity, backupQuantity = 1;
public TableCellChange() {
super();
panelTable = new JPanel();
panelButtons = new JPanel();
setLayout(new BorderLayout());
createTable();
createButtons();
add(panelTable, BorderLayout.NORTH);
add(panelButtons, BorderLayout.CENTER);
// Always focus on the JTextField when opening the window
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
textFilterBox.requestFocusInWindow();
}
});
} // -> TableCellChange()
// Create the buttons for the query result window
public void createButtons() {
GridBagLayout gridbag = new GridBagLayout();
GridBagConstraints gridcons = new GridBagConstraints();
gridcons.fill = GridBagConstraints.HORIZONTAL;
panelButtons.setLayout(gridbag);
labelFilter = new JLabel("Quick search:");
gridcons.insets = new Insets(5,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 0;
gridcons.gridwidth = 2;
gridbag.setConstraints(labelFilter, gridcons);
labelFilter.setHorizontalAlignment(JLabel.CENTER);
panelButtons.add(labelFilter);
// Create text field for filtering
textFilterBox = new JTextField();
gridcons.insets = new Insets(5,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 1;
gridcons.gridwidth = 2;
gridbag.setConstraints(textFilterBox, gridcons);
textFilterBox.getDocument().addDocumentListener(
new DocumentListener() {
#Override
public void changedUpdate(DocumentEvent e) {
tableFilter();
}
#Override
public void insertUpdate(DocumentEvent e) {
tableFilter();
}
#Override
public void removeUpdate(DocumentEvent e) {
tableFilter();
}
}); // -> DocumentListener()
panelButtons.add(textFilterBox);
// Create the button to reset the discount column to 0%
buttonResetDiscounts = new JButton("Reset all discounts");
buttonResetDiscounts.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
BigDecimal valueGPL, valueTotal;
int valueQuantity;
for (int i = 0; i < table.getModel().getRowCount(); i++) {
valueGPL = new BigDecimal( table.getModel().
getValueAt(i, 2).toString().replaceAll("[$,]", "") );
table.getModel().setValueAt("0%", i, 3);
table.getModel().setValueAt(DecimalFormat
.getCurrencyInstance(localeUSFormat).format(valueGPL), i, 4);
valueQuantity = Integer.parseInt( table.getModel().
getValueAt(i, 5).toString() );
valueTotal = valueGPL.multiply(new BigDecimal(valueQuantity),
new MathContext(BigDecimal.ROUND_HALF_EVEN));
table.getModel().setValueAt(DecimalFormat
.getCurrencyInstance(localeUSFormat).format(valueTotal), i, 6);
}
}
});
gridcons.insets = new Insets(10,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 3;
gridcons.gridwidth = 1;
gridbag.setConstraints(buttonResetDiscounts, gridcons);
panelButtons.add(buttonResetDiscounts);
// Create button to reset the quantity column to 1
buttonResetQuantities = new JButton("Reset all quantities");
buttonResetQuantities.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
BigDecimal valueSP;
for (int i = 0; i < table.getModel().getRowCount(); i++) {
valueSP = new BigDecimal( table.getModel().
getValueAt(i, 4).toString().replaceAll("[$,]", "") );
table.getModel().setValueAt("1", i, 5);
table.getModel().setValueAt(DecimalFormat.
getCurrencyInstance(localeUSFormat).format(valueSP), i, 6);
}
}
});
gridcons.insets = new Insets(10,0,0,0);
gridcons.gridx = 1;
gridcons.gridy = 3;
gridcons.gridwidth = 1;
gridbag.setConstraints(buttonResetQuantities, gridcons);
panelButtons.add(buttonResetQuantities);
// Create button for closing the window and releasing resources
buttonExit = new JButton("Exit");
buttonExit.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
gridcons.insets = new Insets(5,0,0,0);
gridcons.gridx = 0;
gridcons.gridy = 5;
gridcons.gridwidth = 2;
gridbag.setConstraints(buttonExit, gridcons);
panelButtons.add(buttonExit);
} // -> createButtons()
// Filters the JTable based on user input
private void tableFilter() {
RowFilter<DefaultTableModel, Object> tableRowFilter;// = null;
// If current expression doesn't parse, don't update
try {
tableRowFilter = RowFilter.regexFilter("(?i)" + textFilterBox.
getText(), 0, 1, 2);
} catch (java.util.regex.PatternSyntaxException e) {
return;
}
sorter.setRowFilter(tableRowFilter);
} // -> tableFilter
// Method that creates the JTable
public void createTable() {
// Create listener for selecting all text when a text field gains focus
KeyboardFocusManager.getCurrentKeyboardFocusManager()
.addPropertyChangeListener("permanentFocusOwner", new PropertyChangeListener() {
#Override
public void propertyChange(final PropertyChangeEvent e) {
if (e.getNewValue() instanceof JTextField) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JTextField textField = (JTextField)e.getNewValue();
textField.selectAll();
}
});
}
}
});
String[] columnNames = {"Model", "Description", "GPL", "Discount", "SP",
"Quantity", "Total"};
Object[][] data = {
{"MR16", "desc1", "$649.00", "0%", "$649.00", new Integer(1), "$649.00"},
{"MR24", "desc2", "$1,199.00", "0%", "$1,199.00", new Integer(1), "1,199.00"},
{"MR62", "desc3", "$699.00", "0%", "$699.00", new Integer(1), "$699.00"},
{"MR66", "desc4", "$1,299.00", "0%", "$1,299.00", new Integer(1), "$1,299.00"},
{"MX80", "desc5", "$1,995.00", "0%", "$1,995.00", new Integer(1), "$1,995.00"},
{"MX90", "desc6", "$3,995.00", "0%", "$3,995.00", new Integer(1), "$3,995.00"},
{"MX400", "desc7", "$15,995.00", "0%", "$15,995.00", new Integer(1), "$15,995.00"},
{"MX600", "desc8", "$31,995.00", "0%", "$31,995.00", new Integer(1), "$31,995.00"},
{"MS22-HW", "desc9", "$1,999.00", "0%", "$1,999.00", new Integer(1), "$1,999.00"},
{"MS42-HW", "desc10", "$3,499.00", "0%", "$3,499.00", new Integer(1), "$3,499.00"},
};
// Create the TableModel and populate it
tableModel = new DefaultTableModel(data, columnNames) {
Class [] classes = {String.class, String.class, String.class,
String.class, String.class, int.class, String.class, Boolean.class};
#Override
public Class getColumnClass(int column) {
return classes[column];
}
};
// Create a JTable and populate it with the content of the TableModel
table = new JTable(tableModel) {
#Override
public boolean isCellEditable(int row, int column) {
if (column == 0 || column == 1 || column == 2 || column == 4 ||
column == 6) {
return false;
}
return true;
}
};
// This sorter is used for text filtering
sorter = new TableRowSorter<>(tableModel);
for (int column = 3; column < 6; column++) {
sorter.setSortable(column, false);
}
table.setRowSorter(sorter);
columnTotal= table.getColumnModel().getColumn(6);
columnTotal.setPreferredWidth(100);
// Filter user input in the quantity text field to only allow digits
discountField =new JTextField();
discountField.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e)
{
if(!Character.isDigit(e.getKeyChar()) && e.getKeyChar() !=KeyEvent.VK_BACK_SPACE) {
discountField.setEditable(false);
discountField.setBackground(Color.WHITE);
} else {
discountField.setEditable(true);
}
}
});
// Set the text field to the cells of the quantity column
columnQuantity = table.getColumnModel().getColumn(5);
columnQuantity.setCellEditor(new DefaultCellEditor (discountField));
// Filter user input in the discount text field to only allow digits
quantityField =new JTextField();
quantityField.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(KeyEvent e)
{
if(!Character.isDigit(e.getKeyChar()) && e.getKeyChar() !=KeyEvent.VK_BACK_SPACE) {
quantityField.setEditable(false);
quantityField.setBackground(Color.WHITE);
//JOptionPane.showMessageDialog(null,"Only digit input is allowed!");
} else {
quantityField.setEditable(true);
}
}
});
// Set the text field to the cells of the quantity column
columnDiscount = table.getColumnModel().getColumn(3);
columnDiscount.setCellEditor(new DefaultCellEditor(discountField));
// Create an US number format
localeUSFormat = Locale.US;
decimalFormatUS = (DecimalFormat) DecimalFormat.getInstance(localeUSFormat);
decimalFormatUS.setMaximumFractionDigits(2);
// Create abstract action which listens for changes made in the JTable
Action actionTableListener = new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
TableCellListener tcl = (TableCellListener)e.getSource();
// Get the current row and column index of the table
selectedRowIndex = tcl.getRow();
selectedColumnIndex = tcl.getColumn();
TableModel model = tcl.getTable().getModel();
// Have a string variable check for null cell value
checkForNull = model.getValueAt(selectedRowIndex,selectedColumnIndex).toString();
// Change the discounted and total price values
if (selectedColumnIndex == 3) {
// Check if the discount value is null and replace with
// last used value if true
if (checkForNull.equals("")) {
model.setValueAt(backupDiscount + "%",selectedRowIndex, selectedColumnIndex);
return;
}
// Get the discount value and replace the '%' with nothing
valueDiscount = new BigDecimal(( model
.getValueAt(selectedRowIndex,selectedColumnIndex)
.toString().replaceAll("[%]","") ));
//
model.setValueAt(valueDiscount + "%",selectedRowIndex, selectedColumnIndex);
// Check if the discount value is greater than 100
if ( (valueDiscount.compareTo(new BigDecimal(100)) == 1 ) ) {
model.setValueAt(backupDiscount + "%",selectedRowIndex, selectedColumnIndex);
JOptionPane.showMessageDialog(null,"Discount cannot be more than 100%.");
} else {
backupDiscount = valueDiscount;
valueDiscount = valueDiscount.divide(new BigDecimal(100)
, 2, BigDecimal.ROUND_HALF_EVEN);
// Calculate SP and Total values based on the discount input
valueGPL = new BigDecimal( ( model
.getValueAt(selectedRowIndex,selectedColumnIndex - 1)
.toString().replaceAll("[$,]","") ) );
// Get the quantity value
valueQuantity = Integer.parseInt( ( model
.getValueAt(selectedRowIndex,selectedColumnIndex + 2)
.toString() ) );
// Calculate the new discount value
resultDiscount = valueGPL.multiply(valueDiscount,
new MathContext(BigDecimal.ROUND_HALF_EVEN));
// Calculate the new SP value
resultSP = valueGPL.subtract(resultDiscount,
new MathContext(BigDecimal.ROUND_HALF_EVEN));
// Calculate the new result value
resultTotal = resultSP.multiply(new BigDecimal(valueQuantity),
new MathContext(BigDecimal.ROUND_HALF_EVEN));
// Display the new SP value
model.setValueAt(DecimalFormat.getCurrencyInstance(localeUSFormat)
.format(resultSP),selectedRowIndex, selectedColumnIndex + 1);
// Display the new Total value
model.setValueAt(DecimalFormat.getCurrencyInstance(localeUSFormat)
.format(resultTotal),selectedRowIndex, selectedColumnIndex + 3);
}
}
// Change the total price values based on the quantity column
if (selectedColumnIndex == 5) {
// Check if the quantity value is null and replace with
// last used value if true
if (checkForNull.equals("")) {
model.setValueAt(backupQuantity,selectedRowIndex, selectedColumnIndex);
return;
}
// Change total price value based on the quantity column
resultSP = new BigDecimal( ( model.
getValueAt(selectedRowIndex,
selectedColumnIndex - 1).toString().replaceAll("[$,]","") ) );
valueQuantity = Integer.parseInt( ( model.getValueAt(selectedRowIndex,
selectedColumnIndex).toString() ) );
// Check if the value quantity is over a certain limit
if (valueQuantity <= 0 || valueQuantity >= 999999) {
model.setValueAt(backupQuantity,selectedRowIndex, selectedColumnIndex);
JOptionPane.showMessageDialog(null,"Quantity value is too high or invalid!");
} else {
// If the value is under the limit: backup the new quantity
// value, calculate the new total value and display it
backupQuantity = valueQuantity;
resultTotal = resultSP.multiply(new BigDecimal(valueQuantity),
new MathContext(BigDecimal.ROUND_HALF_EVEN));
model.setValueAt(DecimalFormat.getCurrencyInstance(localeUSFormat)
.format(resultTotal), selectedRowIndex, selectedColumnIndex + 1);
}
}
}
}; // -> AbstractAction()
tableCellListener = new TableCellListener(table, actionTableListener);
table.setPreferredScrollableViewportSize(table.
getPreferredSize());
table.setRowHeight(22);
setVisibleRowCount(table,10);
table.setAutoResizeMode( JTable.AUTO_RESIZE_OFF );
table.setFillsViewportHeight(true);
table.getTableHeader().setReorderingAllowed(false);
table.getTableHeader().setResizingAllowed(false);
panelTable.add(new JScrollPane(table));
} // -> createTable()
// Method to display a fixed number of rows in the JTable viewport
public static void setVisibleRowCount(JTable table, int rows){
int height = 0;
for(int row=0; row<rows; row++) {
height += table.getRowHeight(row);
}
table.setPreferredScrollableViewportSize(new Dimension(
table.getPreferredScrollableViewportSize().width, height ));
}
// Create and display the contents of the frame
public static void showGUI() {
// Disable boldface controls
UIManager.put("swing.boldMetal", Boolean.FALSE);
// Create the frame
frameTableCellChange = new JFrame("Table frame");
frameTableCellChange.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frameTableCellChange.addWindowListener(new WindowAdapter() {
#Override
public void windowClosing(WindowEvent we) {
System.exit(0);
}
});
// Create and set up the content pane.
TableCellChange newContentPane = new TableCellChange();
newContentPane.setOpaque(true); //content panes must be opaque
frameTableCellChange.setContentPane(newContentPane);
// Arrange and display the window.
frameTableCellChange.pack(); //must be called first
frameTableCellChange.setLocationRelativeTo(null); //center window
frameTableCellChange.setResizable(false);
frameTableCellChange.setVisible(true);
} //-> showQueryResultGUI()
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.
UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException |
IllegalAccessException |
javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(TableCellChange.class.getName()).
log(java.util.logging.Level.SEVERE, null, ex);
}
// Display the frame and it's contents
TableCellChange.showGUI();
}
});
} //-> main(String[] args)
} //-> TableCellChange class
EDIT This class was created by Rob Camick (a.k.a. camickr), all credits go to him for creating this awesome piece of code. Only comments were removed from the code in order to respect the character limit.
TableCellListener class
import java.awt.event.ActionEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.Action;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
/*
* This class listens for changes made to the data in the table via the
* TableCellEditor. When editing is started, the value of the cell is saved
* When editing is stopped the new value is saved. When the old and new
* values are different, then the provided Action is invoked.
* The source of the Action is a TableCellListener instance.
*/
public class TableCellListener implements PropertyChangeListener, Runnable {
private JTable table;
private Action action;
private int row;
private int column;
private Object oldValue;
private Object newValue;
public TableCellListener(JTable table, Action action) {
this.table = table;
this.action = action;
this.table.addPropertyChangeListener(this);
}
private TableCellListener(JTable table, int row, int column, Object oldValue, Object newValue) {
this.table = table;
this.row = row;
this.column = column;
this.oldValue = oldValue;
this.newValue = newValue;
}
public int getColumn() {
return column;
}
public Object getNewValue() {
return newValue;
}
public Object getOldValue() {
return oldValue;
}
public int getRow() {
return row;
}
public JTable getTable() {
return table;
}
#Override
public void propertyChange(PropertyChangeEvent e) {
if ("tableCellEditor".equals(e.getPropertyName())) {
if (table.isEditing()) {
processEditingStarted();
} else {
processEditingStopped();
}
}
}
private void processEditingStarted() {
SwingUtilities.invokeLater(this);
}
#Override
public void run() {
row = table.convertRowIndexToView(table.getEditingRow());
row = table.getEditingRow();
column = table.convertColumnIndexToModel(table.getEditingColumn());
oldValue = table.getModel().getValueAt(row, column);
newValue = null;
}
private void processEditingStopped() {
newValue = table.getModel().getValueAt(row, column);
if (!newValue.equals(oldValue)) {
TableCellListener tcl = new TableCellListener(
getTable(), getRow(), getColumn(), getOldValue(), getNewValue());
ActionEvent event = new ActionEvent(
tcl,
ActionEvent.ACTION_PERFORMED,
"");
action.actionPerformed(event);
}
}
}
I understand that when filtering a table the indexes of the table view change and must be synchronized with the indexes of the underlying model. How can that be done in order for the filtered table to work?
You implemented the Action for the TableCellListener incorrectly. You can't use the selected row/colum because those values are in the Table view. The TableCellListener works on the model.
Check out the example Action provided with Table Cell Editor. To get the row/column that was changed you must reference the TableCellListener itself.
Edit:
Here is my simple text example. When you change the "Price", the "Price Change" and "Value" columns are automatically updated.
import java.awt.*;
import java.awt.event.*;
import java.io.*;
import java.net.*;
import javax.swing.*;
import javax.swing.table.*;
public class TableCellListenerTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
public static void createAndShowGUI()
{
String[] columnNames = {"Stock", "Shares", "Price", "Price Change", "Value"};
Object[][] data =
{
{"IBM", new Integer(100), new Double(85), new Double(0), new Double(8500)},
{"Apple", new Integer(300), new Double(30), new Double(0), new Double(9000)},
{"Sun", new Integer(1500), new Double(5), new Double(0), new Double(7500)},
{"Google", new Integer(100), new Double(100), new Double(0), new Double(10000)}
};
DefaultTableModel model = new DefaultTableModel(data, columnNames)
{
public Class getColumnClass(int column)
{
return getValueAt(0, column).getClass();
}
public boolean isCellEditable(int row, int column)
{
return column == 2;
}
};
JTable table = new JTable(model);
table.setPreferredScrollableViewportSize(table.getPreferredSize());
JScrollPane scrollPane = new JScrollPane(table);
// Add a sorter
TableRowSorter<DefaultTableModel> sorter = new TableRowSorter<DefaultTableModel>(model);
table.setRowSorter(sorter);
// Filter
try
{
RowFilter<DefaultTableModel, Object> rf = RowFilter.regexFilter("l", 0);
sorter.setRowFilter(rf);
}
catch (java.util.regex.PatternSyntaxException e) {}
Action action = new AbstractAction()
{
public void actionPerformed(ActionEvent e)
{
TableCellListener tcl = (TableCellListener)e.getSource();
int column = tcl.getColumn();
if (column == 2)
{
int row = tcl.getRow();
double oldPrice = ((Double)tcl.getOldValue()).doubleValue();
double newPrice = ((Double)tcl.getNewValue()).doubleValue();
TableModel model = tcl.getTable().getModel();
double priceChange = new Double(newPrice - oldPrice);
model.setValueAt(priceChange, row, 3);
double shares = ((Integer)model.getValueAt(row, 1)).doubleValue();
Double value = new Double(shares * newPrice);
model.setValueAt(value, row, 4);
}
}
};
TableCellListener tcl = new TableCellListener(table, action);
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Table Cell Listener");
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
frame.add( scrollPane );
frame.setSize(400, 160);
frame.setLocationRelativeTo( null );
frame.setVisible(true);
}
}
You may need to do the conversion from view to model. Take a look at Sorting and Filtering part of How to Use Tables tutorial:
When a table uses a sorter, the data the users sees may be in a
different order than that specified by the data model, and may not
include all rows specified by the data model. The data the user
actually sees is known as the view, and has its own set of
coordinates. JTable provides methods that convert from model
coordinates to view coordinates — convertColumnIndexToView and
convertRowIndexToView — and that convert from view coordinates to
model coordinates — convertColumnIndexToModel and
convertRowIndexToModel.
EDIT: convert from view (table) to model:
Replace these rows:
row = table.convertRowIndexToView(table.getEditingRow());
row = table.getEditingRow();
With:
row = table.convertRowIndexToModel(table.getEditingRow());

Deletion of JTable row

I'm working on jTable and I intend on deleting specific rows as part of the data manipulation to be conducted on the table. Essentially I've been able to successfully delete a row which the user would specify but I what I really want to do is to delete several rows based on boolean states or check boxes that are selected as part one of the four columns of the table.
I've attached a screenshot as to the current result of running the code and would like to be able to delete the rows based on the selected boolean states or check boxes.
Below is my code including my table model code which extends the AbstractTableModel:
package com.TableRowSelectProgramatically;
import javax.swing.*;
import javax.swing.event.TableModelEvent;
import javax.swing.event.TableModelListener;
import javax.swing.table.AbstractTableModel;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Vector;
#SuppressWarnings("serial")
public class JTableRowSelectProgramatically extends JPanel {
public MyTableModel MyTableModel;
public String Cell1 = "ABCD";
public JTableRowSelectProgramatically() {
initializePanel();
}
private void initializePanel() {
setLayout(null);
setPreferredSize(new Dimension(1250, 700));
// Table model
MyTableModel = new MyTableModel();
// Table
final JTable table = new JTable(MyTableModel);
table.setFillsViewportHeight(true);
// Row data
Object[] values = {Cell1, "EFGH", "IJKL", new Boolean(false)};
Object[] values2 = {"UVWX","QRST","MNOP", new Boolean(false)};
Object[] values3 = {"ABCD","YZAB","CDEF", new Boolean(false)};
final Object[] values4 = {"QWERTY","YTREWQ","QWERTY", new Boolean(false)};
// Insert row data
MyTableModel CustomTableModel = (MyTableModel) table.getModel();
CustomTableModel.insertData(values);
CustomTableModel.insertData(values2);
CustomTableModel.insertData(values3);
CustomTableModel.insertData(values);
CustomTableModel.insertData(values2);
CustomTableModel.insertData(values3);
CustomTableModel.insertData(values);
CustomTableModel.insertData(values2);
CustomTableModel.insertData(values3);
// Create edit menu label
JLabel labelEditMenu = new JLabel("EDIT MENU:\n");
// Create add row btn
JButton addRow = new JButton("Add Row");
// Attach listener for add row btn
addRow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
MyTableModel.insertData(values4);
}
});
// Create delete row btn
JButton deleteRow = new JButton("Delete Row");
// Attach listener for delete btn
deleteRow.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent event) {
MyTableModel.removeRow(1);
}
});
// Create scroll pane
JScrollPane pane = new JScrollPane(table);
pane.setBounds(30, 30, 500, 500);
//
JTextField AgentIDTextField = new JTextField();
// Populate the JPanel
JPanel dataEntryPanel = new JPanel(new FlowLayout());
//dataEntryPanel.setBackground(Color.orange);
dataEntryPanel.setBounds(540, 30, 500, 50);
//dataEntryPanel.add(AgentIDTextField);
dataEntryPanel.add(labelEditMenu);
dataEntryPanel.add(addRow);
dataEntryPanel.add(deleteRow);
// Join up GUI
add(pane);
add(dataEntryPanel);
}
// Enable visibity of frame
public static void showFrame() {
JPanel panel = new JTableRowSelectProgramatically();
JFrame frame = new JFrame("Test table");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setContentPane(panel);
frame.pack();
frame.setVisible(true);
}
// Launch prog
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
JTableRowSelectProgramatically.showFrame();
}
});
}
// Create custom table model for data entry
class MyTableModel extends AbstractTableModel {
private String[] columnNames = {"COLUMN 0", "COLUMN 1", "COLUMN 2", "COLUMN 3"};
private Vector data = new Vector();
#Override
public int getRowCount() {
return data.size();
}
#Override
public int getColumnCount() {
return columnNames.length;
}
#SuppressWarnings("rawtypes")
#Override
public Object getValueAt(int row, int col) {
return ((Vector) data.get(row)).get(col);
}
public String getColumnName(int col){
return columnNames[col];
}
public Class getColumnClass(int c){
return getValueAt(0,c).getClass();
}
public void setValueAt(Object value, int row, int col){
((Vector) data.get(row)).setElementAt(value, col);
fireTableCellUpdated(row,col);
}
public boolean isCellEditable(int row, int col){
if (3 == col){
return true;
}
else {
return false;
}
}
public void insertData(Object[] values){
data.add(new Vector());
for(int i =0; i<values.length; i++){
System.out.println("data.size is: " + data.size());
((Vector) data.get(data.size()-1)).add(values[i]);
}
fireTableDataChanged();
}
public void removeRow(int row){
data.removeElementAt(row);
fireTableDataChanged();
}
}
}
New attempt at deleting rows of a JTable:
public void deleteRow() {
for (int i = 0; i < getRowCount(); i++) {
Object columnState = getValueAt(i, 3);
System.out.println("STEP 6 - In row " + i + " boolean value is: " + columnState);
boolean columnStateAsBoolean = (Boolean) columnState;
System.out.println("STEP 6 - In row " + i + " Column State As Boolean is: " + columnStateAsBoolean);
if(columnStateAsBoolean == true) {
removeRow(i);
}
System.out.println("-------------------------------------");
}
}
I really want to do is to delete several rows based on boolean states or check boxes
create a loop that starts on the last row and counts down to 0.
Then for every row you use the table.getValueAt(...) method to get the Boolean value of the column.
If the value is true then delete the row.
//Try something like this
int rowCount=table.getSelectedRowCount();//get selected row's count
int row;
if(rowCount>0)
{
while((row=table.getSelectedRow())!=-1)
(DefaultTableModel)table.getModel().removeRow(table.convertRowIndexToModel(row));
}

Categories