multiple select with JFileChooser always returns sorted Array of File

C

Cengiz

Hi,

i need a JFileChooser, with which i can select multiple files.
This works fine:

JFileChooser fileChooser = new JFileChooser("File Dialog");
fileChooser.setMultiSelectionEnabled(true);
int returnVal = fileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = fileChooser.getSelectedFiles();
...
}

But the Array files is always sorted by filename.
I want to get a list, where the order depends on the selection-order of the files.
How to make this?
I havent found a method or member in the JFileChooser-API-Documentation.

thx, Cengiz
 
C

Christophe Vanfleteren

Cengiz said:
Hi,

i need a JFileChooser, with which i can select multiple files.
This works fine:

JFileChooser fileChooser = new JFileChooser("File Dialog");
fileChooser.setMultiSelectionEnabled(true);
int returnVal = fileChooser.showOpenDialog(this);
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = fileChooser.getSelectedFiles();
...
}

But the Array files is always sorted by filename.
I want to get a list, where the order depends on the selection-order of
the files. How to make this?
I havent found a method or member in the JFileChooser-API-Documentation.

thx, Cengiz

You can't, unless you override JFileChooser to create your own version of
getSelectedFiles().
 
C

Cengiz

You can't, unless you override JFileChooser to create your own version of
getSelectedFiles().

OK, and how I do this ?

public File[] getSelectedFiles(){
???
}
 
C

Cengiz

Now i have this:

public File[] getSelectedFiles() {
Container c1 = null;
try {
c1 = (Container) getComponent(1);
}
catch (ArrayIndexOutOfBoundsException e) {}
JList list = null;
while (c1 != null) {
Container c = (Container) c1.getComponent(0);
if (c instanceof JList) {
list = (JList) c;
break;
}
c1 = c;
}

Object[] entries = list.getSelectedValues(); // alternative ?

File[] files = new File[entries.length];
for (int k = 0; k < entries.length; k++) {
if (entries[k] instanceof File) {
files[k] = (File) entries[k];
}
}
return files;
}

The problem is: getSelectedValues returns a sorted Array
Is there an alternative ?
 
C

Christophe Vanfleteren

Cengiz said:
Now i have this:

public File[] getSelectedFiles() {
Container c1 = null;
try {
c1 = (Container) getComponent(1);
}
catch (ArrayIndexOutOfBoundsException e) {}
JList list = null;
while (c1 != null) {
Container c = (Container) c1.getComponent(0);
if (c instanceof JList) {
list = (JList) c;
break;
}
c1 = c;
}

Object[] entries = list.getSelectedValues(); // alternative ?

File[] files = new File[entries.length];
for (int k = 0; k < entries.length; k++) {
if (entries[k] instanceof File) {
files[k] = (File) entries[k];
}
}
return files;
}

The problem is: getSelectedValues returns a sorted Array
Is there an alternative ?


Hmm, I've been looking into the JFileChooser code (it's in src.zip in your
JDK directory).
It won't be very easy to get the behaviour you want (which is also somewhat
strange IMHO, what do you need this for?).

The code that gets the selected files, is in
javax/swing/plaf/basic/BasicFileChooserUI, in which a ListSelectionListener
is attached to the JList wich dispalys the files in the JFileChooser.

When multiSelection is enabled, it just asks for the getSelectedValues of
the JList, which will always return all the item, so you lose the history
of what was selected first.

You'd have to override that entire method, and the let JFileChooser use your
custom FileChooserUI, which isn't that simple, since all the other
Look'N'Feels inherit from BasicFileChooserUI, so you'd almost have to
recreate all the other XXXFileChooserUIs, which would break the moment
another UI is used.
 
C

Cengiz

I think i made it,
i need this behaviour, because i have to choose several files and
combine them.
for example:
first selection -> second selection -> third selection
filetype1_no3 -> filetype2_no2 -> filetype3_no2 (this three files
belong together)
filetype1_no2 -> filetype2_no1 -> filetype3_no3 (and also these
tree)
filetype1_no1 -> filetype2_no3 -> filetype3_no1 (and these)

For this I have three JFilechooser with multiple selection.
Therefor the order of selection is important.
It's certainly difficult for the user of this program, but i don't
know how other to build a relation between filetype1, filetype2 and
filetype3.

-------------------------------------------------------------------
public class MultiFileChooser
extends JFileChooser {

MultiFileChooser(){
super();
}

MultiFileChooser(String path){
super(path);
}

private static Object[] previousSelection = null;

public File[] getSelectedFiles() {
Container c1 = null;
try {
c1 = (Container) getComponent(1);
}
catch (ArrayIndexOutOfBoundsException e) {}
JList list = null;
while (c1 != null) {
Container c = (Container) c1.getComponent(0);
if (c instanceof JList) {
list = (JList) c;
break;
}
c1 = c;
}

if (previousSelection == null) { // noch nichts vorher ausgewählt
previousSelection = list.getSelectedValues();
}
else {
Object[] currentSelection = list.getSelectedValues();
if (previousSelection.length - currentSelection.length == 1)
{//less selection
for (int i = 0; i < previousSelection.length; i++) {
boolean remove = true;
for (int j = 0; j < currentSelection.length; j++) {
if ( ( (File)
currentSelection[j]).getAbsolutePath().equals( ( (
File) previousSelection).getAbsolutePath())) {
remove = false;
break;
}
}
if (remove) {
previousSelection = remove(previousSelection, i);
}
}
}
else if (previousSelection.length - currentSelection.length ==
-1){ //extend selection
for (int i = 0; i < currentSelection.length; i++) {
boolean newAdd = true;
for (int j = 0; j < previousSelection.length; j++) {
if ( (currentSelection instanceof File)) {
if ( ( (File)
currentSelection).getAbsolutePath().equals( ( (
File) previousSelection[j]).getAbsolutePath())) {
newAdd = false;
break;
}
}
}
if (newAdd) {
previousSelection = add(previousSelection,
currentSelection);
}
}
}
else { //special cases
if (previousSelection.length == 1 && currentSelection.length
== 1) {
previousSelection = currentSelection;
}
else if (previousSelection.length != currentSelection.length)
{
previousSelection = currentSelection;
}
}
}

File[] files = new File[previousSelection.length];
for (int k = 0; k < previousSelection.length; k++) {
if (previousSelection[k] instanceof File) {
files[k] = (File) previousSelection[k];
}
}
previousSelection = files;
if (previousSelection.length == 0) {
previousSelection = null;
}
return files;
}

private Object[] add(Object[] array, Object object) {
Object[] temp = new Object[array.length + 1];
for (int i = 0; i < array.length; i++) {
temp = array;
}
temp[array.length] = object;
return temp;
}

private Object[] remove(Object[] array, int index) {
Object[] temp = new Object[array.length - 1];
for (int i = 0; i < index; i++) {
temp = array;
}
for (int i = index + 1; i < array.length; i++) {
temp[i - 1] = array;
}
return temp;
}

public static void main(String[] args) {
MultiFileChooser fileChooser = new MultiFileChooser("c:/test");
fileChooser.setDialogTitle("select file");
fileChooser.setMultiSelectionEnabled(true);
int returnVal = fileChooser.showOpenDialog(new JFrame());
if (returnVal == JFileChooser.APPROVE_OPTION) {
File[] files = fileChooser.getSelectedFiles();
String[] fileNames = new String[files.length];
for (int i = 0; i < files.length; i++) {
fileNames = files.getPath();
System.out.println(fileNames);
}
}
}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,734
Messages
2,569,441
Members
44,832
Latest member
GlennSmall

Latest Threads

Top