Swing table update value in the DB and reload table model - java

I want to update a swing table's row value in the DB, clear the model, and load the new model with the new updated value. The problem is that when I click the button to update the value, the model is cleared but no data is shown in the table. What am I doing wrong?
Parts of the code not relative to the table have been removed in order to make the example easier.
public class ShowValues extends JFrame {
//Attributes
private DefaultTableModel model;
private JTable table = new JTable()
{
public boolean isCellEditable(int row, int column)
{
return false;
};
};
public ShowValues() {
btnDeleteItem.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0)
{
int selectedRowNumber = table.getSelectedRow();
String selectedItemId = (String) table.getModel().getValueAt(selectedRowNumber, 0);
//code to change selected item's state to deleted in the DB
model.setRowCount(0); //clear model
showTable(); //load new model
labelMsg.setText("Item deleted");
}
});
btnDeleteItem.setBounds(200, 320, 203, 57);
contentPane.add(btnDeleteItem);
}
public void showTable()
{
String columnNames[] = {"Item Id", "Item Name", "Item price"};
//code to get the data form the DB
String dataValues[][] = new String[itemNum][3];
for(int i=0; i<itemNum; i++)
{
dataValues[i][0] = idItem[i];
dataValues[i][1] = nameItem[i];
dataValues[i][2] = priceItem[i];
}
model = new DefaultTableModel(dataValues, columnNames);
table.setModel(model);
scrollPane = new JScrollPane(table);
scrollPane.setBounds(17, 20, 490, 205);
scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
topPanel.add(scrollPane);
}
}

//code to change selected item's state to deleted in the DB
Why would you want to reload all the data just because the change the value of one property in the row? That is not very efficient.
Just use the setValueAt(...) method to change the value in the JTable.
The problem is that when I click the button to update the value, the model is cleared but no data is shown in the table
The problem is you create a new JTable, but you never add the table to the viewport of your JScrollPane.
The solution is to NOT create a new JTable. Just create a new TableModel. Then you can just use:
table.setModel( theNewlyCreateTableModel );

Related

Populate JTable on press of TAB key

I have a JTable. User will enter an ID in a particular column and press TAB. I need to add event on that column to fetch value from DB and populate the rest of the columns of that row and create a new row for the next entry.
I am new to Swing and its difficult to find what is the best way to do it as i can see examples which were written in 2010 or so. Not sure if thats relevant still.
What I don't know:
adding event handler to a particular column's cell in table.
add next row after populating the data.
You can use a TableModelListener for this. When user change ID column value, tableChanged() is invoked. Then the relevant data is fetched from the DB and set in the row. And a new row is added as well. Try below example.
(For demonstration purpose I have used a mock database in this example. It only gives rows for IDs "111" and "222".)
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.table.DefaultTableModel;
import java.util.Vector;
public class TableDataChange
{
public static void main(String[] args)
{
DefaultTableModel tableModel = new DefaultTableModel(
new Object[][] {{"", "", ""}},
new Object[] {"ID", "Column 2", "Column 3"});
tableModel.addTableModelListener(new TableModelListener()
{
#Override
public void tableChanged(TableModelEvent e)
{
String id = (String) tableModel.getValueAt(e.getFirstRow(), 0);
if (id != null)
{
Vector row = Database.loadRowForId(id);
tableModel.getDataVector().set(e.getFirstRow(), row);
tableModel.addRow(new Vector());
}
}
});
JTable table = new JTable(tableModel);
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(new JScrollPane(table));
f.setBounds(300, 200, 400, 300);
f.setVisible(true);
}
}
// Mock database
class Database
{
static Vector loadRowForId(String id)
{
Vector row = new Vector();
if (id.equals("111"))
{
row.add("111");
row.add("aaa");
row.add("bbb");
}
else if (id.equals("222"))
{
row.add("222");
row.add("ppp");
row.add("qqq");
}
return row;
}
}
You can try something like this,
//Add Key Listener
table.addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent event) {
if (event.getKeyChar() == KeyEvent.VK_TAB) {
int selectedColumn = table.getSelectedColumn();
//Now you can search records related to ID and populate the table
}
}
});

how to delete selected rows (multiple rows) from CheckboxTableViewer when button clicks? (table is connected to oracle database)

