In my application I got 2 tables, table A contains optional columns for table B. It should be possible to drag "columns" (tableItem of table A) and drop them into table B. Table B should use the dragged tableItems as new columns. This works fine. Table B appends them.
Now table B should add the columns in the right order. org.eclipse.swt.dnd.DropTargetEvent knows its position (DropTargetEvent.x / y). So I have to figure out the column / columnIndex at the drop-position, so I could add the "new columns" next to column.atPoint(x,y). org.eclipse.swt.widgets.Table itself just got a method called getColumn(int index). Is there any way to figure this out?
Here is some code that will print out the column for a mouse click event. You can modify it to use the location of your drop instead of the mouse click:
public static void main(String[] args)
{
Display display = new Display();
final Shell shell = new Shell(display);
shell.setText("Stackoverflow");
shell.setLayout(new RowLayout(SWT.VERTICAL));
Table table = new Table(shell, SWT.BORDER);
table.setHeaderVisible(true);
for(int col = 0; col < 3; col++)
{
TableColumn column = new TableColumn(table, SWT.NONE);
column.setText("Col: " + col);
}
for(int row = 0; row < 20; row++)
{
TableItem item = new TableItem(table, SWT.NONE);
for(int col = 0; col < table.getColumnCount(); col++)
{
item.setText(col, row + " " + col);
}
}
for(int col = 0; col < table.getColumnCount(); col++)
{
table.getColumn(col).pack();
}
table.addListener(SWT.MouseDown, new Listener()
{
#Override
public void handleEvent(Event e)
{
Table table = (Table) e.widget;
System.out.println("Column: " + getColumn(table, e.x));
}
});
shell.pack();
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
private static int getColumn(Table table, int x)
{
int overallWidth = 0;
for(int i = 0; i < table.getColumnCount(); i++)
{
overallWidth += table.getColumn(i).getWidth();
if(x < overallWidth)
{
return i;
}
}
return -1;
}
Related
I am trying to validate that when the column step is equal to 2 the row is copied to another JTable.
But the jtable_step2 I have not initialized correctly,
that's why it returns the error:
jtable_step2.setValueAt(jtable.getValueAt(i, j), row, j);
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0 >= 0
How do I copy the same columns and rows that satisfy the condition?
Java code:
import javax.swing.JTable;
public class TestJTableCopy {
public static void main(String args[]){
String data[][]={ {"1","/LOCAL/USER/LOCAL", "20220421", "1"},
{"1","/LOACL/USER/LOCAL", "20220421", "2"},
{"1","/LOACL/USER/LOCAL", "20220422", "2"} };
String columns[] = {"LINE", "SOURCE", "DATE", "STEP"};
final JTable jtable = new JTable(data,columns);
JTable jtable_step2 = new JTable();
//jtable2.addColumn(columns);
int row = 0;
for (int i = 0; i < jtable.getRowCount(); i++) {
//STEP == 2
if (jtable.getValueAt(i, 3).equals("2")) {
for(int j = 0; j < jtable.getColumnCount(); j++) {
jtable_step2.setValueAt(jtable.getValueAt(i, j), row, j);
}
row++;
}
}
for (int i = 0; i < jtable_step2.getRowCount(); i++) {
for (int j = 0; j < jtable_step2.getColumnCount(); j++) {
System.out.println(i + " " + j + " " + jtable_step2.getValueAt(i, j));
}
}
}
}
jtable_step2.setValueAt(jtable.getValueAt(i, j), row, j);
You can't use the setValueAt(...) method because the row doesn't exist in the second table. You need to add a new row of data to the model of the table.
You do this by:
Creating a Vector, lets say "row"
Iterate through all the columns of the row you want to copy and add each item to the table
in the second table you use jtable_step2.addRow( row ) to add a new row of data to the model of the table.
I have created an excel sheet, where I am inserting the value to cell and merging cells vertically at the same time and I am able to achieve that but the problem is that, I am not able to align text vertically center in the merged cell.Currently, text is showing at the bottom of vertically merged cell.
here's my code,
CellStyle cs = null;
cs = wb.createCellStyle();
cs.setWrapText(true);
//cs.setAlignment(CellStyle.ALIGN_CENTER);
cs.setVerticalAlignment(CellStyle.VERTICAL_CENTER);
cs.setFont(f);
Row row[]=new Row[pageListAcrToDept.size()];
for (int i = 0; i < pageListAcrToDept.size(); i++) {
rowIndex = 8 + i ;
row[i]=sheet.createRow(rowIndex);
}
List<List<String>> datas=new ArrayList<>();
datas.add(pageListAcrToDept);
datas.add(notesListAcrToDept);
datas.add(treatmentListAcrToDept);
datas.add(upcListAcrToDept);
datas.add(itemCodeListAcrToDept);
datas.add(descListAcrToDept);
datas.add(subDeptListAcrToDept);
datas.add(limitListAcrToDept);
datas.add(XforListAcrToDept);
datas.add(priceListAcrToDept);
datas.add(couponListAcrToDept);
datas.add(adzoneListAcrToDept);
datas.add(promoDescListAcrToDept);
for (int column = 0; column < 13; column++) {
List <String> list=datas.get(column);
int index=0;
for (int i = 0, prev = -1; i < list.size(); i++) {
if (i == list.size() - 1 || ! list.get(i).equals(list.get(i + 1))) {
//System.out.printf("number: %d, count: %d%n", list.get(i), i - prev);
for(int pos=0;pos<i - prev;pos++){
int posi=index+pos;
Cell cell= row[posi].createCell(column);
cell.setCellStyle((CellStyle) cs);
cell.setCellValue(list.get(i));
}
int startrowpos=index+8;
int endrowpos=index+8+(i - prev)-1;
if(startrowpos==endrowpos){
LOG.info("don't merge");
}else{
CellRangeAddress cellRangeAddress = new CellRangeAddress(startrowpos, endrowpos,
column, column);
sheet.addMergedRegion(cellRangeAddress);
}
index=index+(i - prev);
prev = i;
}
}
}
Finally, I resolved this problem. I am posting here the changes,because it may help other.
for (int column = 0; column < 13; column++) {
List <String> list=datas.get(column);
int index=0;
for (int i = 0, prev = -1; i < list.size(); i++) {
if (i == list.size() - 1 || ! list.get(i).equals(list.get(i + 1))) {
//System.out.printf("number: %d, count: %d%n", list.get(i), i - prev);
int posi=0;
for(int pos=0;pos<i - prev;pos++){
if(pos==0){
posi=index+pos;
}
}
int startrowpos=index+8;
int endrowpos=index+8+(i - prev)-1;
if(startrowpos==endrowpos){
LOG.info("don't merge");
Cell cell= row[posi].createCell(column);
cell.setCellStyle((CellStyle) cs);
cell.setCellValue(list.get(i));
}else{
CellRangeAddress cellRangeAddress = new CellRangeAddress(startrowpos, endrowpos,
column, column);
sheet.addMergedRegion(cellRangeAddress);
Cell cell= row[posi].createCell(column);
cell.setCellStyle((CellStyle) cs);
cell.setCellValue(list.get(i));
}
index=index+(i - prev);
prev = i;
}
}
}
I have a JTable with 2 coloumns, one column is object type, second column is checkbox. In that table user want to select only a single checkbox. I am tried many codes (Examples : jtable checkbox single selection and Second one), finally i done this by using function.
Here is my function:
public void setSelectionEnableOrDisable(JTable table) {
int earlierSelectionRow = 0;
int selectedRow = table.getSelectedRow();
for (int i = 0; i < table.getRowCount(); i++) {
if ((Boolean) table.getValueAt(i, 1) == true && i != selectedRow) {
earlierSelectionRow = i;
}
}
table.setValueAt(true, selectedRow, 1);
table.setValueAt(true, earlierSelectionRow, 1);
}
But, whats the problem with this one is, when i clicking the checbox slowly it's fine. if i am clicking fastly 2 or 3 checkboxes then my code allows to multi selection. What's wrong here?.
I think you can do it simpler, like:
public void setSelectionEnableOrDisable(JTable table) {
int selectedRow = table.getSelectedRow();
if ((Boolean)table.getValueAt(selectedRow , 1)) {
for (int i = 0; i < table.getRowCount(); i++) {
if ( i != selectedRow) {
table.setValueAt(false, i, 1);
}
}
}
http://git.eclipse.org/c/platform/eclipse.platform.swt.git/tree/examples/org.eclipse.swt.snippets/src/org/eclipse/swt/snippets/Snippet2.java
I am trying in SWT to add sorting to a table widget. Copying the code from Snippet2 sortListener Handler doesn't work. It correctly swaps two items into sorted order. More than 2 items in the table, and the results are unpredictable.
It seems to me (in the following code extract from Snippet2 sortListener) that items[i].dispose() is going to change the array of TableItems called items that we are iterating over in the outer for loop, for (int i = 1 ...... Also, when one item is disposed(), and inserted into items at a new index, the whole array is recreated afresh. That surely breaks the iteration?
So, I guess I have two questions:
What am I not understanding about Snippet2's algorithm?
Is there any other obvious reason why a sort operation might return random results (bearing in mind I am a noob, so am likely to have made the stupidest of mistakes)?
Here is my code:
Listener sortListener = new Listener() {
public void handleEvent(Event e) {
TableItem[] items = table.getItems();
Collator collator = Collator.getInstance(Locale.getDefault());
TableColumn column = (TableColumn)e.widget;
int index = column == column1 ? 0 : 1;
for (int i = 1; i < items.length; i++) { <--------- HERE
String value1 = items[i].getText(index);
for (int j = 0; j < i; j++){
String value2 = items[j].getText(index);
if (collator.compare(value1, value2) < 0) {
String[] values = {items[i].getText(0), items[i].getText(1)};
items[i].dispose(); <--------- HERE
TableItem item = new TableItem(table, SWT.NONE, j);
item.setText(values);
items = table.getItems(); <--------- HERE
break;
}
}
}
table.setSortColumn(column);
}
};
This code snippet works for any number of items in the table (I tested it).
But it works only for 2 columns. (Is that your problem?)
If you have more columns in the table, the code would look like this:
Listener sortListener = new Listener() {
public void handleEvent(Event e) {
TableItem[] items = table.getItems();
Collator collator = Collator.getInstance(Locale.getDefault());
TableColumn column = (TableColumn)e.widget;
int index = table.indexOf(column);
for (int i = 1; i < items.length; i++) { // <--------- HERE
String value1 = items[i].getText(index);
for (int j = 0; j < i; j++){
String value2 = items[j].getText(index);
if (collator.compare(value1, value2) < 0) {
String[] values = new String[table.getColumnCount()];
for (int columnIdx = 0; columnIdx < table.getColumnCount();
columnIdx++){
values[columnIdx] = items[i].getText(columnIdx);
}
items[i].dispose(); // <--------- HERE
TableItem item = new TableItem(table, SWT.NONE, j);
item.setText(values);
items = table.getItems(); // <--------- HERE
break;
}
}
}
table.setSortColumn(column);
}
};
You may want to use JFace wrapper for SWT table (org.eclipse.jface.viewers.TableViewer), which gives your table more built in features. I suggest this tutorial for JFace TableViewer. Here is tutorial for sorting TableViewer.
I would like to get the value from the Jtable, and I tried it using the getvalueat however whenever I try to get the value from the JTable it only get the value from the first column of the selected row, I need to get all the value from the Jtable which I selected. Can you please help me with this one
here is my code:
class GetTableValue implements ActionListener{
public void actionPerformed(ActionEvent e){
AbstractButton button = (AbstractButton)e.getSource();
if(e.getActionCommand().equals(button.getActionCommand)){
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
Object data = (Object)table.getValueAt(row, col);
JOptionPane.showMessageDialog(null, data);
}
}
}
This is my action event where the value of the selected table is shown in the JOptionPane unfortunately it only display one value(which is the one you already selected) not the whole row.
This code is for my Jbutton for call the action event(I already excluded my code from the JTable since it fetch the Jtable value from my database)
ActionListener tableAction = new GetTableValue();
buttonEdit = new JButton("EDIT");
buttonEdit.addActionListener(tableAction);
the code is plain and simple, I also search Mr. G(google) about a good tutorial on fetching row, unfortunately there isn't a good tutorial for fetching Jtable value(per row).
If you want all the values from selected row then try this code.
int row = jTable1.getSelectedRow();
int column = jTable1.getColumnCount();
for(int i = 0; i < column; i++) {
System.out.println(jTable1.getValueAt(row, i));
}
You get the all values for selected row, no matter how much columns are there in jtable
If you want all the values from jtable then try:
int row = jTable1.getRowCount();
int column = jTable1.getColumnCount();
for (int j = 0; j < row; j++) {
for (int i = 0; i < column; i++) {
System.out.println(jTable1.getValueAt(j, i));
}
}
Yes you can use Object[] to store the values. For example:
Object[] val = new Object[column];
for (int k = 0; k < val.length - 1; k++) {
for (int j = 0; j < row; j++) {
for (int i = 0; i < column; i++) {
val[k] = jTable1.getValueAt(j, i);
System.out.println(val[k]);
}
}
}
getValueAt will return you the value of the cell (at row/col). Unless you're table model supports it, there is no convenient way (beyond what you are doing) to get the whole row in a single request.
Also, remember, if the table is sorted or filtered, the model indices will not match the view, you need to convert them first, using convertRowIndexToModel and convertColumnIndexToModel
UPDATE
The only way around it is if the table model you're using has a getRow (or equivalent) method. Without know how you are storing the data in the table model it's next to near impossible to give an accurate answer, but a general idea would be...
public class MyAwesomeTableModel extends AbstractTableModel {
// All the usual stuff...
public MyRowData getRowAt(int index) { ... }
}
Now, MyRowData is what ever implementation of the table data you've created. It could be (preferably) a single Object or in the case of the DefaultTableModel an array of objects.
class GetTableValue implements ActionListener{
public void actionPerformed(ActionEvent e){
AbstractButton button = (AbstractButton)e.getSource();
if(e.getActionCommand().equals(button.getActionCommand)){
int row = table.convertRowIndexToModel(table.getSelectedRow());
MyAwesomeTableModel model = (MyAwesomeTableModel)table.getModel();
MyRowData data = model.getRowAt(row);
JOptionPane.showMessageDialog(null, data);
}
}
}
This is all dependent on how you've implemented your TableModel and how you've implemented your row data, but that's the general jist
private void jTable1MousePressed(java.awt.event.MouseEvent evt) {
int selectedRow;
ListSelectionModel rowSM = jTable1.getSelectionModel();
rowSM.addListSelectionListener(new ListSelectionListener()
{
#Override
public void valueChanged(ListSelectionEvent e)
{
ListSelectionModel lsm = (ListSelectionModel) e.getSource();
selectedRow = lsm.getMinSelectionIndex();
int numCols = jTable1.getColumnCount();
model = (DefaultTableModel) jTable1.getModel();
System.out.print(" \n row " + selectedRow + ":");
for (int j = 0; j < numCols; j++)
{
System.out.print(" " + model.getValueAt(selectedRow, j));
}
}
});
}
Using this you can get value of whole row where u click on particular row.
you can try the below code to get selected row value:
int selectedRow = jTableName.getSelectedRow();
selectedRow = jTableName.convertRowIndexToModel(selectedRow);
String val1 = (String)jTableName.getModel().getValueAt(selectedRow, 0);
String val2 = (String)jTableName.getModel().getValueAt(selectedRow, 1);