I added a mouse clicked listner to my jtable, when i double click the row, will pop up an window accordingly.
jTable.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent e) {
double amount = Double.parseDouble(jTable.getValueAt(getSelectedRow(), 4).toString());
String remarks = jTable.getValueAt(getSelectedRow(), 3).toString();
String transactionID = jTable.getValueAt(getSelectedRow(), 1).toString();
new EditFrame(...)
}
});
This code I used to retrieve the row selected row.
public int getSelectedRow() {
jTable.getSelectionModel().addListSelectionListener(
new ListSelectionListener() {
public void valueChanged(ListSelectionEvent event) {
int viewRow = jTable.getSelectedRow();
selectedRow = viewRow;
System.out.println(viewRow);
}
});
return selectedRow;
}
In my case, I realised when I clicked the second row in the first time, I get null for selectedRow, only when I select first row then second row, I then can get the correct data. And If I removed the mouse listener the problem then be solved. Is it because I doing something wrong at the mouse click listener?
If you just want to know what row was clicked then you don't need the selection listener. Just use:
table.rowAtPoint();
You're doing it the wrong way. Remove your current getSelectedRow() method completely and never try to code something similar. Here is a better version:
jTable.addMouseListener(new java.awt.event.MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent e) {
int selectedRow = jTable.getSelectedRow();
double amount = Double.parseDouble(jTable.getValueAt(selectedRow, 4).toString());
String remarks = jTable.getValueAt(selectedRow, 3).toString();
String transactionID = jTable.getValueAt(selectedRow, 1).toString();
new EditFrame(...)
}
});
Related
I've got a Swing screen that opens with a JTable full of itenms and a JList that is empty. After an event from a button I move the itens from JTable to JList, making JTable empty and JList full of items as I desire. But I've got a weird problem that JTable goes back to its original state with all the items again when the frame is minimized and then maximized.
It should not happen as I remove the items from the array that keeps the JTable values. I used sysout to watch on console the array size as the items are being removed and I am sure in the end its size has come to zero.
Plus, I put break points in the getXXX that retrieves the array value to JTable and a repaint() method I put myself to overwrite its original and I got no break point pause of any of them.
So....I don't know where it is getting the value to reset to original state!
Finally, I've just noticed it happens when the table's area is clicked, so change the JFrame to a JDialog where there is no minimize/maximize button would not solve the problem at all.
I don't know if some code would help but in any case, I've got an init method just to initialize the JTable.
private void initTable(Object rowData[][]) {
documents = rowData;
dataModel = new DataModel(rowData, COLUMNS);
scrollPane = new JScrollPane();
scrollPane.setBounds(13, 188, 300, 148);
contentPane.add(scrollPane);
table = new JTable(dataModel) {
#Override
public void changeSelection(int rowIndex, int columnIndex, boolean toggle, boolean extend) {
super.changeSelection(rowIndex, columnIndex, true, false);
}
};
scrollPane.setViewportView(table);
table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
table.getColumnModel().getColumn(0).setPreferredWidth(30);
table.getColumnModel().getColumn(1).setPreferredWidth(260);
table.setCellSelectionEnabled(true);
table.setRowSelectionAllowed(false);
table.setColumnSelectionAllowed(false);
ListSelectionModel cellSelectionModel = table.getSelectionModel();
cellSelectionModel.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
if (selectedRow >= 0) {
if (selectedColumn == 0) {
Boolean valorCol= (Boolean) documents[selectedRow][0];
if (valorCol== true) {
documents[selectedRow][0] = false;
}
else {
documents[selectedRow][0] = true;
}
}
}
}
table.clearSelection();
}
});
}
_______EDITING_______
The way I remove the items are made of a List not the original array. After the procedure that moves the items from the JTable, I call the method above but this time the list is empty. Here it goes the "missing code"
After moving all the items...
Object[][] documentsMoved = buildTableDataFromList(myVO.getDocuments());
initTable(documentsMoved );
private Object[][] buildTableDataFromList(List<MyVO> list) {
Object[][] retorno = new Object[list.size()][COLUMNS.length];
for (int i = 0; i < list.size(); i++) {
MyVO vo = lista.get(i);
retorno[i][CHECK_COL] = Boolean.TRUE;
retorno[i][DOC_COL] = vo.getFileName();
}
return retorno;
}
It appears you are changing the dataVector of the DataModel directly. This is not the way you should be doing things. What you should do is change cell values through the interface of DataModel (using model indexes) or through the JTable interface (using view indexes).
So my advice would be to change your program to do what I just told. However if you insist on working the way you are you can signal the DataModel about changes in its underlying dataVector, if your DataModel extends DefaultTableModel which I assume it does or implements the AbstractTableModel interface. Call documents.fireTableDataChanged(); after your changes to the whole model, or more granular when changing cells using documents.fireTableCellUpdated(rowModelId,colModelId);.
Another mistake you are making is mixing up view indexes and model indexes. These can be different if rows are sorted and/or columns moved around in your table. Before indexing the model with indexes returned from the view, you should be converting these view indexes with JTable.convertRowIndexToModel and JTable.convertColumnIndexToModel.
Applying this to your selectionListener:
What you should be doing:
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
if (selectedRow >= 0) {
if (table.convertColumnIndexToModel(selectedColumn) == 0) {
Boolean valorCol = (Boolean) table.getValueAt(selectedRow,selectedColumn);
if (valorCol == true) {
table.setValueAt(Boolean.FALSE,selectedRow,selectedColumn);
}
else {
table.setValueAt(Boolean.TRUE,selectedRow,selectedColumn);
}
}
}
}
table.clearSelection();
}
});
If you insist on working the way you are:
cellSelectionModel.addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
if (e.getValueIsAdjusting()) {
int selectedRow = table.getSelectedRow();
int selectedColumn = table.getSelectedColumn();
if (selectedRow >= 0) {
int rowModelId = table.convertRowIndexToModel(selectedRow);
int colModelId = table.convertColumnIndexToModel(selectedColumn);
if (colModelId == 0) {
Boolean valorCol= (Boolean) documents[rowModelId][0];
if (valorCol== true) {
documents[rowModelId][0] = false;
}
else {
documents[rowModelId][0] = true;
}
dataModel.fireTableCellUpdated(rowModelId,0);
}
}
}
table.clearSelection();
}
});
Alas I think with your understanding of swing and JTable, there are likely more problems in your code.
I am facing the same problem mentioned here SWT: Table lost selection . I am using ubuntu 12.04 NOT windows. Is there any way to highlight the selected row of a SWT table even after focus lost. I tried adding focus listener to the table and in focus lost I changed the selected item background colour and on focus gain resets the background colour. See the code.
#Override
public void focusLost(FocusEvent e) {
System.out.println("table focus los");
TableItem item = fileListTable
.getItem(fileListTable.getSelectionIndex());
prevSelItemBackground = item.getBackground();
item.setBackground(soureWindow.getSelectionBackground());//Some random colour
System.out.println(fileListTable.getSelectionIndex());
}
#Override
public void focusGained(FocusEvent e) {
System.out.println("table focus gain");
TableItem item = fileListTable
.getItem(fileListTable.getSelectionIndex());
item.setBackground(prevSelItemBackground);
System.out.println(fileListTable.getSelectionIndex());
}
But it is not working. Is there any other solution/workaround for this?
The below snippet can be used:
this.fileListTable.addSelectionListener(new SelectionListener() {
#Override
public void widgetDefaultSelected(SelectionEvent e) {
// Nothing to do
}
#Override
public void widgetSelected(SelectionEvent e) {
int selectionIndex = fileListTable.getSelectionIndex();
TableItem[] items = fileListTable.getItems();
TableItem newItem;
for (int i = 0; i < items.length; i++) {
String first = items[i].getText(0);
String second = items[i].getText(1);
String third = items[i].getText(2);
items[i].dispose();
newItem = new TableItem(fileListTable, SWT.NONE);
newItem.setText(new String[] { first, second, third });
if (i == selectionIndex) {
newItem.setForeground(soureWindow.getSelectionForeground());//Or Anyother color
newItem.setBackground(soureWindow.getSelectionBackground());//Or Anyother color
} else {
newItem.setForeground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));//Default foreground color
newItem.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_WHITE));//Default background color
}
}
}
});
Its is working fine for me but not tested on larger data.
I have a situation where I have a popup menu created when a JTable is right clicked on. Standard way of creating the popup menu:
aJTable.setComponentPopupMenu(rightClickMenu);
Now afterwards in the action that gets registered, I am unable to find out which cell was right clicked on to get that popup menu to appear.
rightClickMenuItem.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
// Work out what cell was right clicked to generate the menu
}
});
Any ideas on how you do this?
Astonishing fact: with a componentPopupMenu installed, a mouseListener never sees the mouseEvent that is the popupTrigger (reason is that showing the componentPopup is handled globally by a AWTEventListener installed by BasicLookAndFeel, and that listener consumes the event).
The only place which sees the mousePosition of that trigger is the getPopupLocation(MouseEvent), so the only reliable way to get hold of it (for doing location dependent config/actions) is #Mad's suggestion to override that method and store the value somewhere for later use.
The snippet below uses a clientProperty as storage location:
final JTable table = new JTable(new AncientSwingTeam()) {
#Override
public Point getPopupLocation(MouseEvent event) {
setPopupTriggerLocation(event);
return super.getPopupLocation(event);
}
protected void setPopupTriggerLocation(MouseEvent event) {
putClientProperty("popupTriggerLocation",
event != null ? event.getPoint() : null);
}
};
JPopupMenu popup = new JPopupMenu();
Action action = new AbstractAction("show trigger location") {
#Override
public void actionPerformed(ActionEvent e) {
JPopupMenu parent = (JPopupMenu) SwingUtilities.getAncestorOfClass(
JPopupMenu.class, (Component) e.getSource());
JTable invoker = (JTable) parent.getInvoker();
Point p = (Point) invoker.getClientProperty("popupTriggerLocation");
String output = p != null ? "row/col: "
+ invoker.rowAtPoint(p) + "/" + invoker.columnAtPoint(p) : null;
System.out.println(output);
}
};
popup.add(action);
popup.add("dummy2");
table.setComponentPopupMenu(popup);
#MadProgrammer's suggestion of getPopupLocation looked promising, but I couldn't work out how to get the information across between the table and the actionEvent...
I got around this by making sure that the row was selected when you rightclicked on it -> since the popup menu prevents the selection of the row, you can add in a mouse listener that makes sure the row gets selected no matter what click (left or right) is pressed.
aTable.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
int r = aTable.rowAtPoint(e.getPoint());
if (r >= 0 && r < clt.getRowCount()) {
aTable.setRowSelectionInterval(r, r);
} else {
aTable.clearSelection();
}
}
});
This means that in the rightClickMenuItem's action listener, you can grab the table's selected cell / row
rightClickMenuItem.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
aTable.get details about the selected one....
}
});
Too easy! Thanks everyone for the help.
JTable has methods
int row = rowAtPoint(p);
int col = columnAtPoint(p);
So pass the MouseEvent's point and use the values
Add a MouseListener and store the last right click point somewhere.
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)
How can I find out which row in a JTable the user just clicked?
Try this:
aJTable.rowAtPoint(evt.getPoint());
If you only ever care about listening to selections on the JTable:
jTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
public void valueChanged(ListSelectionEvent e) {
int sel = jTable.getSelectedRow();
}
});