Java JFileChooser按单击顺序打开多个文件
我有一个应用程序,它接收多个文件,并根据它们的顺序应用一些操作(例如,一个接一个地合并它们) 用户可以通过Ctrl+单击或Shift+单击按任意顺序选择文件 选择器返回的列表文件的顺序与用户单击的顺序不同。我希望返回的顺序与用户单击的顺序相同 免责声明:我是“用户” 我正在使用Java JFileChooser按单击顺序打开多个文件,java,swing,jfilechooser,look-and-feel,Java,Swing,Jfilechooser,Look And Feel,我有一个应用程序,它接收多个文件,并根据它们的顺序应用一些操作(例如,一个接一个地合并它们) 用户可以通过Ctrl+单击或Shift+单击按任意顺序选择文件 选择器返回的列表文件的顺序与用户单击的顺序不同。我希望返回的顺序与用户单击的顺序相同 免责声明:我是“用户” 我正在使用JFileChooser类,该类在64位Windows 7和JDK 7上具有Java外观 这里有一个最小的例子 package choosertest; import java.io.File; import javax
JFileChooser
类,该类在64位Windows 7和JDK 7上具有Java外观
这里有一个最小的例子
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());
}
}
}
}
<> P>而不是按JFLeLe选择器中的选择顺序排序文件,您可以考虑在使用JTab/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()返回的文件数组,以查看选择(或取消选择)了哪个新文件以保持顺序。我已经知道,Ctrl+单击工作,Shift+单击“向下”选择文件工作 但是,使用Shift+单击“向上”选择文件仍然会以错误的顺序添加文件,这可能会造成混淆 此外,此解决方案不会更新“文件名”文本字段以反映选择的实际顺序。不过,可以使用反射来“修复”这个问题 如果您需要一个快速解决方案,通过按住Ctrl键并单击文件来按正确的顺序选择文件,那么这很好(选择和取消选择)
包选择测试;
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入java.io.File;
导入java.util.array;
导入java.util.LinkedList;
导入java.util.List;
导入javax.swing.JFileChooser;
导入javax.swing.JFrame;
公共类选择器测试扩展了JFrame{
选择文件[];
JFileChooser选择器;
公共选择器测试(){
chooser=newjfilechooser();
选择器。setMultiSelectionEnabled(真);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(真);
testOpen();
}
公共静态void main(字符串[]args){
新建选择器测试();
}
私有void testOpen(){
addPropertyChangeListener(新的PropertyChangeListener(){
@凌驾
公共作废属性更改(属性更改事件evt){
if(evt.getPropertyName().equals(“SelectedFilesChangedProperty”)){
如果(所选==null){
selected=(文件[])evt.getNewValue();
}否则{
文件[]newSelection=(文件[])evt.getNewValue();
if(newSelection==null){
选中=空;
}
//来回检查以保持文件的顺序
//当用户添加它们时
否则{
List orderedSel=new LinkedList();
//添加仍处于选中状态的文件
对于(文件f:已选定){
for(文件f2:新闻选举){
如果(f等于(f2)){
订单选择添加(f);
打破
}
}
}
数组。排序(选定);
//添加新选择的文件
用于(文件f:newSelection){
if(Arrays.binarySearch(selected,f)<0){
订单选择添加(f);
}
}
所选=orderedSel.toArray(
新文件[orderedSel.size()];
}
}
System.out.println(Arrays.toString(选中));//调试
}
}
});
//复制选定文件的上一个数组
文件[]prevSelected=null;
如果(已选择!=null){
prevSelected=新文件[selected.length];
System.arraycopy(选中,0,prevSelected,0,selected.length);
}
int choice=chooser.showOpenDialog(此);
//如果用户没有取消选择
if(choice==JFileChooser.APPROVE\u选项){
System.out.println(“最终选择:“+Arrays.toString(已选择));//调试
}否则{
//恢复以前的选择
已选择=已选择;
System.out.println(“上一个选择:“+Arrays.toString(已选择));//调试
}
}
}
修改了上述代码,以便在文本字段中按选择顺序显示
/*
* FileName :SelectedOrderedFileChooser.java
*/
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JTextField;
import javax.swing.plaf.metal.MetalFileChooserUI;
/**
* File Chooser with selection order<br>
* Only work for Ctrl + click selection
*/
public class SelectedOrderedFileChooser extends JFileChooser{
/** Selection order file name list */
private List<String> selectedFileNames = new ArrayList<String>();
boolean isSelectionOrder = false;
/**
* Constructor
*/
public SelectedOrderedFileChooser() {
super();
setSelectionOrder(false);
}
/**
* Constructor
* @param aIsSelectionOrder Selection ordered or not<br>
* true : Selection order, false : File Name order(JFileChooser Default)
*/
public SelectedOrderedFileChooser(boolean aIsSelectionOrder) {
super();
setSelectionOrder(aIsSelectionOrder);
}
/**
* Get selected file names in selection order
* @param fs Selected files
* @return File names in selection order
*/
private List<String> getFileNamesInSelectionOrder(File[] fs) {
List<String> tmpSelectedFileNames = new ArrayList<String>();
List<String> tmpResultFileNames = new ArrayList<String>();
for (File f : fs) {
// Get all current selected file names
tmpSelectedFileNames.add(f.getAbsolutePath());
}
for (String fn : selectedFileNames) {
if (tmpSelectedFileNames.contains(fn)) {
// If ordered selected file name is in current selected file names, add to temporary file name list
tmpResultFileNames.add(fn);
}
}
// If there are current selected file names that is not in temporary file name list, add them
for (String fn : tmpSelectedFileNames) {
if (tmpResultFileNames.contains(fn) == false) {
tmpResultFileNames.add(fn);
}
}
return tmpResultFileNames;
}
/**
* Get selected file names
* @return Selected file names
*/
public List<String> getSelectedFileNames() {
return selectedFileNames;
}
/**
* Is selection order or not?
* @return true : Selection order, false : File Name order(JFileChooser Default)
*/
public boolean isSelectionOrder() {
return isSelectionOrder;
}
/**
* Set whether file selection order or not.
* @param aIsSelectionOrder true : Selection order, false : File Name order(JFileChooser Default)
*/
public void setSelectionOrder(boolean aIsSelectionOrder) {
this.isSelectionOrder = aIsSelectionOrder;
this.addPropertyChangeListener(new PropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ( evt.getPropertyName().equals("SelectedFilesChangedProperty") ){
File[] fs = (File[])evt.getNewValue();
if (null != fs && fs.length > 0) {
if (isSelectionOrder) {
// If selection order、get file name in selection order and set to selected order file name list
List<String> tmpResultFileNames = getFileNamesInSelectionOrder(fs);
selectedFileNames = tmpResultFileNames;
showTextField();
} else {
// If not selection order、FileChooser default order
selectedFileNames.clear();
for (File f : fs) {
selectedFileNames.add(f.getAbsolutePath());
}
}
}
}
}
});
}
/**
* Get selection ordered files in array
* @return selection ordered files in array
*/
public File[] getSelectedOrderedFiles() {
List<File> ret = new ArrayList<File>();
for (String fName : selectedFileNames) {
File f = new File(fName);
ret.add(f);
}
return ret.toArray(new File[ret.size()]);
}
/**
* Show file names in selection order in text field of JFileChooser
*/
public void showTextField(){
try {
String res = "";
for (File f : getSelectedOrderedFiles()) {
res += "\"" + f.getName() + "\" ";
}
MetalFileChooserUI ui = (MetalFileChooserUI)this.getUI();
Field field;
field = MetalFileChooserUI.class.getDeclaredField("fileNameTextField");
field.setAccessible(true);
JTextField tf = (JTextField) field.get(ui);
tf.setText(res.trim());
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
*文件名:SelectedOrderedFileChooser.java
*/
导入java.beans.PropertyChangeEvent;
导入java.beans.PropertyChangeListener;
导入java.io.File;
导入java.lang.reflect.Field;
导入java.util.ArrayList;
导入java.util.List;
导入javax.swing.JFileChooser;
导入javax.swing.JTextField;
导入javax.swing.plaf.metal.MetalFileChooserUI;
/**
*具有选择顺序的文件选择器
*仅适用于Ctrl+单击选择
*/
公共类SelectedOrderedFileChooser扩展了JFileChooser{
/**选择顺序文件名列表*/
private List selectedFileNames=new ArrayList();
布尔值isSelectionOrder=false;
/**
*建造师
*/
public SelectedOrderedFileChooser(){
超级();
设置选择顺序(假);
}
/**
/*
* FileName :SelectedOrderedFileChooser.java
*/
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFileChooser;
import javax.swing.JTextField;
import javax.swing.plaf.metal.MetalFileChooserUI;
/**
* File Chooser with selection order<br>
* Only work for Ctrl + click selection
*/
public class SelectedOrderedFileChooser extends JFileChooser{
/** Selection order file name list */
private List<String> selectedFileNames = new ArrayList<String>();
boolean isSelectionOrder = false;
/**
* Constructor
*/
public SelectedOrderedFileChooser() {
super();
setSelectionOrder(false);
}
/**
* Constructor
* @param aIsSelectionOrder Selection ordered or not<br>
* true : Selection order, false : File Name order(JFileChooser Default)
*/
public SelectedOrderedFileChooser(boolean aIsSelectionOrder) {
super();
setSelectionOrder(aIsSelectionOrder);
}
/**
* Get selected file names in selection order
* @param fs Selected files
* @return File names in selection order
*/
private List<String> getFileNamesInSelectionOrder(File[] fs) {
List<String> tmpSelectedFileNames = new ArrayList<String>();
List<String> tmpResultFileNames = new ArrayList<String>();
for (File f : fs) {
// Get all current selected file names
tmpSelectedFileNames.add(f.getAbsolutePath());
}
for (String fn : selectedFileNames) {
if (tmpSelectedFileNames.contains(fn)) {
// If ordered selected file name is in current selected file names, add to temporary file name list
tmpResultFileNames.add(fn);
}
}
// If there are current selected file names that is not in temporary file name list, add them
for (String fn : tmpSelectedFileNames) {
if (tmpResultFileNames.contains(fn) == false) {
tmpResultFileNames.add(fn);
}
}
return tmpResultFileNames;
}
/**
* Get selected file names
* @return Selected file names
*/
public List<String> getSelectedFileNames() {
return selectedFileNames;
}
/**
* Is selection order or not?
* @return true : Selection order, false : File Name order(JFileChooser Default)
*/
public boolean isSelectionOrder() {
return isSelectionOrder;
}
/**
* Set whether file selection order or not.
* @param aIsSelectionOrder true : Selection order, false : File Name order(JFileChooser Default)
*/
public void setSelectionOrder(boolean aIsSelectionOrder) {
this.isSelectionOrder = aIsSelectionOrder;
this.addPropertyChangeListener(new PropertyChangeListener(){
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ( evt.getPropertyName().equals("SelectedFilesChangedProperty") ){
File[] fs = (File[])evt.getNewValue();
if (null != fs && fs.length > 0) {
if (isSelectionOrder) {
// If selection order、get file name in selection order and set to selected order file name list
List<String> tmpResultFileNames = getFileNamesInSelectionOrder(fs);
selectedFileNames = tmpResultFileNames;
showTextField();
} else {
// If not selection order、FileChooser default order
selectedFileNames.clear();
for (File f : fs) {
selectedFileNames.add(f.getAbsolutePath());
}
}
}
}
}
});
}
/**
* Get selection ordered files in array
* @return selection ordered files in array
*/
public File[] getSelectedOrderedFiles() {
List<File> ret = new ArrayList<File>();
for (String fName : selectedFileNames) {
File f = new File(fName);
ret.add(f);
}
return ret.toArray(new File[ret.size()]);
}
/**
* Show file names in selection order in text field of JFileChooser
*/
public void showTextField(){
try {
String res = "";
for (File f : getSelectedOrderedFiles()) {
res += "\"" + f.getName() + "\" ";
}
MetalFileChooserUI ui = (MetalFileChooserUI)this.getUI();
Field field;
field = MetalFileChooserUI.class.getDeclaredField("fileNameTextField");
field.setAccessible(true);
JTextField tf = (JTextField) field.get(ui);
tf.setText(res.trim());
} catch (Exception e) {
e.printStackTrace();
}
}
}