I currently have a populated SWT table with the following styles:
SWT.BORDER | SWT.FULL_SELECTION | SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
used SWT.FULL_SELECTION to get the whole line selected if clicked.
but using table.getSelection() only returns the first column.
I don't have any tableviewer or something else set.
where did I make a mistake?
edit:
example:
if (table.getSelectionCount() > 0) {
for (TableItem item : table.getSelection()) {
System.out.println(item);
}
}
this returns only the first column
Since you are only calling System.out.println() on the whole TableItem, Java will internally use TableItem#toString() to convert it to a String.
The resulting string however, will not contain all the data of the TableItem.
Instead, you'll need to iterate over the columns to get the data using TableItem#getText(int column):
for(int i = 0; i < table.getColumnCount(); i++)
System.out.println(item.getText(i));
Related
I create a simple JTable with TableModel, and I hidden the first column.
I set at my JTable also the TableRowSorter
This is the code that I use to create a table
tableModelArticoliVendere = new MyTableModelDescrizioneArticoli();
tableArticoliVendere = new CustomTableArticoliDaVendereBar(tableModelArticoliVendere);
sorter = new TableRowSorter<MyTableModelDescrizioneArticoli>(tableModelArticoliVendere);
tableArticoliVendere.setRowSorter(sorter);
tableArticoliVendere.addMouseListener(new MyMouseAdapterArticoliDaVendere());
tableArticoliVendere.removeColumn(tableArticoliVendere.getColumnModel().getColumn(0));
If the user click on the one row of the table the mouse listenere are called.
This is the method:
public class MyMouseAdapterArticoliDaVendere extends MouseAdapter {
public void mouseClicked(MouseEvent me) {
JTable t = (JTable)me.getSource();
if (me.getClickCount() == 1) {
String codiceArticolo =((JTable)tableArticoliVendere).getModel().getValueAt(t.getSelectedRow(), 0).toString();
inserisciProdotto(codiceArticolo);
}
}
}
The problem is this:
If I see the complete table and I clik on the one of the row table, I read the codiceArticolo right. If I use the row filter, and I try to click on the first row I have an error.
I have the table with 3 row for example:
TABLE
column 0| column 1
------------------
valore1 | 1
valore2 | 2
valore3 | 3
If I use the filter I have this situation:
TABLE
column 0| column 1
------------------
valore2 | 2
valore3 | 3
if I try to click on the first row, the value of codiceArticolo is valore1 and not valore2.
If I not hidden the column 0, I don't have this error.
When you have sorting or filtering enabled in your table, the indexes of table rows and columns stop lining up with indexes of the model rows and columns. You can account for this using convertRowIndexToModel and convertColumnIndexToModel.
For instance, when you use t.getSelectedRow(), you can adjust like this:
int tableRowIndex = t.getSelectedRow();
int modelRowIndex = t.convertRowIndexToModel(tableRowIndex);
It will also help if you indicate in your code when you are using view indexes and when you are using model indexes.
I couldn't find any answers for this special case (using CheckboxTableViewer), so I hope it's not a duplicate.
I have the following createPartControl() in an Eclipse view (3.x).
I'm trying to display two buttons and a checkable table in a GridLayout, as below
-------------------
| Button | Button |
-------------------
| Table |
-------------------
Nothing spectacular. Everything is displayed fine so far. My table is embedded within a CheckboxTableViewer, has a single column and sometimes the content (String) is longer than the column width. So I'm trying to make the Table (got via viewer.getTable(), not explicitly constructed!) scrollable to make all content available. This doesn't work and I cannot understand why.
I have played around with SWT style bits (SWT.H_SCROLL, SWT.V_SCROLL), I've tried a ScrollableComponent, but to no avail. I couldn't get the ScrolledComponent to work because I'm not constructing my table explicitly, and thus couldn't setContents() properly.
Below is the gist of my createPartControl().
public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout(2, false));
addSelectionButtons(parent); // Works
myTableViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER);
myTableViewer.getTable().setLayoutData(new GridData(SWT.FILL, SWT.CENTER, true, false, 2, 1));
Table myTable = (Table) myTableViewer.getControl();
TableLayout tableLayout = new TableLayout();
tableLayout.addColumnData(new ColumnWeightData(100, 50, true));
myTable.setLayout(tableLayout);
myTableViewer.setContentProvider(new MyContentProvider());
TableViewerColumn viewerCol = new TableViewerColumn(myTableViewer, SWT.LEFT);
TableColumn col = viewerCol.getColumn();
col.setText("My column");
viewerCol.setLabelProvider(new ColumnLabelProvider() {
#Override
public String getText(Object element) {
return text; // Dummy var
}
});
myTableViewer.setInput(getInput()); // Gets model
myTableViewer.getTable().setHeaderVisible(true);
myTableViewer.getTable().setLinesVisible(true);
}
I know this is borderline "give me teh codez", but I really cannot find the issue with this setup.
I've managed to solve this issue by going back to square one and re-implementing in the most generic fashion I could find documented. I.e.:
I've added a proper LabelProvider (and got rid of the ColumnLabelProvider),
set a simple GridData layout data object to the table (and otherwise haven't messed with it),
and simplified the TableColumn section a lot (despite having only one column in the table, I still need to declare a TableColumn to be able to set a column heading). Note: The TableColumn must be pack()ed, otherwise the content doesn't show. From the TableColumn API: "Causes the receiver to be resized to its preferred size."
Simple and working.
public void createPartControl(Composite parent) {
parent.setLayout(new GridLayout(1, true));
addSelectionButtons(parent); // Adds select/deselect all buttons
myTableViewer = CheckboxTableViewer.newCheckList(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL);
myTableViewer.getTable().setLayoutData(new GridData(GridData.FILL_BOTH));
myTableViewer.setContentProvider(new MyContentProvider());
myTableViewer.setLabelProvider(new MyLabelProvider());
myTableViewer.setInput(getInput()); // Gets model
TableColumn column = new TableColumn(myTableViewer.getTable(), SWT.FILL);
column.setText("My column");
column.pack();
myTableViewer.getTable().setHeaderVisible(true);
myTableViewer.getTable().setLinesVisible(true);
}
I am trying to add an action to a menu to the header (titles) of a TableViewer.
This is the code that I am using now:
viewer = new TableViewer(parent, SWT.MULTI | SWT.H_SCROLL | SWT.V_SCROLL
| SWT.FULL_SELECTION | SWT.BORDER);
//...
MenuManager manager = new MenuManager();
viewer.getControl().setMenu(manager.createContextMenu(viewer.getControl()));
manager.add(new Action("MENU ITEM TEXT") {
#Override
public void run() {
// get the current selection of the tableviewer
IStructuredSelection selection = (IStructuredSelection) viewer.getSelection();
// do something
if (selection.getFirstElement() instanceof MyObject)
return;
System.out.println("OK: "+selection.getFirstElement().getClass().getName());
}
});
And this is how it looks:
The problem is that the menu gets added to the entire TableViewer, not only to the header row.
Because for the other rows I will need to use a different menu.
I have tryied to find a way of adding the action only to the top row (the titles row), but with no success so far.
So how can I add the menu only for the header?
You add a MouseListener to the table, and you check for the following things:
Clicked button is mouse right-click.
The pointer of the event is located within the bounds of your table item (i.e. your first TableItem - you will use table.getItem(Point)).
If these conditions are met, you open the menu at mouse location.
Actually, here's a snippet of how this can be done.
This maybe a really silly question but I just could not find the answer anywhere, is there any way for the user to be able to highlight rows in an SWT Table and either ctrl+c or right-click+c to copy the values?
I would specifically like to be able to copy into an excel sheet.
This is how I create the table,
Table aTable = new Table(parent, SWT.SINGLE | SWT.BORDER
| SWT.FULL_SELECTION);
aTable.setHeaderVisible(true);
aTable.setLinesVisible(true);
aTable.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
I have seen information about this using a JTable but nothing with an SWT. If JTable is my only option, then what would be the dis/advantages of using either?
You can easily code it.
Add a key listener to your table and listen for Ctrl+C keys. When Ctrl+C is hit, get the selection from the table, extract text from each of the TableItems and form a tab-separated-fields/newline-separated-rows String containing your data. Then just put it into clipboard (see org.eclipse.swt.dnd.Clipboard#setContents, use TextTransfer data type).
That is it - your result will be pasteable into Excel.
The accepted answer is good, but since developers prefer code snippets over text I'd answer the question this way:
aTable.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
if (e.stateMask == SWT.CTRL && (e.keyCode == 'c' || e.keyCode == 'C')) {
Clipboard clipboard = new Clipboard(Display.getDefault());
clipboard.setContents(new Object[] { getTextFromSelectedRows() }, new Transfer[] { TextTransfer.getInstance() });
clipboard.dispose();
}
}
});
Then just implement a getTextFromSelectedRows()-Method that - based on the table selection - returns the String that should be added to the clipboard.
I have a simple Swing JTable and a TableRowSorter made by me. However, I would exclude the first column from the sorting, as I want to keep it to show row numbers.
I can't see to find anything, except
sorter.setSortable(0, false);
Which makes the column not clickable, but still sortable when another column is clicked...
So quick question will be: how to keep a column from being sorter by a TableRowSorter?
Thank you!
So, with a JTable (ex below) sorting on column A would produce the following. However, you want the data to sort, but not the row numbers, correct?
|row| column A | |row| column A |
+---+-----------+ +---+-----------+
| 1 | blah blah | --> | 1 | blah blah |
| 2 | something | | 3 | more blah |
| 3 | more blah | | 2 | something |
I would approach this with a TableCellRenderer for column 0. The trick is to ignore the value passed and instead use the row parameter.
public class RowRenderer extends JLabel implements TableCellRenderer {
public Component getTableCellRendererComponent(JTable table, Object color,
boolean isSelected, boolean hasFocus, int row, int column) {
setText(Integer.toString(row));
return this;
}
}
Note: if you are paginating your table (ie the model does not contain all of the rows; for example only rows 100-200) you will need to advise the cell renderer of the amount to add to row to obtain the row number to display.
A JTable is designed around displaying rows of data, not cells of data, so it isn't really possible to prevent an individual column from sorting, as you put it. Instead I would try modifying your TableModel to return the row index for the value for that column:
#Override public Object getValueAt(int rowIndex, int columnIndex) {
if (columnIndex == 0) return rowIndex;
else {
// handle other columns
}
}
If that doesn't work you could also try modifying the table cell renderer to use the table row index instead.
If the row number isn't part of the data, then it should not be stored in the model.
Instead I would use a row header that displays a row number. Something like you would see in Excel. You can use the Row Number Table for this.