Set order of columns in JTable - java

I have a JTable with some columns. I have a HashMap of the column identifier mapped to the position in the view, for example:
TableHeader1 | TableHeader2 | TableHeader3
sth. sth. sth.
I know that:
TableHeader1 -> position 0
TableHeader2 -> position 1
TableHeader3 -> position 2
Now I want to reorder the columns. I know that there is a function called moveColumn(A, B) within the JTable class. This moves a column from A to B, and B is putted left or right.
My problem is, I want to order the whole table in a specific way, how can I do this?
If I use moveColumn, I cannot know where B has been moved, in 5 out of 10 cases it might be the right side and in the other cases the wrong side.
Hope you understand my problem :-)

You can change the columns order by removing all of them and adding them in the right order:
public static void setColumnOrder(int[] indices, TableColumnModel columnModel) {
TableColumn column[] = new TableColumn[indices.length];
for (int i = 0; i < column.length; i++) {
column[i] = columnModel.getColumn(indices[i]);
}
while (columnModel.getColumnCount() > 0) {
columnModel.removeColumn(columnModel.getColumn(0));
}
for (int i = 0; i < column.length; i++) {
columnModel.addColumn(column[i]);
}
}

OK how about this. Might be a bit left field.
Extend TableColumn and give your new class a position property. Have it implement Comparable and use the position to compare columns.
Next, extend DefaultTableColumnModel and store TableColumns in an ordered list.
Your JTable should now display columns according to their position. Untested but it sounds interesting so I might give it a go later.

Based on #Guillaume answer I found a way to do that without the need to remove all columns and add them again.
public static void setColumnOrder(int[] indices, JTable table, TableColumnModel columnModel) {
for (int i = 0; i < indices.length; i++) {
columnModel.moveColumn(i, table.convertColumnIndexToView(indices[i]));
}
}
This works better for me because with (SwingX) JXTable, the order of the invisible columns is not modified.

If you want to reorder by column name then you can check out the Table Column Reordering suggestion.

This problem can be solved by using the built in moveColumn function as a bubble sort shortcut. The hashmap holds your weights in that case. Keep in mind that getColumnModel().getColumn(j).getModelIndex() can be seen as the initial column index / ID that will not change. See it as a column title.
HashMap<int, int> mapOrder = new HashMap<int, int>();
for (int i = 0; i < jt_table.getColumnCount(); i++) {
for (int j = 0; j < jt_table.getColumnCount() - 1; j++) {
int col1 = mapOrder.get(jt_table.getColumnModel().getColumn(j).getModelIndex());
int col2 = mapOrder.get(jt_table.getColumnModel().getColumn(j + 1).getModelIndex());
if (col1 > col2) {
jt_table.moveColumn(jt_table.getColumnModel().getColumn(j).getModelIndex(), jt_table.getColumnModel().getColumn(j + 1).getModelIndex());
}
}
}

Related

Optimization of deletion nodes in 2-d array