i hava a CheckboxTableViewer which has 10 columns, and the table is filled from database,
and i have a button outside the table named as "Delete",
what i want to do is:-
when i select rows using check box (multiple selection also) and when i press the "delete" button , i want the selected rows should get deleted from the database, and the tableviewer shuold get refreshed.
am pasting my tableviewer code below:-
final CheckboxTableViewer dataTable = CheckboxTableViewer.newCheckList(TableComposite2, SWT.MULTI | SWT.H_SCROLL
| SWT.V_SCROLL | SWT.BORDER |SWT.DM_FILL_BACKGROUND|SWT.FULL_SELECTION);
dataTable .getTable().setHeaderVisible(true);
dataTable .getTable().setLinesVisible(true);
dataTable .setContentProvider(new ArrayContentProvider());
//Action Check box
TableColumn columnCHead=new TableColumn(dataTable .getTable(),SWT.NONE);
columnCHead.setText("Delete");
columnCHead.setWidth(50);
// setting column input
TableViewerColumn columnC=new TableViewerColumn(dataTable ,columnCHead);
columnC.setLabelProvider(new ColumnLabelProvider()
{
public String getText(Object Element)
{
return null;
}
});
TableColumn columnFS1Head=new TableColumn(dataTable .getTable(),SWT.NONE);
columnFS1Head.setText("SOURCE DIRECTORY");
columnFS1Head.setWidth(300);
TableViewerColumn columnFS1=new TableViewerColumn(dataTable ,columnFS1Head);
columnFS1.setLabelProvider(new ColumnLabelProvider()
{
public String getText(Object Element)
{
AgedFileMaster a=(AgedFileMaster)Element;
return a.getDIRECTORY_PATH();
}
enter code here});
......
and i have a button for delete operation,(outside the table),
when i press delete button, i want the selected rows to get deleted...
am beginner to SWT.
anyone please help......
Use addSelectionListener on your Button control to be notified when the button is pressed:
button.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent event)
{
// TODO handle delete here
}
});
You need to do two things to remove the data - first update your data model to remove the objects and secondly tell the table viewer that the model has changed.
You can do something like this:
dataTable.getTable().setRedraw(false); // Stop redraw during update
IStructuredSelection selection = (IStructuredSelection)dataTable.getSelection();
for (Iterator<?> iterator = selection.iterator(); iterator.hasNext(); )
{
Object selectedObject = iterator.next();
// TODO remove from data model array
// Tell table view the object has been removed
dataTable.remove(selectedObject);
}
dataTable.getTable().setRedraw(true); // Allow updates to be drawn
An alternative to calling dataTable.remove on each object is to call dataTable.refresh once at the end. There is also a variant of remove which accepts an array of objects.
TableViewerColumn actionsNameCol = new TableViewerColumn(viewer, column);
actionsNameCol.setLabelProvider(new ColumnLabelProvider(){
//make sure you dispose these buttons when viewer input changes
Map<Object, Button> buttons = new HashMap<Object, Button>();
#Override
public void update(ViewerCell cell) {
TableItem item = (TableItem) cell.getItem();
Button button;
if(buttons.containsKey(cell.getElement()))
{
button = buttons.get(cell.getElement());
}
else
{
button = new Button((Composite) cell.getViewerRow().getControl(),SWT.NONE);
button.setText("Remove");
buttons.put(cell.getElement(), button);
}
TableEditor editor = new TableEditor(item.getParent());
editor.grabHorizontal = true;
editor.grabVertical = true;
editor.setEditor(button , item, cell.getColumnIndex());
editor.layout();
}
});
Delete selected rows (multiple rows) from Table when button clicks (Database Connectivity)
//Java ArrayList class uses a dynamic array for storing the elements
List<String> id_list=new ArrayList<String>();
//Button Text:Selected Row Delete
Button btnNewButton = new Button(parent, SWT.NONE);
btnNewButton.setText("Selected Row Delete");
btnNewButton.addSelectionListener(new SelectionAdapter() {
#Override
public void widgetSelected(SelectionEvent e) {
TableItem[] item=table.getItems();
for(int i=0;i<table.getItemCount();i++)
{
if(item[i].getChecked()&&!item[i].getText(1).equals(""))
{
String id=item[i].getText(1);
id_list.add(id);//Add ID into List
}
}
for(int j=0;j<id_list.size();j++)
{
//class:Test
//Method:DeleteData(String ID) pass id to delete rows
// type cast object into string
Test.DeleteData((String) id_list.get(j));
}
}
});
btnNewButton.setImage(ResourceManager.getPluginImage("RCP_Demo", "icons/delete.png"));
btnNewButton.setBounds(18, 370, 68, 23);
Test.java
public class Test {
static Connection conn = null;
static PreparedStatement presta=null;
public static void DeleteData(String ID)
{
String url = "jdbc:sqlite:Demo.db";
try{
Class.forName("org.sqlite.JDBC");
conn = DriverManager.getConnection(url);
presta = conn.prepareStatement("delete from Student where sid=?");
presta.setString(1, ID);
presta.executeUpdate();
DisplayData();
}catch(Exception e)
{
System.err.println( e.getClass().getName() + ": " + e.getMessage() );
}
}//End DeleteData()
}//End Test class

