У меня есть приложение, которое принимает несколько файлов и применяет некоторую операцию, которая зависит от их порядка (например, объединять их один за другим).
Пользователь может выбрать файлы в любом порядке, нажав Ctrl + клик, или нажав Shift +.
Файлы списка, возвращаемые выбором, не имеют того же порядка, что и пользователь, щелкнув по ним. Я бы хотел, чтобы они были возвращены в том же порядке, когда пользователь щелкнул их.
Отказ от ответственности: я "пользователь"
Я использую класс JFileChooser
с внешним видом Java в Windows 7 64bits, с JDK 7.
Вот минимальный пример
package choosertest;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class ChooserTest extends JFrame {
JFileChooser chooser;
public ChooserTest() {
chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
testOpen();
}
public static void main(String[] args) {
new ChooserTest();
}
private void testOpen() {
int choice = chooser.showOpenDialog(this);
if (choice == JFileChooser.APPROVE_OPTION) {
File[] inputFiles = chooser.getSelectedFiles();
for (File f: inputFiles) {
System.out.println(f.getName());
}
}
}
}
Я дошел до того, что он нажимает Ctrl + клик, и Shift + щелчок по выбору файлов "вниз" работает.
Однако использование Shift + click для выбора файлов "вверх" по-прежнему добавляет файлы в неправильном порядке, что может сбить с толку.
Кроме того, это решение не обновляет текстовое поле "Имя файла", чтобы отобразить фактический порядок выбора. Однако можно "исправить" это с помощью отражения.
Если вам нужно быстрое решение для выбора файлов в правильном порядке, нажав Ctrl-клик, это будет просто отлично (как выбрать, так и снять выделение).
package choosertest;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
public class ChooserTest extends JFrame {
File[] selected;
JFileChooser chooser;
public ChooserTest() {
chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(true);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
testOpen();
}
public static void main(String[] args) {
new ChooserTest();
}
private void testOpen() {
chooser.addPropertyChangeListener(new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if (evt.getPropertyName().equals("SelectedFilesChangedProperty")) {
if (selected == null) {
selected = (File[]) evt.getNewValue();
} else {
File[] newSelection = (File[]) evt.getNewValue();
if (newSelection == null) {
selected = null;
}
// check back and forth to preserve the order of files
// as the user added them
else {
List<File> orderedSel = new LinkedList<>();
// add files that are still selected
for (File f : selected) {
for (File f2 : newSelection) {
if (f.equals(f2)) {
orderedSel.add(f);
break;
}
}
}
Arrays.sort(selected);
// add newly selected files
for (File f : newSelection) {
if (Arrays.binarySearch(selected, f) < 0) {
orderedSel.add(f);
}
}
selected = orderedSel.toArray(
new File[orderedSel.size()]);
}
}
System.out.println(Arrays.toString(selected)); //debug
}
}
});
// copy previous array of selected files
File[] prevSelected = null;
if (selected != null) {
prevSelected = new File[selected.length];
System.arraycopy( selected, 0, prevSelected, 0, selected.length );
}
int choice = chooser.showOpenDialog(this);
// if the user did not cancel the selection
if (choice == JFileChooser.APPROVE_OPTION) {
System.out.println("FINAL selection: " + Arrays.toString(selected)); //debug
} else {
// restore the previous selection
selected = prevSelected;
System.out.println("PREVIOUS selection: " + Arrays.toString(selected)); //debug
}
}
}
Вместо того, чтобы упорядочивать файлы на основе порядка выбора в JFileChooser, вы можете подумать о повторном заказе файлов после выбора, используя что-то вроде JTable/JList. Как бы то ни было, вы можете подключиться к системе слушателей JFileChooser, чтобы получить порядок выбора, добавив PropertyChangeListener в JFileChooser. Всякий раз, когда выбран файл, вызывается "SelectedFilesChangedProperty", а свойство PropertyChangeEvent.getNewValue() должно возвращать выбранные файлы
final JFileChooser chooser = new JFileChooser();
chooser.setMultiSelectionEnabled(true);
chooser.addPropertyChangeListener(new PropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ( evt.getPropertyName().equals("SelectedFilesChangedProperty") ){
System.out.println(Arrays.toString((File[])evt.getNewValue()));
}
}
});
Вам нужно будет проверить массив файлов, возвращаемых getNewValue(), чтобы увидеть, какой новый файл был выбран (или отменен) для поддержания порядка.