I have double dimensional array of dimensions 720x90. Let's denote rows by R and C as columns.
R1 = {C1,...,C90}
....
R720 = {C1,...C90}
Now, I want to see if any of the data in any of the rows appears anywhere else in any other rows. For instance, lets say the data in row 470 and column 67 is a duplicate of row 672 and column 34. In that case, I want to remove both row 470 and row 672 from the data set and continue checking. After I have checked all the rows, I want to print just the index of the rows that have survived. I have written a brute-force method of this. However, when I run this code, it never returns and I am not able to diagnose why. Also, is there a more efficient way to do this?
//check all the subsets of the interleaved data
public static int checkSubsets(String[][] subsets){
List subset = new ArrayList();
for(int i = 0; i< 720; i++){
for(int j = 0; j < 90; j++)
subset.add(subsets[i][j]);
}
Object duplicate;
Iterator itr = subset.iterator();
while(itr.hasNext()){
duplicate = itr.next();
while(itr.hasNext()){
subset.remove(duplicate);
itr=subset.iterator(); //to avoid concurrent modification
itr.next();
}
}
return subset.size();
}
Clarifications: Lets say I am iterating through looking at each value in the matrix. I take the first value in R1 C1 (row 1 - column 1). I find that these values are found somewhere in the 12, 346,123, 356 row. Then I remove all those rows from the matrix. So now the matrix is 5 rows smaller. I stop checking row 1 now and move onto row 2. I continue checking, skipping over row 12, 346, 123, and 356. Hence, I am after a row that is unique (has 90 values that are all unique).
I am not sure what the code you wrote has to do with the requirement, I will give you the approach of the answer yet you have to try it yourself first.
it is clear that you need to iterate on each row to check for possible duplicates yet this will cause a performance failure , you can overcome this with a smiple use of HashMap, first store each entry in the map , the key will be the value of the node of the array, and the value should be the coordinates of this node.
When iterating over the array for each row you should find the y coordinates from the map which is common between all nodes of the row, so duplicate rows detected.
In order to avoid keep checking the already removed rows try to store all the rows to be deleted and remove them once you are done, you can use Set to store them to avoid duplicate.
Good luck with the implemenation.
The algorithm is almost there, but helpfull data-structures are missing.
To add a bit of spice I used Java 8 somewhat.
As you did one can collect the values to check for duplicates.
However one needs to remember the first row of that value, as only there it is still unknown whether a duplicate exists.
public static int checkSubsets(String[][] subsets) {
// The results.
final Set<Integer> duplicateRows = new HashSet<>();
// From the first occurrence of a duplicate value we do not know it yet,
// so need to remember.
final Map<String, Integer> firstRowOfValue = new HashMap<>();
for (int i = 0; i < subsets.length; ++i) {
for (int j = 0; j < subsets[i].length; ++j) {
final String value = subsets[i][j];
Integer oldRow = firstRowOfValue.putIfAbsent(value, i);
if (oldRow != null) { // Duplicates
duplicateRows.add(i);
duplicateRows.add(oldRow);
// oldRow might already be added if third duplicate or same row.
}
}
}
IntStream.rangeOf(0, subsets.length)
.filter(i -> !duplicateRows.contains(i))
.forEach(System.out::println);
return subsets.length - duplicateRows.size();
}
The IntStream part would be in java 7:
for (int i = 0; i < subsets.length; ++i) {
if (!duplicateRows.contains(i)) {
System.out.println(i);
}
}
With java 7 you can safely substitute here putIfAbsent with put.

How to return desired number in a 2d array?