how to Make only one column editable in JTable

I want to make my JTable unEditable but i want to add JButton to to it and the column of the button must be editable for the press event so how can i make this only column editable?
here is my table model code:
DefaultTableModel model = new DefaultTableModel();
model.setColumnIdentifiers(new String[]{
"IDemp",
"empNumber",
"Fname","Lname",
"BirthDate",
"Address",
"email",
"Button" }
);
//TableCellRenderer buttonRenderer = new JTableButtonRenderer();
for(int i=0;i<emps1.size();i++) {
model.addRow(new Object[]{String.format("%d",emps1.get(i).getIDemp()),
String.format("%d",emps1.get(i).getEmpNumber()),emps1.get(i).getFname(),
emps1.get(i).getLname(),emps1.get(i).getBirthDate(),
emps1.get(i).getAddress(), emps1.get(i).getEmail().getEmailAddress()});
}
and here is my jtable:
JTable emps=new JTable(model);
emps.getColumn("Button").setCellRenderer(new ButtonRenderer());
emps.getColumn("Button").setCellEditor(new ButtonEditor(new JCheckBox()));
How could I make the "Button" column editable and the others not?
*And if you have better way to add JButton to the JTable it will be great."
You need to extends the AbstractTableModel and override isCellEditable like this:
public class MyTableModel extends AbstractTableModel {
public boolean isCellEditable(int row, int col) {
if (col== columnIndex) { //columnIndex: the column you want to make it editable
return true;
} else {
return false;
}
}
}

Firing itemStateChanged event on Combo box inside jTable

My problem is that I want to have a itemSateChanged listener on a combo box which is inside a jTable. When I change the values of the combo box I want data added to a cell in the respected row of the jTable.
This is the code where the combo box is created.
public void setUpSectionColumn(JTable table, TableColumn statusColumn) {
//Set up the editor for the sport cells.
JComboBox comboBox = new JComboBox();
comboBox.addItem("Lending");
comboBox.addItem("Childen Lending");
comboBox.addItem("Reference");
comboBox.addItem("Special Collection");
statusColumn.setCellEditor(new DefaultCellEditor(comboBox));
//Set up tool tips for the sport cells.
DefaultTableCellRenderer renderer =
new DefaultTableCellRenderer();
renderer.setToolTipText("Click for combo box");
statusColumn.setCellRenderer(renderer);
}
This is the method I have come up with for the listener which does not work.
public void fillTable2() {
jTable2.getModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent evt) {
int row = jTable2.getSelectedRow();
String section;
if (row == -1) {
section = "Lending";
} else {
section = jTable2.getValueAt(row, 3).toString();
}
int accessNo = bdao.getLastAccessNo(section);
DefaultTableModel model = (DefaultTableModel) jTable2.getModel();
Object[] rowdata = {Integer.toString(accessNo), "", ""};
model.addRow(rowdata);
}
});
}
As discussed here, you can use a JComboBox as a TableCellEditor. There's an example here using DefaultCellEditor.

Updating jtextfield's from jtable

Can someone help me with this listener?
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.getSelectionModel().addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent e){
if(e.getValueIsAdjusting()){
ListSelectionModel model = table.getSelectionModel();
int lead = model.getLeadSelectionIndex();
displayRowValues(lead);
}
}
private void displayRowValues(int rowIndex){
String country = "";
Object oCountry = table.getValueAt(rowIndex, 0);
country += oCountry.toString();
countryTxt.setText(country );
}
});
It's supposed to send data from cell in jtable (table) into a textfield (countryTxt) when one of the row's is selected, but it works only when I click on row and not when I'm cycling trough my table with arrow key's.
The problem is with this line:
if (e.getValueIsAdjusting()) {
Replace this with:
if (e.getValueIsAdjusting()) return;
This is a check for multiple selection events BTW.
If you comment out e.getValueIsAdjusting() it works.
http://docs.oracle.com/javase/6/docs/api/javax/swing/ListSelectionModel.html#setValueIsAdjusting(boolean)

Categories

Resources