I am working on an application that uses Swing. I have a JTabbedPane, and each tab is considered a 'page.' Each page contains 4 normal panels (I refer to them as 'views') that are arranged according to 2x2 GridLayout.
I want to minimize the amount of pages, so every time a view is removed, I want to re-sort all of the views across all of the pages (think two-dimensional arrays if it makes more sense) so that the views near the last page and removed from there, and are added to a page nearer the front.
Consider this example:
Object[][] array = new Object [][] {
{ new Object(), null, new Object(), new Object() },
{ null, null, new Object(), new Object() },
{ new Object(), new Object(), new Object(), new Object() }
};
How can I sort that array so that it looks more like:
Object[][] array = new Object[][] {
{ new Object(), new Object(), new Object(), new Object() },
{ new Object(), new Object(), new Object(), new Object() },
{ new Object(), null, null, null },
};
At first, I thought of using two loops, one going from 0 to array.length
, and one going from array.length
to 0. The idea was that: as the one going from length to 0 approaches 0, it would check whether or not the indices of the array going from 0 to length are empty. If so, it would place the non-null element in the index that contains null
.
This approach gave me a headache because of all the looping so I asked a close friend of mine for a suggestion. He suggested a much more elegant solution: Arrays.sort(Object[][], Comparator)
.
This code was the result:
Object[][] array = new Object[][] { { new Object(), null, new Object(), new Object() }, { null, null, new Object(), new Object() }, { new Object(), new Object(), new Object(), new Object() } };
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
System.out.println("Before sorting: (i = " + i + " j = " + j + " null = " + (array[i][j] == null) + ")");
}
}
Arrays.sort(array, new Comparator<Object>()
{
public int compare(Object a, Object b)
{
return a == null ? (b == null ? 0 : -1) : (b == null ? 1 : 0);
}
});
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
System.out.println("After sorting: (i = " + i + " j = " + j + " null = " + (array[i][j] == null) + ")");
}
}
The output is:
Before sorting: (i = 0 j = 0 null = false) Before sorting: (i = 0 j = 1 null = true) Before sorting: (i = 0 j = 2 null = false) Before sorting: (i = 0 j = 3 null = false) Before sorting: (i = 1 j = 0 null = true) Before sorting: (i = 1 j = 1 null = true) Before sorting: (i = 1 j = 2 null = false) Before sorting: (i = 1 j = 3 null = false) Before sorting: (i = 2 j = 0 null = false) Before sorting: (i = 2 j = 1 null = false) Before sorting: (i = 2 j = 2 null = false) Before sorting: (i = 2 j = 3 null = false) After sorting: (i = 0 j = 0 null = false) After sorting: (i = 0 j = 1 null = true) After sorting: (i = 0 j = 2 null = false) After sorting: (i = 0 j = 3 null = false) After sorting: (i = 1 j = 0 null = true) After sorting: (i = 1 j = 1 null = true) After sorting: (i = 1 j = 2 null = false) After sorting: (i = 1 j = 3 null = false) After sorting: (i = 2 j = 0 null = false) After sorting: (i = 2 j = 1 null = false) After sorting: (i = 2 j = 2 null = false) After sorting: (i = 2 j = 3 null = false)
Exactly the same.
I have also tried replacing the compare(Object, Object)
implementation with:
public int compare(Object a, Object b)
{
if (a == null && b != null)
{
return -1;
}
if (b == null && a != null)
{
return 1;
}
return 0;
}
... and have achieved the same results. I am kind of at a loss. This is not something that I do not have the knowledge to do, I just cannot wrap my head around how to actually create a solution for a problem like this.
I'd appreciate any help. Whichever way you prefer approaching it, the loop method or the Comparator method, I'd love to see it!
Thanks!