I have a JFrame application that contains a JTabel. The underlying table model is my own class that I made that extends AbstractTableModel. The data in the first column is of type boolean and so I want it to show the value in the form of a checkbox. To do this, I added the following code in my table model getColumnClass method:
#Override
public Class<?> getColumnClass(int columnIndex) {
if (columnIndex == 0) {
return Boolean.class;
} else if (columnIndex == 1) {
....
....
}
This works fine and my table cell looks like the following which is what I want:
The behavior I now want is that when the user clicks on a cell in column 0 of any row I want to toggle the value of On Sale.
My main class listens to selections in the table by implementing ListSelectionListener and overriding the valueChanged method. Inside the valueChanged method I can check the selected column by calling table.getSelectedColumn and checking to see if it's 0 then getting the object at the selected row and toggling the boolean on sale value.
The problem I am running into is that if a particular row is already selected and the user clicks the cell in column 0 for the selected row the valueChanged method is never called and so therefore I never toggle the value.
My quesion is, how do I detect a cell selection/click on a row that is already selected? Should I use a mouse selection listener then determine the cell that was clicked using the location data from the mouse click event?
Thank you.
Have you tried listening to table change instead ? You would need to implement TableModelListener and to have this :
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);
...// Do something with the data...
}
Related
I want to populate the combo box with the value from database based on the selection of table row, it works, but only when I select the different cell of the row then select required combo box cell. But if I select the combobox cell of another row, it shows previous items, and after selecting one of them, if I again click on the combobox it will populate with fresh values. I want the fresh values be populated when I click on row or even combo box cell. Please help.
The code is given below:-
String columnName[] = { "Date","Voucher ID","Voucher No","Amount","VOUCHER_NARRATION","Exp. Head" };
String dataValues[][] = {};
voucherTable=new JTable(dataValues,columnName);
voucherTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
ListSelectionModel list=voucherTable.getSelectionModel();
voucherTable.setSelectionModel(list);
list.addListSelectionListener(new ListSelectionListener(){
public void valueChanged(ListSelectionEvent lt) {
try {
voucherid=voucherTable.getValueAt(voucherTable.getSelectedRow(),1).toString();
System.out.println(voucherid);
comboBox.removeAllItems();
TableColumn road=voucherTable.getColumnModel().getColumn(5);
voucherTable.getColumnModel().getColumn(5).setCellEditor(new DefaultCellEditor(new VoucherUpdate().getExpHead(voucherid)));
} catch(Exception h) {
System.err.println(h);
return;
}
}
});
public JComboBox getExpHead(String vid) {
String voucherId=vid;
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
Connection conn=DriverManager.getConnection("jdbc:odbc:SARALIFMS","SARALIFMS","O391120SUMAN");
Statement st=conn.createStatement();
ResultSet rs=st.executeQuery("SELECT E.EXP_ID,EXP_HEAD FROM TD_VOUCHER_SUMAN D, MM_PRIA_EXPENDITURE E"
+" WHERE VOUCHER_ID='"+voucherId+"' AND D.ACCOUNT_CODE=E.ACCOUNT_CODE");
while(rs.next()) {
String expHead=rs.getString("EXP_HEAD");
comboBox.addItem(expHead);
}
conn.close();
} catch(Exception e) {
System.out.println(e);
}
return comboBox;
}
it works, but only when I select the different cell of the row then select required combo box cell
When you click on a cell using a combo box as an editor, the editor is invoked BEFORE the selected row has been updated. So this is a timing issue.
One solution is to override the getCellEditor(...) method of the JTable to load the data when the editor is actually invoked. At this point in time the selected row will be updated and you can get the data for the appropriate row.
This approach is demonstrated in this question: https://stackoverflow.com/a/4211552/131872
Note you may want to consider caching the data so you don't do an SQL access every time you edit the cell.
I have a table displayed in my Java GUI, which the user can add rows to by clicking an 'Add' button. The cells in the row that is added to the table are all editable by default, and the user can select each row/ cell as they wish.
I now want to add the functionality to remove a row from the table, but I can't seem to find the correct way to do this with a DefaultTableModel data type.
I have added the following code to the action listener for my 'remove row' button:
removeBtn.addActionListener(new ActionListener(){
public void removeRow(){
DefaultTableModel model = (DefaultTableModel)jEntityFilterTable.getModel();
model.removeRow();
}
});
However, the removeRow() method requires a parameter of type int (the index number of the row I want to remove). How can I get the 'selected row' from the DefaultTableModel? There doesn't appear to be a method that allows you to do this...
You can obtain the index from the table.
removeBtn.addActionListener(new ActionListener(){
public void removeRow(){
int selRow = jEntityFilterTable.getSelectedRow();
if(selRow != -1) {
DefaultTableModel model = (DefaultTableModel)jEntityFilterTable.getModel();
model.removeRow(selRow);
}
}
});
I'm building and app with multiple JTables and I need to detect when cell value change occurs so I can update it in the database. I tried TableModelListener and overriding tableChanged, but it fires only when I click away (click on another row) after I have edited a cell.
Any other way to do this?
You can implement the CellEditorListener interface, as shown in this example. Note that JTable itself is a CellEditorListener.
It may also be convenient to terminate the edit when focus is lost, as shown here:
table.putClientProperty("terminateEditOnFocusLost", true);
More Swing client properties may be found here.
I'm agreeing with #mKorbel - unless all your input is checkboxes and dropdowns, you're going to want to wait until the cell editing is stopped (you don't want to commit to the database every time a letter is typed in a textbox).
If the problem is that it's not committing after focus has gone to another component, add a FocusListener that stops editing the table when focus is lost on the table:
Example:
final JTable table = new JTable();
table.addFocusListener(new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
TableCellEditor tce = table.getCellEditor();
if(tce != null)
tce.stopCellEditing();
}
});
I use the enter key so everytime a user hit enter the cell will update.
DefaultTableModel dtm = new DefaultTableModel(data, columnNames);
JTable table = new JTable(dtm);
table.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
int row = table.getSelectedRow();
int column = table.getSelectedColumn();
// resul is the new value to insert in the DB
String resul = table.getValueAt(row, column).toString();
// id is the primary key of my DB
String id = table.getValueAt(row, 0).toString();
// update is my method to update. Update needs the id for
// the where clausule. resul is the value that will receive
// the cell and you need column to tell what to update.
update(id, resul, column);
}
}
});
This is also handy if you want to stop the editing on an event handler from selection change or save button.
if (table.isEditing())
table.getCellEditor().stopCellEditing();
I am using GXt GWt and am trying to get the values from a selected row in a tree grid, but can't seem to get it working..
E.g. if the user clicks row, i want to be able to get the values for all the columns in that row.
cm = new ColumnModel(createColumnConfig());
// Create grids based on data (held in stores), and attach listeners for when a row is clicked
final TreeGrid<Build> nightlyResultsGrid = createTreeGrid(nightlyResultsStore);
nightlyResultsGrid.addListener(Events.RowClick, new Listener<BaseEvent>()
{
public void handleEvent(BaseEvent clickEvent)
{
GridEvent gridEvent = (GridEvent)clickEvent;
gridEvent.getModel().get("Platform").toString();
gridEvent.getModel().get("Date").toString();
gridEvent.getModel().get("Build").toString();
}
}
The code above keeps generating an exception..
15:58:09.861 [ERROR] [dashboard] Uncaught exception escaped
java.lang.NullPointerException: null
at com.rory.mep.ui.metrics.client.UserInterface$3.handleEvent(UserInterface.java:109)
at com.extjs.gxt.ui.client.event.BaseObservable.callListener(BaseObservable.java:178)
at com.extjs.gxt.ui.client.event.BaseObservable.fireEvent(BaseObservable.java:86)
at com.extjs.gxt.ui.client.widget.Component.fireEvent(Component.java:456)
at com.extjs.gxt.ui.client.widget.grid.Grid.onClick(Grid.java:811)
at com.extjs.gxt.ui.client.widget.treegrid.TreeGrid.onClick(TreeGrid.java:745)
Any help is much appreciated.
Be sure to read the Javadocs for events when you use them. From Grid's docs:
RowClick : GridEvent(grid, rowIndex, cellIndex, event)
Fires after a row is clicked.
grid : this
rowIndex : the row index
cellIndex : cell index
index : the cell index
event : the dom event
The model isn't available, so getModel() is returning null. Instead, use the rowIndex with the store to get the model.
I am using gwt2.3
My celltable contains 10 rows, 5 columns.
All cells in 1st row is empty,editable.
Whenever user clicks on column cell lets say 1st row X 3rd column
then user will edit that cell say "xyz".
after that when user click on button: "update column cell" then xyz value set to all cell present in that column.
I am using different celltype in celltable.
How to set/update all cell value in that particular column/page whose 1st cell is edited
Any help or guidance in this matter would be appreciated
Create a FieldUpdater in order to push back the changes to your Domain object. Then in the onClick callback of your button update your List with the values from the first row.
For example for an arbitrary TextInputColumn which takes a MyDTO class (can be any domain object) as the value type you can define following FieldUpdater:
myColumn.setFieldUpdater(new FieldUpdater() {
#Override
public void update(int index, MyDTO object, String value) {
// Push the changes into the MyDTO. At this point, you could send an
// asynchronous request to the server to update the database.
object.someField = value;
// Redraw the table with the new data.
table.redraw();
}
});
You have to set such a FieldUpdater for all 5 columns. (someField is the field in your DTO which you want to update).
Now in the onClick() callback of the button you have to update the actual list. Looks something like that:
update_column_cell.addClickHandler(new ClickHandler() {
#Override
public void onClick(ClickEvent event) {
//Supose listDataProvider is the instance of your DataSource for your CellTable
List<MyDTO> list = listDataProvider.getList();
// get cell values for the first row (this is for one cell)
newSomeField = list.get(0).someField;
newSomeField2 = list.get(0).someField2;
for (int i = 1;i<list.size();i++) {
MyDTO dto = list.get(i);
if (newSomeField != null && newSomeField.isNotEmpty()) {
dto.someField = newSomeField;
}
if (newSomeField2 != null && newSomeField2.isNotEmpty()) {
dto.someField2 = newSomeField2;
}
}
}
})
This example only handles two fields of your DTO. You will probably have to extend it to cover all 5 fields you are showing as columns in your CellTable