I have problems with getting certain row or column number from an image data (barcode):
Say I have image[row][col]. How do I access row by a method?
public int getRow (Object[][] image){
return image[row];
}
doesn't work.
Thank you.
Sorry for not figuring out correctly:
There's an image I have set to true and false, for example, image[1][2] = true, image[1][3] = false etc. Now, I need to print each and every image. When I try to do it by
for (row = 0; row < 1 (which is from image[1][]); row++){
for (col = 0; col < 2 (which is from image[][2]; row++){
System.out.print(image[row][col];
}
}
Please let me know if additional info needed.
Assuming your image array contains integer values then you need to cast it to integer and return like this:
return (Integer)image[row][col];
where row,col you need to replace with the desired index.
All Bi-dimensional arrays would work the same way, ObjectType[Row][Column]. This will return the Object at the specified row and column. However, I believe (Could be wrong) that your posted programming statement is casting an Image to an Object array.
Not sure about your actual problem statement. But in the above example you should increase col value instead of row++
It should be
for (col = 0; col < 2 ; col++){
System.out.print(image[row][col]);
instead of
for (col = 0; col < 2 (which is from image[][2]; row++){
System.out.print(image[row][col];

Initialize 2D arrayList with specified number of columns but not rows?

I want to make a 2D ArrayList, with the number of columns already specified but not the rows.
For example, I want to create a table with 26 columns and 0 or 1 columns at first, then after each loop of doing something else, the number of rows will increase along with that loop.
When I increase the number of rows (length of an ArrayList of ArrayLists), I also want all 26 arrays to increase as well. What is the syntax for it?
And how would I index into, or add a new item into a specific location - say array[2][3] = item?
BTW this is a DFSA table converted from a NFSA table
You could have a list of lists, essentially something like so:
List<List<String>> table = new ArrayList<List<String>>();
Then add the 26 columns:
for(int i = 0; i < 26; i++)
{
table.add(new ArrayList<String>());
}
You can then have a method, called, say, addToColumn(int column, String value, List<List<String>> table) in which you do something like so:
for(int i = 0; i < table.size(); i++)
{
if(i == column)
{
table.get(i).add(value);
}
else
{
table.get(i).add("");
}
}
This should allow you to have lists which grow together. Of course, my assumption in the above is that you will be entering one element at a time.
Alternatively, you can do something like so:
public void addToColumns(Map<int, String> data, List<List<String>> table)
{
for(int key : data.keyset())
{
table.get(key).add(data.get(key));
}
for(int i = 0; i < table.size(); i++)
{
if(!data.containsKey(i))
{
table.get(i).add("");
}
}
}
The above algorithm should allow you to add items to multiple columns, while filling the rest up with empty strings. This should allow you to end up with rows of equal length. Also, the map will be used to store a key-value pair where the key is the column number, and the value will be whatever string you would like to throw in there. This will allow you to populate your table one row at a time.
You can simply create an array by giving only the number of rows:
int[][] array = new int[4][];
Now you may treat your array as the transpose of what you have defined so if you want to enter an element at 3rd column of 2nd row you can enter as transpose i.e.
array[3][2]=5;

Does this function work in conjunction properly with JTable model?

I have a program that is written to work in conjunction with a JTable and a few other Swing elements in order to display and model a backend for a game. The function is supposed to get the first row selected and the last row selected and store them in an array rows at index 0 and 1 respectively. Thanks for your help and hope to understand what is going on here.
public int[] getRows(JTable table) {
rows = new int [2];
rows[0] = table.getSelectedRow();
rowCount = table.getSelectedRowCount() - 1;
rows[1] = rows[0] + rowCount;
return rows;
}
JTable.getSelectedRows() can you help you in this case. Just take the first and last index from the array it returns. Note that it can return an empty array.

how to sort a two dimensional char array (only column wise) by selection sort in java

im very new in java i need the whole sorting algorithm....i can find ways to sort a 1 D array but a 2 D array gets very confusing.PLEASE help
sorry i dont have a code yet, i dont know where to start from! (this is the code for a one D array:) but i need one of 2 D (only column wise selection sort)
public static void sort(Comparable[] table) {
int n = table.length;
for (int fill=0; fill < n-1; fill++) {
int posMin = fill;
for(int next=fill; next < n; next++) {
if(table[next].compareTo(table[posMin] < 0) {
posMin = next;
}
}
//Exchange table[fill] and table[posMin]
Comparable temp = table[fill];
table[fill] = table[posMin];
table[posMin] = temp;
}
From the comments, it sounds like you can treat each column as a 1D array, so you can apply your existing 1D solution to each column: wherever you refer to table[x], you can now refer to table[x][c], where c is the column being sorted (or table[c][x]; not certain which index you're using for column).
If you have each DNA sequence be a string, you have a List of Strings. Then just sort the strings.
List<String> dnaSequences = new ArrayList<String>();
dnaSequences.add("AGCAGAAGCGGAGCTTTAAGATGAATATAAATC");
...
dnaSequences.add("AGCAGAAGCGGAGCTTTAAGATGAATATAAATC");
Collections.sort(dnaSequences);

Categories