how to select one cell from SWT table - java

table.addSelectionListener(new SelectionAdapter()
{
public void widgetSelected(SelectionEvent e)
{
if(table.getSelectionIndex() != -1)
{
System.out.println(table.getSelectionIndex());
TableItem item = table.getItem(table.getSelectionIndex());
System.out.println(item.toString());
}
else
{}
}
});
when i click on any cell in my table, only the first cell of that row is selected and returned and not exactly that cell
please tell me how can i select and get item from exactly that cell which i select
please see the image
i have selected 3rd column but it returned the TableItem of first column

I encountered the same problem before, and this is how I solved it:
First, you should make the table SWT.FULL_SELECTION`;
Then, you have to get the selected cell by reading the mouse position (because the basic swt table does not provide listeners to get selected cell; select a item is possible). Here is the code:
table.addListener(SWT.MouseDown, new Listener(){
public void handleEvent(Event event){
Point pt = new Point(event.x, event.y);
TableItem item = table.getItem(pt);
if(item != null) {
for (int col = 0; col < table.getColumnCount(); col++) {
Rectangle rect = item.getBounds(col);
if (rect.contains(pt)) {
System.out.println("item clicked.");
System.out.println("column is " + col);
}
}
}
}
});

I was facing a similar problem with nebula grid and found out that you have to enable cell selection on the table object. Here is my code line:
tableViewer.getGrid().setCellSelectionEnabled(true);
Perhaps it you could try to replace getGrid() by getTable(). You will not need to implement the selection listener for this.

Related

How to detect a selection on JavaFX TableView when clicking a highlighted item?

I need a way to get the user selection every time a user selects an item on a TableView, even if the item is already selected.
The tableView.getSelectionModel().selectedItemProperty().addListener works when the user selects a different item from the one highlighted, but if the user selects the highlighted item again, it doesn't seem to work.
How would this be fixed?
you can do this:
tableView.setOnMouseClicked((MouseEvent event) -> {
if(event.getButton().equals(MouseButton.PRIMARY)){
System.out.println(tableView.getSelectionModel().getSelectedItem());
}
});
the code above doesn't work if you select the highlighted item again using editable table cell
If you're only interested in the clicks on the rows, use a custom rowFactory:
TableView<Item> table = ...
EventHandler<MouseEvent> clickListener = evt -> {
TableRow<Item> row = (TableRow<Item>) evt.getTarget();
if (!row.isEmpty()) {
// do something for non-empty rows
System.out.println("you clicked " + row.getItem());
}
};
table.setRowFactory(tv -> {
TableRow<Item> row = new TableRow<>();
// add click listener to row
row.setOnMouseClicked(clickListener);
return row;
});
The simplest way what i know:
yourTableView.setOnMousePressed(e ->{
if (e.getClickCount() == 2 && e.isPrimaryButtonDown() ){
int index = yourTableView.getSelectionModel().getSelectedIndex();
System.out.println("" + index);
}
});
put it in to constructor or initialize method in your corntroller class... :)

Updating checkboxes in Jtable goes into recursion, causes stack overflow error

I have a Jtable set up in a tabbed pane that is filled with an id and checkboxes. The table looks something along the lines of this, where . are the checkboxes.
| VAR1 |
ID | ALL | subVar1 | subVar2 |
------------------------------
id1| . | . | . |
Now, I also have a TableListener attached to this table. What I would like to happen is that, whenever a user presses the ALL checkbox, all the checkboxes in that row need to be selected (ie true). This is the table listener code.
#Override
public void tableChanged(TableModelEvent e) {
if(e.getSource() == assignedTableModel) {
for (int i = 0; i < aTable.getRowCount(); i++) {
boolean isAllChecked = (Boolean) aTable.getValueAt(i, 1);
if(isAllChecked) {
assignedTableModel.setValueAt(Boolean.TRUE, i, j);
}
else {
...
}
}
}
}
Clicking the ALL checkbox causing the table to change, assignedTableModel.setValueAt(Boolean.TRUE, i, j); is called, the table is changed again and therefore calls the listener, which calls this function again.
My question, is there another way of updating the checkboxes? Or is there a way to set a base to get out of the recursion?
EDIT The rows are added dynamically. I'm wondering if adding an actionListener to the ALL checkbox as it's being added will be a solution. I'll come back with how it turns out.
EDIT2 I'd forgot to mention that the whole table is generated dynamically. That means I have no way of knowing how many columns and rows will be present, the only columns I know are ID and the ALL col. Most answers already present deal with hard coded implementations.
whenever a user presses the ALL checkbox, all the checkboxes in that row are selected
So why are you looping through all the rows in your code? The event will be generated only for the row you click and you only need to select the check marks for the columns on that row. Get rid of the looping code.
the table is changed again and therefore calls the listener, which calls this function again.
You need an if condition to identify when the check box in the first column is checked:
if (e.getType() == TableModelEvent.UPDATE)
{
int row = e.getFirstRow();
int column = e.getColumn();
if (column == 0)
{
TableModel model = (TableModel)e.getSource();
model.setValueAt(Boolean.true, row, 1);
...
}
}
Now the change of state on the other columns will be ignored.
Based off of #camickr's response, the following piece of code seems to be doing the trick. Thanks.
#Override
public void tableChanged(TableModelEvent e) {
if (e.getType() == TableModelEvent.UPDATE && e.getSource() == assignedTableModel)
{
int row = e.getFirstRow();
int column = e.getColumn();
if (column == 1)
{
DefaultTableModel model = (DefaultTableModel) e.getSource();
for(int i=2 ; i<model.getColumnCount() ; i++) {
if((boolean) model.getValueAt(row, 1))
model.setValueAt(Boolean.TRUE, row, i);
else
model.setValueAt(Boolean.FALSE, row, i);
}
}
}
}

Multiple selection and JPopupMenu on right click

I am having problems with a popup menu on a JTable and the fact that this JTable allows for Multiple Interval Selection.
I'm going to explain in detail my situation, making it as clear as possible, hopefully.
I have a basic data class, lets call it Item, with a string id (name) and two boolean fields, online and active (with relative getters).
The idea behind the JTable is that, for each item in the dataset, it will show its name in the first colum and its status in the second column, where by 'status' I mean that, it will show "ACTIVE/NOT ACTIVE" if the Item is Online, otherwise it will show "OFFLINE".
I have implemented a TableModel that does the job and it works.
I also want, when the user right clicks on a row, a popup to appear (if the selected Item is ONLINE) allowing to Activate/Deactivate the item, depending on its status.
This worked perfectly as long as the Selection Model was SINGLE SELECTION, but when I changed it to MULTIPLE INTERVALS SELECTION, I could not make it work properly anymore.
The behaviour that I want is that, on right-click, a popup appears where the click is performed, the row is added to the selection and highlighted and all the previously selected rows stay selected! This I cannot manage to do!
Here is the code I have in the MouseListener:
tblModel.addMouseListener(new MouseAdapter() {
void showPopup(MouseEvent e){
int r = tblModel.rowAtPoint(e.getPoint());
if (r >= 0 && r < tblModel.getRowCount()) {
//tblModel.setRowSelectionInterval(r, r);
} else {
tblModel.clearSelection();
}
int[] viewRowIndexes = tblModel.getSelectedRows();
int rowViewIndex = tblModel.getSelectedRow();
if (rowViewIndex < 0)
return;
int rowModelIndex = tblModel.convertRowIndexToModel(rowViewIndex);
if (e.isPopupTrigger() && e.getComponent() instanceof JTable) {
Action changeActiveAction;
Action changeInactiveAction;
List<String> actives = new ArrayList<String>();
List<String> inactives = new ArrayList<String>();
DefaultListSelectionModel selectionModel = (DefaultListSelectionModel) tblModel.getSelectionModel();
for (int viewRowIndex : viewRowIndexes) {
int modelRowIndex = tblModel.convertRowIndexToModel(viewRowIndex);
if (selectionModel.isSelectedIndex(viewRowIndex)) {
boolean online = ((MyTableModel) tblModel.getModel()).isItemOnline(modelRowIndex);
if (!online)
continue;
boolean active = ((MyTableModel) tblModel.getModel()).isItemActive(modelRowIndex);
String idItem = (String) ((MyTableModel) tblModel.getModel()).getValueAt(modelRowIndex,0);
if (active) {
actives.add(idItem);
} else {
inactives.add(idItem);
}
}
}
if (actives.size() > 0 || inactives.size() > 0) {
popup = new JPopupMenu();
if (actives.size() > 0) {
changeActiveAction = new ChangeAction("Deactivate ACTIVE Items","This will deactivate all the selected ACTIVE items",actives, false);
popup.add(new JMenuItem(changeActiveAction));
}
if (inactives.size() > 0) {
changeInactiveAction = new ChangeAction("Activate INACTIVE Items","This will activate all the selected INACTIVE items",inactives, true);
popup.add(new JMenuItem(changeInactiveAction));
}
popup.show(e.getComponent(), e.getX(),e.getY());
}
}
}
#Override
public void mousePressed(MouseEvent e) {
showPopup(e);
}
#Override
public void mouseReleased(MouseEvent e) {
showPopup(e);
}
};
The behaviour is functionally correct, but the selection of rows is not working.
Having commented the line
//tblModel.setRowSelectionInterval(r, r);
when I right-click on a row, a popup appears, but it ignores the row on which I clicked.
On the other hand, if uncommented, that line will select only the clicked row, losing all the rest of the selection....
I am sorry for the long post, but I didn't know how to explain my problem without giving all the details of my situation....
Hopefully this is a trivial thing and you can tell me how I can fix/change it.
Thank you in advance.
One part of the answer is:
if (tblModel.isSelectedIndex(r)) {
tblModel.removeSelectionInterval(r, r);
} else {
tblModel.addSelectionInterval(r, r);
}

How to add tooltips to JTable's rows

how can I add tooltips to JTable's rows (Java Swing)?
These tooltips should contain same values of the relative row.
This is the code I used in my class that extends JTable. It overrides the method "prepareRenderer", but I got empty cells, and it adds a tooltip for each single cell within row, not one tooltip for the whole row (that is what I'm looking for):
public Component prepareRenderer(TableCellRenderer renderer,int row, int col) {
Component comp = super.prepareRenderer(renderer, row, col);
JComponent jcomp = (JComponent)comp;
if (comp == jcomp) {
jcomp.setToolTipText((String)getValueAt(row, col));
}
return comp;
}
it adds a tooltip for each single cell within row, not one tooltip for the whole row
You are changing the tooltip depending on the row and column. If you only want the tooltip to change by row, then I would only check the row value and forget about the column value.
Another way to set the tooltip is to override the getToolTipText(MouseEvent) method of JTable. Then you can use the rowAtPoint(...) method of the table to get the row and then return the appropriate tool tip for the row.
Just use below code while creation of JTable object.
JTable auditTable = new JTable(){
//Implement table cell tool tips.
public String getToolTipText(MouseEvent e) {
String tip = null;
java.awt.Point p = e.getPoint();
int rowIndex = rowAtPoint(p);
int colIndex = columnAtPoint(p);
try {
//comment row, exclude heading
if(rowIndex != 0){
tip = getValueAt(rowIndex, colIndex).toString();
}
} catch (RuntimeException e1) {
//catch null pointer exception if mouse is over an empty line
}
return tip;
}
};
see JComponent.setToolTipText() -- the JComponent you want on per-row data is not the table, but rather the cell renderer of the data, which has access to configuring a JComponent for each rendered cell.
rowIndex can be ZERO.
change:
if(rowIndex != 0){
tip = getValueAt(rowIndex, colIndex).toString();
}
by:
if(rowIndex >= 0){
tip = getValueAt(rowIndex, colIndex).toString();
}

How to add a type of listener to a JTable (Java)?

I have a column with plain text in it.
If the user double-clicks a row in that column, the column allows itself to be edited for that row (as it should).
I need something to detect when that text is done with being edited (when the user hits the enter key, for example). When that happens, I need something to get the row ID of that change (0-based of course).
Any ideas?
Thanks!
You should add a listener to the TableModel:
table.getModel().addTableModelListener(new TableModelListener() {
public void tableChanged(TableModelEvent e) {
// your code goes here;
}
});
TableModelEvent contains row and column number and type of modification.
I think the easiest way to get the location of the click in terms of row and column would be this:
table.addMouseListener(new java.awt.event.MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent e) {
int row = table.rowAtPoint(e.getPoint());
int column = table.columnAtPoint(e.getPoint());
if (row >= 0 && column >= 0) {
......
}
}
});

Categories

Resources