帆软报表设计器源代码。
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

1922 lines
69 KiB

package com.fr.file;
import com.fr.base.BaseUtils;
import com.fr.base.FRContext;
import com.fr.base.extension.FileExtension;
import com.fr.design.DesignerEnvManager;
import com.fr.design.ExtraDesignClassManager;
import com.fr.design.actions.UpdateAction;
import com.fr.design.dialog.BasicPane;
import com.fr.design.dialog.FineJOptionPane;
import com.fr.design.dialog.UIDialog;
import com.fr.design.env.DesignerWorkspaceInfo;
import com.fr.design.env.DesignerWorkspaceType;
import com.fr.design.file.HistoryTemplateListPane;
import com.fr.design.file.NodeAuthProcessor;
import com.fr.design.fun.ReportSupportedFileUIProvider;
import com.fr.design.gui.ibutton.UIButton;
import com.fr.design.gui.ibutton.UIButtonUI;
import com.fr.design.gui.icombobox.UIComboBox;
import com.fr.design.gui.ilable.UILabel;
import com.fr.design.gui.itextfield.DefaultCompletionFilter;
import com.fr.design.gui.itextfield.UIAutoCompletionField;
import com.fr.design.gui.itextfield.UITextField;
import com.fr.design.gui.itree.filetree.FileTreeIcon;
import com.fr.design.i18n.Toolkit;
import com.fr.design.layout.FRGUIPaneFactory;
import com.fr.design.layout.TableLayout;
import com.fr.design.layout.TableLayoutHelper;
import com.fr.design.mainframe.DesignerFrame;
import com.fr.design.mainframe.DesignerFrameFileDealerPane;
import com.fr.design.mainframe.JTemplate;
import com.fr.design.utils.gui.GUICoreUtils;
import com.fr.event.Event;
import com.fr.event.EventDispatcher;
import com.fr.event.Listener;
import com.fr.file.filetree.FileNode;
import com.fr.file.filter.ChooseFileFilter;
import com.fr.file.filter.FILEFilter;
import com.fr.general.ComparatorUtils;
import com.fr.general.GeneralContext;
import com.fr.log.FineLoggerFactory;
import com.fr.report.ExtraReportClassManager;
import com.fr.report.fun.ReportSupportedFileProvider;
import com.fr.stable.CoreConstants;
import com.fanruan.product.ProductConstants;
import com.fr.stable.StableUtils;
import com.fr.stable.StringUtils;
import com.fr.stable.os.windows.WindowsDetector;
import com.fr.stable.project.ProjectConstants;
import com.fr.workspace.WorkContext;
import com.fr.workspace.Workspace;
import com.fr.workspace.WorkspaceEvent;
import javax.swing.AbstractAction;
import javax.swing.AbstractListModel;
import javax.swing.ActionMap;
import javax.swing.BorderFactory;
import javax.swing.DefaultComboBoxModel;
import javax.swing.DefaultListCellRenderer;
import javax.swing.DefaultListModel;
import javax.swing.Icon;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JDialog;
import javax.swing.JFileChooser;
import javax.swing.JList;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.KeyStroke;
import javax.swing.ListModel;
import javax.swing.ListSelectionModel;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.filechooser.FileSystemView;
import javax.swing.plaf.basic.BasicArrowButton;
import javax.swing.plaf.basic.BasicButtonUI;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Insets;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.EnumSet;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static javax.swing.JOptionPane.DEFAULT_OPTION;
import static javax.swing.JOptionPane.WARNING_MESSAGE;
/*
* FileChooserPane要高亮显示某Button,以显示当前路径
* 边距要调整
* postfix还没有处理
* 该文件选择器,整理行为如下:
*/
public class FILEChooserPane extends BasicPane {
/**
* Return value if OK is chosen.
*/
public static final int OK_OPTION = 0;
/**
* Return value if CANCEL is chosen.
*/
public static final int CANCEL_OPTION = 1;
public static final int JOPTIONPANE_OK_OPTION = 2;
public static final int JOPTIONPANE_CANCEL_OPTION = 3;
/**
* alex:之所以在Pattern那里加个+,是因为有些路径会有两个甚至多个分隔符放在一起
*/
private static final Pattern SEPARATOR_PATTERN = Pattern.compile("[/\\\\]+");
private static final FILEChooserPane INSTANCE = new FILEChooserPane();
private FILE currentDirectory; // 当前路径,在subFileList中显示这个路径下所有的文件
private List<FILEFilter> filterList = new ArrayList<>();
private FILEFilter filter;
private LocationButtonPane locationBtnPane; // 显示location的Panel
private UIButton mkdirButton;
private JList placesList; // File.listRoots() + Env + Favourite
private JList subFileList; // 当前选中目录下的文件夹及文件
private JScrollPane scrollPane;
private UIAutoCompletionField fileNameTextField; // 文件名的文本框
private UIComboBox postfixComboBox; // 文件后缀名的下拉列表框
private UIButton okButton;
protected int type;
protected boolean showEnv;
protected boolean showLoc;
protected boolean showWebReport = false;
private UIDialog dialog;
private int option = CANCEL_OPTION;
protected String suffix;
/**
* @return
*/
public static FILEChooserPane getInstance() {
return getInstance(true, true);
}
/**
* @param showEnv
* @return
*/
public static FILEChooserPane getInstance(boolean showEnv) {
return getInstance(showEnv, true);
}
/**
* @param showEnv
* @param showLoc
* @return
*/
public static FILEChooserPane getInstance(boolean showEnv, boolean showLoc) {
INSTANCE.showEnv = showEnv;
INSTANCE.showLoc = showLoc;
INSTANCE.showWebReport = false;
INSTANCE.setPlaceListModel();
INSTANCE.removeAllFilter();
return INSTANCE;
}
public static FILEChooserPane getMultiEnvInstance(boolean showLoc, boolean showWebReport, FILEFilter filter) {
INSTANCE.showEnv = true;
INSTANCE.showLoc = showLoc;
INSTANCE.showWebReport = showWebReport;
// 替换掉 PlaceListModel
INSTANCE.setMultiPlaceListModel();
INSTANCE.removeAllFilter();
INSTANCE.addChooseFILEFilter(filter, 0);
return INSTANCE;
}
public static FILEChooserPane getInstanceWithDesignatePath(String path, FILEFilter filter, String topPath) {
INSTANCE.showLoc = false;
INSTANCE.showEnv = false;
INSTANCE.showWebReport = false;
INSTANCE.setTopPath(topPath);
INSTANCE.setDesignateModel(path);
INSTANCE.removeAllFilter();
INSTANCE.addChooseFILEFilter(filter, 0);
return INSTANCE;
}
public static FILEChooserPane getMultiEnvInstance(boolean showLoc, boolean showWebReport) {
INSTANCE.showEnv = true;
INSTANCE.showLoc = showLoc;
INSTANCE.showWebReport = showWebReport;
// 替换掉 PlaceListModel
INSTANCE.setMultiPlaceListModel();
INSTANCE.removeAllFilter();
return INSTANCE;
}
/**
* @param showEnv
* @param filter
* @return
*/
public static FILEChooserPane getInstance(boolean showEnv, FILEFilter filter) {
INSTANCE.showEnv = showEnv;
INSTANCE.setPlaceListModel();
INSTANCE.removeAllFilter();
INSTANCE.addChooseFILEFilter(filter, 0);
return INSTANCE;
}
/**
* @param showEnv
* @param showLoc
* @param filter
* @return
*/
public static FILEChooserPane getInstance(boolean showEnv, boolean showLoc, FILEFilter filter) {
INSTANCE.showEnv = showEnv;
INSTANCE.showLoc = showLoc;
INSTANCE.showWebReport = false;
INSTANCE.setPlaceListModel();
INSTANCE.removeAllFilter();
INSTANCE.addChooseFILEFilter(filter, 0);
return INSTANCE;
}
/**
* @param showEnv
* @param showLoc
* @param showWebReport
* @param filter
* @return
*/
public static FILEChooserPane getInstance(boolean showEnv, boolean showLoc, boolean showWebReport, FILEFilter filter) {
INSTANCE.showEnv = showEnv;
INSTANCE.showLoc = showLoc;
INSTANCE.showWebReport = showWebReport;
INSTANCE.setPlaceListModel();
INSTANCE.removeAllFilter();
INSTANCE.addChooseFILEFilterToFist(filter, 0);
return INSTANCE;
}
private FILEChooserPane() {
this.setBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4));
this.setLayout(FRGUIPaneFactory.createBorderLayout());
// kel:support Esc key.
InputMap inputMapAncestor = this.getInputMap(JComponent.WHEN_ANCESTOR_OF_FOCUSED_COMPONENT);
ActionMap actionMap = this.getActionMap();
// transfer focus to CurrentEditor
inputMapAncestor.put(KeyStroke.getKeyStroke(KeyEvent.VK_ESCAPE, 0), "dialogExit");
actionMap.put("dialogExit", new AbstractAction() {
@Override
public void actionPerformed(ActionEvent evt) {
option = CANCEL_OPTION;
dialogExit();
}
});
JPanel locationPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
// locationPane.setLayout(FRGUIPaneFactory.createBorderLayout());
locationPane.add(locationBtnPane = new LocationButtonPane(), BorderLayout.CENTER);
mkdirButton = initMkdirButton();
locationPane.add(mkdirButton, BorderLayout.EAST);
JPanel centerLeftPanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
// centerLeftPanel.setLayout(FRGUIPaneFactory.createBorderLayout());
// Richie:placesList includes C,D,E,F and DeskTop etc.
placesList = new JList();
centerLeftPanel.add(placesList, BorderLayout.CENTER);
centerLeftPanel.setBorder(BorderFactory.createLineBorder(Color.GRAY));
centerLeftPanel.setPreferredSize(new Dimension(120, 1));
placesList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
placesList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof FILE) {
FILE dir = (FILE) value;
String name = dir.getName();
if (name != null && !StringUtils.isBlank(name)) {
this.setText(name);
} else {
this.setText(GeneralContext.getCurrentAppNameOfEnv());
}
Icon icon = dir.getIcon();
if (icon != null) {
this.setIcon(icon);
}
}
return this;
}
});
// placeList listener
placesList.addListSelectionListener(new ListSelectionListener() {
@Override
public void valueChanged(ListSelectionEvent e) {
Object selValue = placesList.getSelectedValue();
if (selValue instanceof FILE) {
setSelectedDirectory((FILE) selValue);
}
}
});
/*
* placeList mouseListener
*/
placesList.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Object selValue = placesList.getSelectedValue();
if (selValue instanceof FILE) {
setSelectedDirectory((FILE) selValue);
}
}
});
// centerRightPane
JPanel centerRightPane = FRGUIPaneFactory.createBorderLayout_S_Pane();
JPanel subFilePanel = FRGUIPaneFactory.createBorderLayout_S_Pane();
// 以后rightPanel要用JTable
subFileList = new JList(new DefaultListModel<>());
/*
* JList的CellRenderer
*/
subFileList.setCellRenderer(new DefaultListCellRenderer() {
@Override
public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
if (value instanceof FILE) {
FILE dir = (FILE) value;
String name = dir.getName();
if (name != null) {
this.setText(name);
}
Icon icon = dir.getIcon();
if (icon != null) {
this.setIcon(icon);
}
}
return this;
}
});
/*
* 鼠标点击JList时的listener
*/
subFileList.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
Object source = e.getSource();
if (!(source instanceof JList)) {
return;
}
if (e.getClickCount() < 1) {
return;
}
JList list = (JList) source;
Object selValue = list.getSelectedValue();
if (selValue instanceof FILE) {
if (e.getClickCount() == 1) {
fileNameTextField.removeDocumentListener();
setFileTextField((FILE) selValue);
fileNameTextField.addDocumentListener();
} else {
setSelectedDirectory((FILE) selValue);
if (!((FILE) selValue).isDirectory()) {
doOK();
}
}
}
}
});
/*
* right list.
*/
// Richie:按下Enter的时候打开文件夹或者打开文件
subFileList.addKeyListener(new KeyAdapter() {
@Override
public void keyReleased(KeyEvent e) {
Object source = e.getSource();
if (!(source instanceof JList)) {
return;
}
JList list = (JList) source;
Object selValue = list.getSelectedValue();
if (selValue instanceof FILE) {
setFileTextField((FILE) selValue);
// if (((FILE)selValue).isDirectory()) {
// fileNameTextField.setText("");
// }
// Richie:按下Enter的时候打开文件夹或者打开文件
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
setSelectedDirectory((FILE) selValue);
if (!((FILE) selValue).isDirectory()) {
doOK();
}
}
}
}
});
scrollPane = new JScrollPane(subFileList);
subFilePanel.add(scrollPane, BorderLayout.CENTER);
centerRightPane.add(subFilePanel, BorderLayout.CENTER);
// 用createTableLayoutPane布局下fileNamePane
UIButton cancelButton;
Component[][] coms = new Component[][]{
new Component[]{GUICoreUtils.createBorderPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_Utils_File_Name") + ":"), BorderLayout.WEST),
fileNameTextField = new UIAutoCompletionField(), okButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Utils_Design_File_Open"))
},
new Component[]{GUICoreUtils.createBorderPane(new UILabel(Toolkit.i18nText("Fine-Design_Report_Utils_File_Type") + ":"), BorderLayout.WEST),
postfixComboBox = new UIComboBox(), cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Utils_Design_Action_Cancel"))
}};
JPanel fileNamePane = TableLayoutHelper.createGapTableLayoutPane(coms, new double[]{TableLayout.PREFERRED, TableLayout.PREFERRED,
TableLayout.PREFERRED}, new double[]{TableLayout.PREFERRED, TableLayout.FILL, TableLayout.PREFERRED}, 24, 4);
centerRightPane.add(fileNamePane, BorderLayout.SOUTH);
Component[][] outComponents = new Component[][]{
new Component[]{GUICoreUtils.createBorderPane(new UILabel(Toolkit.i18nText("Fine-Design_Basic_App_File_Lookup_range") + ":"), BorderLayout.WEST), locationPane},
new Component[]{centerLeftPanel, centerRightPane}};
JPanel contentPane = TableLayoutHelper.createTableLayoutPane(outComponents, new double[]{TableLayout.PREFERRED, TableLayout.FILL},
new double[]{TableLayout.PREFERRED, TableLayout.FILL});
this.add(contentPane, BorderLayout.CENTER);
okButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
doOK();
}
});
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
option = CANCEL_OPTION;
doCancel();
}
});
fileNameTextField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ENTER) {
option = CANCEL_OPTION;
doOK();
}
}
});
postfixComboBox.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
Object ss = postfixComboBox.getSelectedItem();
if (ss instanceof ChooseFileFilter) {
setFILEFilter((ChooseFileFilter) ss);
if (fileNameTextField.isShowing()) {
fileNameTextField.setText(calProperFileName(fileNameTextField.getText(), (ChooseFileFilter) ss));
}
} else {
setFILEFilter(null);
}
}
});
}
private String calProperFileName(String fileName, ChooseFileFilter fileFilter) {
if (fileFilter == null) {
return fileName;
}
String filterExtension = fileFilter.getExtensionString();
int lastDotIndex = fileName.lastIndexOf(".") != -1 ? fileName.lastIndexOf(".") : fileName.length();
String fileNameWithOutExtension = fileName.substring(0, lastDotIndex);
String fileNameExtension = fileName.substring(lastDotIndex);
FileExtension fileExtension = FileExtension.parse(fileNameExtension);
if (StringUtils.isEmpty(fileName) || StringUtils.isEmpty(filterExtension) || fileFilter.containsExtension(fileExtension.getExtension())) {
return fileName;
}
if (!ComparatorUtils.equals(fileNameExtension, filterExtension) && !isMapping(fileNameExtension, filterExtension)) {
return fileName + filterExtension;
}
return fileNameWithOutExtension + filterExtension;
}
private boolean isMapping(String fromExtension, String toExtension) {
if (FileExtension.CPTX.matchExtension(fromExtension)) {
return FileExtension.CPT.matchExtension(toExtension);
} else if (FileExtension.CPT.matchExtension(fromExtension)) {
return FileExtension.CPTX.matchExtension(toExtension);
}
return false;
}
private void doCancel() {
this.locationBtnPane.setPopDir(null);
dialogExit();
}
/**
* @param showEnv
* @param showLoc
*/
public FILEChooserPane(boolean showEnv, boolean showLoc) {
this();
this.showEnv = showEnv;
this.showLoc = showLoc;
this.setPlaceListModel();
}
/**
* 返回选中的FILE
*
* @return
*/
public FILE getSelectedFILE() {
String fileName = fileNameTextField.getText().trim();
if (!fileName.endsWith(suffix) && !fileName.contains(CoreConstants.DOT)) {
fileName += this.suffix;
}
if (currentDirectory == null) {
return null;
}
if (currentDirectory instanceof FileFILE) {
return new FileFILE((FileFILE) currentDirectory, fileName);
} else {
return new FileNodeFILE((FileNodeFILE) currentDirectory, fileName, false);
}
}
protected String getEnvProjectName() {
return Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Env_Directory");
}
/**
* 增加文件过滤器
*
* @param filter 过滤器
*/
public void addChooseFILEFilter(FILEFilter filter) {
addChooseFILEFilter(filter, filterList.size());
}
/**
* 在指定index增加过滤器
*
* @param filter 过滤器
* @param index 序号
*/
public void addChooseFILEFilter(FILEFilter filter, int index) {
if (filterList.contains(filter)) {
return;
}
this.filterList.add(index, filter);
}
/**
* 若是已经存在,则将之删去之后,在指定的位置增加
*
* @param filter 过滤
* @param index 序号
*/
public void addChooseFILEFilterToFist(FILEFilter filter, int index) {
if (filterList.contains(filter)) {
filterList.remove(filter);
filterList.add(index, filter);
return;
}
this.filterList.add(index, filter);
}
/**
* 删除文件过滤器
* 这命名太乱了,完全是误导
*
* @param filter 过滤
*/
public void removeFILEFilter(FILEFilter filter) {
if (filterList.contains(filter)) {
this.filterList.remove(filter);
}
}
/**
* 删掉全部的过滤器
*/
public void removeAllFilter() {
this.filterList.clear();
}
public void removeTopPath() {
this.setTopPath(StringUtils.EMPTY);
}
/**
* 设置filter,刷新右侧subFileList中的items
*
* @param filter 过滤
*/
public void setFILEFilter(FILEFilter filter) {
this.filter = filter;
refreshSubFileListModel();
}
/**
* richer:默认的话就使用.cpt作为后缀名
*
* @param text 文本
* @param suffix 后缀
*/
public void setFileNameTextField(String text, String suffix) {
if (StringUtils.isEmpty(suffix)) {
suffix = FileExtension.CPT.getSuffix();
}
this.suffix = suffix;
if (!text.endsWith(suffix)) {
text = removeSuffix(text) + suffix;
}
fileNameTextField.removeDocumentListener();
fileNameTextField.setText(text);
fileNameTextField.addDocumentListener();
if (currentDirectory == null) {
return;
}
FILE[] files = currentDirectory.listFiles();
String[] names = new String[files.length];
for (int i = 0; i < files.length; i++) {
names[i] = files[i].getName();
}
fileNameTextField.setFilter(new DefaultCompletionFilter(names));
}
public void disableFileNameTextFiled() {
fileNameTextField.setEditable(false);
fileNameTextField.setEnabled(false);
}
public void enableFileNameTextFiled() {
fileNameTextField.setEditable(true);
fileNameTextField.setEnabled(true);
}
/**
* 移除文件后缀的方法
* 解决cptx文件的另存为操作默认会出现双后缀的bug(xxx.cptx.cpt)
**/
private String removeSuffix(String text) {
return FileExtension.CPTX.matchExtension(text) ? text.substring(0, text.length() - FileExtension.CPTX.getSuffix().length()) : text;
}
/**
* 打开对话框
*
* @param parent 父类
* @return 类型
*/
public int showOpenDialog(Component parent) {
return showOpenDialog(parent, FileExtension.CPT.getSuffix());
}
/**
* 打开对话框
*
* @param parent 父类
* @param suffix 后缀
* @return 类型
*/
public int showOpenDialog(Component parent, String suffix) {
return showDialog(parent, JFileChooser.OPEN_DIALOG, suffix);
}
/**
* 打开对话框
*
* @param parent 父类
* @return 类型
*/
public int showSaveDialog(Component parent) {
return showSaveDialog(parent, FileExtension.CPT.getSuffix());
}
/**
* 打开对话框
*
* @param parent 父类
* @param suffix 后缀
* @return 类型
*/
public int showSaveDialog(Component parent, String suffix) {
return showDialog(parent, JFileChooser.SAVE_DIALOG, suffix);
}
/**
* august:控件的事件都在这里面添加的 那么我每次showDialog,不都要重复添加一次事件吗?无语了
*
* @param parent 父类
* @param type 类型
* @param suffix 后缀
* @return 类型
*/
public int showDialog(Component parent, int type, String suffix) {
this.type = type;
this.suffix = suffix;
dialog = showWindow(parent instanceof DesignerFrame ? (Window) parent : SwingUtilities.getWindowAncestor(parent), false);
JPanel contentPane = (JPanel) dialog.getContentPane();
contentPane.setLayout(FRGUIPaneFactory.createM_BorderLayout());
contentPane.add(this, BorderLayout.CENTER);
okButton.setText(dialogName());
// kel:打开界面的时候让文本域获得焦点,支持enter打开或保存。
dialog.addWindowListener(new WindowAdapter() {
@Override
public void windowActivated(WindowEvent e) {
fileNameTextField.requestFocusInWindow();
}
@Override
public void windowClosing(WindowEvent e) {
option = CANCEL_OPTION;
dialogExit();
}
});
// neil:默认打开pane里显示所有支持的格式
// daniel 从templateFileTree中取
if (!showWebReport && filterList.isEmpty()) {
fileType();
}
chooseType();
// richer:当文件类型被选定时,显示的文件就仅仅显示被选定的类型
// 如果是保存对话框,给个默认名字
if (type != JFileChooser.SAVE_DIALOG) {
fileNameTextField.removeDocumentListener();
fileNameTextField.setText("");
fileNameTextField.addDocumentListener();
}
dialog.setAlwaysOnTop(true);
dialog.setVisible(true);
return option;
}
protected void fileType() {
String appName = ProductConstants.APP_NAME;
JTemplate editing = HistoryTemplateListPane.getInstance().getCurrentEditingTemplate();
if (editing == null || !editing.isChartBook()) {
if (type == JFileChooser.OPEN_DIALOG) {
ChooseFileFilter supportedTypes = new ChooseFileFilter(FRContext.getFileNodes().getSupportedTypes(), appName + Toolkit.i18nText("Fine-Design_Report_Template_File"));
Set<ReportSupportedFileProvider> providers = ExtraReportClassManager.getInstance().getArray(ReportSupportedFileProvider.XML_TAG);
for (ReportSupportedFileProvider provider : providers) {
for (FileExtension fileExtension : provider.getFileExtensions()) {
supportedTypes.addExtension(fileExtension.getExtension());
}
}
this.addChooseFILEFilter(supportedTypes);
}
// ben:filefilter设置初值为cpt过滤
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPT, appName + Toolkit.i18nText("Fine-Design_Report_Template_File")));
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CPTX, appName + Toolkit.i18nText("Fine-Design_Report_Template_File")));
// richer:form文件 daniel 改成三个字
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.FRM, appName + Toolkit.i18nText("Fine-Design_Report_Template_File")));
Set<ReportSupportedFileUIProvider> providers = ExtraDesignClassManager.getInstance().getArray(ReportSupportedFileUIProvider.XML_TAG);
for (ReportSupportedFileUIProvider provider : providers) {
provider.addChooseFileFilter(this, StringUtils.EMPTY);
}
} else {
if (type == JFileChooser.OPEN_DIALOG) {
this.addChooseFILEFilter(new ChooseFileFilter(EnumSet.of(FileExtension.XLS, FileExtension.XLSX), Toolkit.i18nText("Fine-Design_Basic_Import_Excel_Source")));
}
}
// 添加 xls 文件类型过滤 kt
if (WorkContext.getCurrent().isLocal()) { //本地连接
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.XLS, Toolkit.i18nText("Fine-Design_Basic_Import_Excel_Source")));
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.XLSX, Toolkit.i18nText("Fine-Design_Basic_Import_Excel2007_Source")));
}
if (FileExtension.PNG.matchExtension(suffix)) {
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.PNG, Toolkit.i18nText("Fine-Design_Basic_App_Export_png")));
}
if (type == JFileChooser.SAVE_DIALOG) {
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.PDF, Toolkit.i18nText("Fine-Design_Basic_Import_Export_PDF")));
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.SVG, Toolkit.i18nText("Fine-Design_Basic_Import_Export_SVG")));
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.CSV, Toolkit.i18nText("Fine-Design_Basic_Import_Export_CSV")));
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.DOC, Toolkit.i18nText("Fine-Design_Basic_Import_Export_Word")));
this.addChooseFILEFilter(new ChooseFileFilter(FileExtension.TXT, Toolkit.i18nText("Fine-Design_Basic_Import_Export_Text")));
}
}
private void chooseType() {
DefaultComboBoxModel defaultComboBoxModel = (DefaultComboBoxModel) postfixComboBox.getModel();
defaultComboBoxModel.removeAllElements();
for (FILEFilter filter : filterList) {
defaultComboBoxModel.addElement(filter);
}
if (WorkContext.getCurrent().isLocal()) { //本地连接
if (!showWebReport) {
defaultComboBoxModel.addElement(Toolkit.i18nText("Fine-Design_Basic_Utils_App_AllFiles") + "(*.*)");
}
}
// 默认选取的文件类型(.cpt)类型
if (!filterList.isEmpty()) {
setFILEFilter(filterList.get(0));
defaultComboBoxModel.setSelectedItem(filterList.get(0));
}
// richer:根据不同的文件类型显示不同的后缀名
EnumSet<FileExtension> fileExtensions = EnumSet.of(
FileExtension.CPT, FileExtension.CPTX, FileExtension.FRM, FileExtension.FRMX,
FileExtension.XLS, FileExtension.XLSX, FileExtension.PDF, FileExtension.SVG,
FileExtension.CSV, FileExtension.DOC, FileExtension.TXT, FileExtension.PNG);
for (FileExtension fileExtension : fileExtensions) {
if (fileExtension.matchExtension(suffix)) {
postfixComboBox.setSelectedIndex(suffixIndex(fileExtension.getExtension()));
break;
}
}
//jerry 26216 只保留.cpt .frm有用的格式,并且不可编辑
postfixComboBox.setEnabled(true);
//只有一个类型时不可下拉
if (filterList.size() == 1) {
postfixComboBox.setEnabled(false);
}
}
private int suffixIndex(String extension) {
for (int i = 0; i < filterList.size(); i++) {
FILEFilter fileFilter = filterList.get(i);
if (fileFilter.containsExtension(extension)) {
return i;
}
}
return 0;
}
private void doOK() {
// 如果没有写文件名,不允许打开 or save
if (fileNameTextField.getText().length() == 0 || !validInput()) {
return;
}
if (type == JFileChooser.OPEN_DIALOG) {
if (this.subFileList.getSelectedValue() == null) {
FILE file = this.getSelectedFILE();
if (file.exists()) {
option = OK_OPTION;
saveDictionary();
dialogExit();
} else {
FineJOptionPane.showMessageDialog(this, Toolkit.i18nText("Fine-Design_Basic_App_File_Not_Exist"));
return;
}
}
// alex:NPE判断,因为可能没有选中子目录,直接在文本框中输入文件名
FILE selectedSubFile = (FILE) this.subFileList.getSelectedValue();
if (selectedSubFile != null && selectedSubFile.isDirectory()) {
setSelectedDirectory((FILE) this.subFileList.getSelectedValue());
} else {
option = OK_OPTION;
saveDictionary();
dialogExit();
}
} else if (type == JFileChooser.SAVE_DIALOG) {
saveDialog();
}
}
private boolean validInput() {
String name = fileNameTextField.getText().trim();
if (!Pattern.compile(DesignerFrameFileDealerPane.FILE_NAME_LIMIT).matcher(name).matches()) {
FineJOptionPane.showConfirmDialog(this,
Toolkit.i18nText("Fine-Design_Basic_Template_Name_Illegal"),
Toolkit.i18nText("Fine-Design_Basic_Error"),
DEFAULT_OPTION,
WARNING_MESSAGE);
return false;
}
return true;
}
private void saveDialog() {
String filename = fileNameTextField.getText();
filename = calProperFileName(filename, (ChooseFileFilter) (postfixComboBox.getSelectedItem()));
fileNameTextField.setText(filename);
option = OK_OPTION;
FILE selectedFile = this.getSelectedFILE();
if (access(selectedFile) && access(currentDirectory)) {
if (selectedFile.exists()) {
int selVal = FineJOptionPane.showConfirmDialog(dialog, Toolkit.i18nText("Fine-Design_Basic_Utils_Would_You_Like_To_Cover_The_Current_File") + " ?",
Toolkit.i18nText("Fine-Design_Basic_Confirm"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (selVal == JOptionPane.YES_OPTION) {
option = JOPTIONPANE_OK_OPTION;
saveDictionary();
dialogExit();
} else {
option = JOPTIONPANE_CANCEL_OPTION;
}
} else {
dialogExit();
saveDictionary();
}
} else {
FineJOptionPane.showMessageDialog(FILEChooserPane.this, Toolkit.i18nText("Fine-Design_Basic_App_Privilege_No") + "!", Toolkit.i18nText("Fine-Design_Basic_App_File_Message"), JOptionPane.WARNING_MESSAGE);
}
}
private boolean access(FILE selectedFile) {
boolean access = true;
try {
if (selectedFile.isEnvFile() && selectedFile instanceof FileNodeFILE) {
FileNodeFILE fileNodeFILE = ((FileNodeFILE) selectedFile);
access = access && fileNodeFILE.hasFullAuth() && NodeAuthProcessor.getInstance().checkFileNodeAuth(new FileNode(fileNodeFILE.getPath(), fileNodeFILE.isDirectory()));
}
} catch (Exception e) {
FineLoggerFactory.getLogger().error(e.getMessage(), e);
}
return access;
}
private void saveDictionary() {
FILE selectedFile = this.getSelectedFILE();
if (selectedFile != null) {
DesignerEnvManager designerEnvManager = DesignerEnvManager.getEnvManager();
String prefix = currentDirectory.prefix();
String path = currentDirectory.getPath();
designerEnvManager.setCurrentDirectoryPrefix(prefix);
designerEnvManager.setDialogCurrentDirectory(path);
designerEnvManager.saveXMLFile();
}
}
private void dialogExit() {
if (dialog == null) {
return;
}
dialog.setVisible(false);
dialog.dispose();
dialog = null;
}
/*
* dialog的名字
*/
private String dialogName() {
return type == JFileChooser.OPEN_DIALOG ? Toolkit.i18nText("Fine-Design_Basic_Utils_Design_File_Open") : Toolkit.i18nText("Fine-Design_Basic_App_Template_Save");
}
/*
* 在subFileList中选中文件
*/
private void setSelectedFileName(String name) {
if (name == null) {
return;
}
ListModel model = subFileList.getModel();
for (int i = 0, len = model.getSize(); i < len; i++) {
if (ComparatorUtils.equals(name, ((FILE) model.getElementAt(i)).getName())) {
subFileList.setSelectedIndex(i);
break;
}
}
}
@Override
protected String title4PopupWindow() {
return dialogName();
}
private void setPlaceListModel(AbstractPlaceListModel model) {
if (placesList == null) {
return;
}
placesList.setModel(model);
String lastDirectoryPath = DesignerEnvManager.getEnvManager().getDialogCurrentDirectory();
String prefix = DesignerEnvManager.getEnvManager().getCurrentDirectoryPrefix();
FILE lastDirectory = FILEFactory.createFolder(prefix + lastDirectoryPath);
model.setCD(lastDirectory);
if (currentDirectory != null) {
return;
}
// b:这里应该是currentDirectory为空时尝试从envmanager取,最后FileSystemView,和this.env有啥关系
if (StringUtils.isNotBlank(DesignerEnvManager.getEnvManager().getDialogCurrentDirectory())) {
currentDirectory = FILEFactory.createFolder(DesignerEnvManager.getEnvManager().getDialogCurrentDirectory());
} else {
currentDirectory = FILEFactory.createFolder(FileSystemView.getFileSystemView().getHomeDirectory().getPath());
}
if (currentDirectory != null && currentDirectory.exists()) {
this.setCurrentDirectory(currentDirectory);
}
}
private void setPlaceListModel() {
if (placesList == null) {
return;
}
setPlaceListModel(new PlaceListModel());
}
private void setDesignateModel(String path) {
if (placesList == null) {
return;
}
setPlaceListModel(new DesignateRemotePlaceListModel(path));
}
private void setTopPath(String path) {
this.locationBtnPane.setTopPath(path);
}
private void setMultiPlaceListModel() {
if (placesList == null) {
return;
}
setPlaceListModel(new MultiLocalEnvPlaceListModel());
}
/*
* 选中文件
*/
private void setFileTextField(FILE file) {
if (file != null && !file.isDirectory()) {
fileNameTextField.setText(file.getName());
if (file instanceof FileFILE) {
fileNameTextField.setText(((FileFILE) file).getTotalName());
}
}
}
/**
* Sets the current directory. Passing in <code>null</code> sets the file
* chooser to point to the user's default directory.
*
* @param dir the current directory to point to
* @see #setSelectedDirectory
*/
public void setCurrentDirectory(FILE dir) {
if (dir == null && placesList != null) {
dir = (FILE) placesList.getModel().getElementAt(0);
placesList.setSelectedIndex(0);
}
if (placesList != null) {
if (ComparatorUtils.equals(dir.prefix(), FILEFactory.ENV_PREFIX) || dir.prefix().endsWith(FILEFactory.WEBREPORT_PREFIX)) {
placesList.setSelectedIndex(0);
} else if (ComparatorUtils.equals(dir.prefix(), FILEFactory.FILE_PREFIX)) {
AbstractPlaceListModel defaultListModel = (AbstractPlaceListModel) placesList.getModel();
for (int i = 0; i < defaultListModel.getSize(); i++) {
if (defaultListModel.getElementAt(i) instanceof FileFILE) {
FileFILE popDir = (FileFILE) defaultListModel.getElementAt(i);
if (popDir != null && dir.getPath().indexOf(popDir.getPath()) == 0) {
placesList.setSelectedIndex(i);
break;
}
}
}
}
}
setSelectedDirectory(dir);
}
/*
* Set Selected Directory 在右侧的subFileList中显示dir下面的所有文件和文件夹
*/
private void setSelectedDirectory(FILE dir) {
if (ComparatorUtils.equals(currentDirectory, dir) || dir == null || !dir.isDirectory()) {
return;
}
currentDirectory = dir;
this.locationBtnPane.populate(currentDirectory);
this.mkdirButton.setEnabled(currentDirectory != null);
refreshSubFileListModel();
}
/*
* 刷新右侧的SubFileList
*/
private void refreshSubFileListModel() {
if (currentDirectory != null) {
((DefaultListModel) subFileList.getModel()).removeAllElements();
FILE[] res_array = currentDirectory.listFiles();
((DefaultListModel) subFileList.getModel()).removeAllElements();
for (int i = 0; i < res_array.length; i++) {
if (filter == null || filter.accept(res_array[i])) {
((DefaultListModel) subFileList.getModel()).addElement(res_array[i]);
}
}
String[] name_array = new String[res_array.length];
for (int i = 0; i < res_array.length; i++) {
name_array[i] = res_array[i].getName();
}
fileNameTextField.setFilter(new DefaultCompletionFilter(name_array));
subFileList.validate();
subFileList.repaint(10);
}
}
private abstract class AbstractPlaceListModel extends AbstractListModel<FILE> {
private static final long serialVersionUID = 8473695327688235386L;
protected List<FileFILE> filesOfSystem = new ArrayList<FileFILE>();
protected void processSystemFile() {
if (WindowsDetector.detect(true)) {
// windows下展示桌面
File[] desktop = FileSystemView.getFileSystemView().getRoots();
if (desktop != null) {
for (int i = 0; i < desktop.length; i++) {
if (desktop[i].exists()) {
filesOfSystem.add(new FileFILE(desktop[i]));
}
}
}
} else {
// *nix下展示家目录
filesOfSystem.add(new FileFILE(FileSystemView.getFileSystemView().getDefaultDirectory()));
}
// C, D, E等盘符
File[] roots = File.listRoots();
if (roots != null) {
for (int i = 0; i < roots.length; i++) {
if (roots[i].exists()) {
filesOfSystem.add(new FileFILE(roots[i]));
}
}
}
}
protected void setCD(final FILE lastDirectory) {
for (int i = 0; i < this.getSize(); i++) {
FILE file = this.getElementAt(i);
//前缀相同不代表能用啊,比如说 repolets 和 resource ,都是 env下的,但就不该去显示resource下的文件呀
if (ComparatorUtils.equals(lastDirectory.prefix(), file.prefix()) && lastDirectory.getPath() != null && lastDirectory.getPath().startsWith(file.getPath())) {
setCurrentDirectory(lastDirectory);
return;
}
}
setCurrentDirectory(this.getElementAt(0));
}
}
/**
* 一个简单的指定远程目录的 placelistmodel
*/
private class DesignateRemotePlaceListModel extends AbstractPlaceListModel {
private static final long serialVersionUID = -6340666958714469249L;
private FileNodeFILE envFILE;
public DesignateRemotePlaceListModel(String path) {
envFILE = new DesignateFileNodeFILE(new FileNode(path, true)) {
@Override
public String getName() {
return Toolkit.i18nText("Fine-Design_Basic_Utils_Report_Env_Directory_Designate");
}
};
}
@Override
public FILE getElementAt(int index) {
if (index < 1) {
return envFILE;
}
throw new IndexOutOfBoundsException();
}
@Override
public int getSize() {
return 1;
}
@Override
protected void setCD(FILE lastDirectory) {
setCurrentDirectory(envFILE);
}
/**
* 简单的重写了标签的FileNodeFILE
*/
private class DesignateFileNodeFILE extends FileNodeFILE {
public DesignateFileNodeFILE(FileNode node) {
super(node);
}
@Override
public Icon getIcon() {
return BaseUtils.readIcon("/com/fr/base/images/oem/logo.png");
}
}
}
private class PlaceListModel extends AbstractPlaceListModel {
private static final long serialVersionUID = 6138969918807381364L;
private FileNodeFILE envFILE;
private FileNodeFILE webReportFILE;
PlaceListModel() {
if (FILEChooserPane.this.showEnv) {
envFILE = new FileNodeFILE(new FileNode(ProjectConstants.REPORTLETS_NAME, true)) {
@Override
public String getName() {
return getEnvProjectName();
}
};
}
if (FILEChooserPane.this.showWebReport) {
webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath);
}
if (FILEChooserPane.this.showLoc) {
processSystemFile();
}
}
@Override
public FILE getElementAt(int index) {
int n = FILEChooserPane.this.showEnv ? 1 : 0;
int n2 = FILEChooserPane.this.showWebReport ? 1 : 0;
if (index < n) {
return envFILE;
} else if (index < n + n2) {
return webReportFILE;
} else if (index < n + n2 + filesOfSystem.size()) {
return filesOfSystem.get(index - n - n2);
}
throw new IndexOutOfBoundsException();
}
@Override
public int getSize() {
if (FILEChooserPane.this.showEnv && FILEChooserPane.this.showWebReport) {
return 2 + filesOfSystem.size();
} else if (FILEChooserPane.this.showEnv || FILEChooserPane.this.showWebReport) {
return 1 + filesOfSystem.size();
} else {
return filesOfSystem.size();
}
}
}
private class MultiLocalEnvPlaceListModel extends AbstractPlaceListModel {
private static final long serialVersionUID = 6300018896958532154L;
private List<FileFILE> envFiles = new ArrayList<FileFILE>();
private FileNodeFILE webReportFILE;
MultiLocalEnvPlaceListModel() {
Iterator<String> iterator = DesignerEnvManager.getEnvManager().getEnvNameIterator();
while (iterator.hasNext()) {
final String envName = iterator.next();
DesignerWorkspaceInfo info = DesignerEnvManager.getEnvManager().getWorkspaceInfo(envName);
if (info.getType() == DesignerWorkspaceType.Local) {
FileFILE fileFILE =
new FileFILE(new File(info.getPath() + CoreConstants.SEPARATOR + ProjectConstants.REPORTLETS_NAME)) {
@Override
public String getName() {
return envName;
}
};
if (fileFILE.exists() && fileFILE.isDirectory()) {
envFiles.add(fileFILE);
}
}
}
if (FILEChooserPane.this.showWebReport) {
webReportFILE = new FileNodeFILE(FileNodeFILE.webRootPath);
}
if (FILEChooserPane.this.showLoc) {
processSystemFile();
}
}
@Override
public FILE getElementAt(int index) {
int envCount = envFiles.size();
int webReportCount = FILEChooserPane.this.showWebReport ? 1 : 0;
if (index < envCount) {
return envFiles.get(index);
} else if (index < envCount + webReportCount) {
return webReportFILE;
} else if (index < envCount + webReportCount + filesOfSystem.size()) {
return filesOfSystem.get(index - envCount - webReportCount);
}
throw new IndexOutOfBoundsException();
}
@Override
public int getSize() {
int webReportCount = FILEChooserPane.this.showWebReport ? 1 : 0;
return envFiles.size() + filesOfSystem.size() + webReportCount;
}
private class FileFILE extends com.fr.file.FileFILE {
public FileFILE(File file) {
super(file);
}
@Override
public Icon getIcon() {
if (ComparatorUtils.equals(getTotalName(), ProjectConstants.REPORTLETS_NAME)) {
return BaseUtils.readIcon("/com/fr/base/images/oem/logo.png");
} else {
return FileTreeIcon.getIcon(new File(this.getPath()), false);
}
}
@Override
public FILE[] listFiles() {
FILE[] fileFILES = super.listFiles();
List<FileFILE> results = new ArrayList<>();
for (FILE fileFILE : fileFILES) {
results.add(new FileFILE(new File(fileFILE.getPath())));
}
return results.toArray(new FILE[results.size()]);
}
}
}
/*
* 上面的LocationButtonPane
*/
private class LocationButtonPane extends JPanel {
private FILE popDir;
private BasicArrowButton leftArrowButton;
private BasicArrowButton rightArrowButton;
private List<UIButton> buttonList = new ArrayList<>();
private int pathIndex = 0;
private int maxPathIndex = 0;
// 对顶层目录进行的限制
private String topPath;
public LocationButtonPane() {
this.setLayout(FRGUIPaneFactory.createBoxFlowLayout());
leftArrowButton = new BasicArrowButton(BasicArrowButton.WEST) {
@Override
public Dimension getPreferredSize() {
return new Dimension(21, 21);
}
};
leftArrowButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (pathIndex > 0) {
pathIndex--;
}
LocationButtonPane.this.doLayout();
LocationButtonPane.this.repaint(10);
}
});
rightArrowButton = new BasicArrowButton(BasicArrowButton.EAST) {
@Override
public Dimension getPreferredSize() {
return new Dimension(21, 21);
}
};
rightArrowButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (pathIndex < maxPathIndex) {
pathIndex++;
}
LocationButtonPane.this.doLayout();
LocationButtonPane.this.repaint(10);
}
});
EventDispatcher.listen(WorkspaceEvent.AfterSwitch, new Listener<Workspace>() {
@Override
public void on(Event event, Workspace param) {
setPopDir(null);
}
});
}
public void setTopPath(String path) {
this.topPath = path;
}
public void highLightButton(FILE dir) {
for (int i = 0; i < this.buttonList.size(); i++) {
this.buttonList.get(i).setForeground(null);
if (((SetDirectoryAction) this.buttonList.get(i).getAction()).getDir() != null
&& this.buttonList.get(i).getAction() instanceof SetDirectoryAction
&& (ComparatorUtils.equals(((SetDirectoryAction) this.buttonList.get(i).getAction()).getDir().getPath(), dir.getPath()))) {
this.buttonList.get(i).setForeground(Color.BLUE);
}
}
}
public void setPopDir(FILE file) {
popDir = file;
}
public void populate(FILE dir) {
if (popDir != null && dir != null && popDir.toString().indexOf(dir.toString()) == 0) {
highLightButton(dir);
return;
}
boolean isWebAppNamePath;
popDir = dir;
this.buttonList.clear();
if (dir == null) {
return;
}
String path = dir.getPath();
isWebAppNamePath = ComparatorUtils.equals(dir.prefix(), FILEFactory.WEBREPORT_PREFIX);
// 确保最后一个字符是分隔符
if (!path.endsWith("/") && !path.endsWith("\\") && !StringUtils.isBlank(path)) {
path = path + "/";
}
String webAppName = GeneralContext.getCurrentAppNameOfEnv();
if (StringUtils.isBlank(path) && isWebAppNamePath) {
this.buttonList.add(createBlankButton(new SetDirectoryAction(webAppName + '/')));
}
Matcher matcher = SEPARATOR_PATTERN.matcher(path);
int node_start = 0;
boolean needTopPath = !StringUtils.isEmpty(topPath);
while (matcher.find()) {
int start = matcher.start();
String btn_text = path.substring(node_start, start);
String btn_path = path.substring(0, start);
if (StringUtils.isBlank(btn_text) && isWebAppNamePath) {
btn_text = webAppName;
}
node_start = matcher.end();
if (needTopPath && topPath.equals(btn_text)) {
needTopPath = false;
}
this.buttonList.add(createBlankButton((new SetDirectoryAction(btn_text + '/',
// alex:dir.prefix不和btn_path一起参与pathJoin,因为btn_path是否以/打头在unix,linux
// OS中意义很不一样
FILEFactory.createFolder(dir.prefix() + StableUtils.pathJoin(btn_path, "/")), !needTopPath))));
}
maxPathIndex = calculateMaxPathIndex();
pathIndex = maxPathIndex;
this.doLayout();
this.repaint(10);
// 高亮显示当前目录
highLightButton(dir);
}
// doLayout
@Override
public void doLayout() {
this.removeAll();
if (popDir == null) {
return;
}
int pathWidth = 0;
// 前缀
// UILabel prefixLabel = new UILabel(popDir.prefix());
// this.add(prefixLabel);
// pathWidth += prefixLabel.getPreferredSize().width;
// pathWidth
for (int i = 0; i < buttonList.size(); i++) {
pathWidth += buttonList.get(i).getPreferredSize().width;
}
// 当path按钮的长度超出显示范围时,隐藏
if (this.getWidth() < pathWidth) {
int tmpWidth = leftArrowButton.getPreferredSize().width + leftArrowButton.getPreferredSize().width;
int oldTmpWidth = tmpWidth;
for (int i = pathIndex; i < buttonList.size(); i++) {
tmpWidth += buttonList.get(i).getPreferredSize().width;
if (tmpWidth > this.getWidth()) {
break;
}
this.add(buttonList.get(i));
oldTmpWidth = tmpWidth;
}
UILabel blankLabel = new UILabel("");
blankLabel.setPreferredSize(new Dimension(this.getWidth() - oldTmpWidth - 1, blankLabel.getPreferredSize().height));
this.add(blankLabel);
// leftArrowButton
this.add(leftArrowButton, 1);
// rightArrowButton
this.add(rightArrowButton);
} else {
pathIndex = 0;
for (int i = 0; i < buttonList.size(); i++) {
this.add(buttonList.get(i));
}
}
super.doLayout();
}
private int calculateMaxPathIndex() {
if (popDir == null) {
return 0;
}
int pathWidth = 0;
// 前缀
UILabel prefixLabel = new UILabel(popDir.prefix());
pathWidth += prefixLabel.getPreferredSize().width;
for (int i = 0; i < buttonList.size(); i++) {
pathWidth += buttonList.get(i).getPreferredSize().width;
}
if (this.getWidth() < pathWidth) {
int index = 0;
int tmpWidth = prefixLabel.getPreferredSize().width + leftArrowButton.getPreferredSize().width
+ leftArrowButton.getPreferredSize().width;
for (int i = buttonList.size() - 1; i >= 0; i--) {
tmpWidth += buttonList.get(i).getPreferredSize().width;
if (tmpWidth > this.getWidth()) {
break;
}
index = i;
}
return index;
}
// 当长度足够时,不出现左右的按钮,皆从0开始显示
else {
return 0;
}
}
}
private class SetDirectoryAction extends UpdateAction {
private FILE dir;
private boolean response = true;
public SetDirectoryAction(String name) {
this.setName(name);
// this.dir = file;
}
public SetDirectoryAction(String name, FILE file) {
this.setName(name);
this.dir = file;
}
public SetDirectoryAction(String name, FILE file, boolean response) {
this.setName(name);
this.dir = file;
this.response = response;
}
@Override
public void actionPerformed(ActionEvent evt) {
if (dir != null && response) {
setSelectedDirectory(dir);
}
}
public FILE getDir() {
return dir;
}
}
private UIButton createBlankButton(SetDirectoryAction setDirectoryAction) {
final Color brighter = this.getBackground().brighter();
final Color darker = this.getBackground().darker();
final UIButton blankButton = new UIButton(setDirectoryAction);
blankButton.setMargin(new Insets(0, 0, 0, 0));
blankButton.setUI(new BasicButtonUI());
blankButton.setHorizontalTextPosition(SwingConstants.CENTER);
blankButton.setBorderPainted(false);
blankButton.setBorder(BorderFactory.createRaisedBevelBorder());
blankButton.setBackground(darker);
blankButton.addMouseListener(new MouseAdapter() {
@Override
public void mouseEntered(MouseEvent e) {
blankButton.setBackground(brighter);
blankButton.setBorderPainted(true);
blankButton.repaint();
}
@Override
public void mouseExited(MouseEvent e) {
blankButton.setBackground(darker);
blankButton.setBorderPainted(false);
blankButton.repaint();
}
@Override
public void mousePressed(MouseEvent e) {
blankButton.setBackground(brighter);
blankButton.setBorderPainted(false);
blankButton.repaint();
}
@Override
public void mouseReleased(MouseEvent e) {
blankButton.setBackground(darker);
blankButton.setBorderPainted(true);
blankButton.repaint();
}
});
return blankButton;
}
/*
* 新建文件夹的Button
*/
private UIButton initMkdirButton() {
UIButton folderButton = new UIButton();
folderButton.setIcon(BaseUtils.readIcon("com/fr/design/images/icon_NewFolderIcon_normal.png"));
folderButton.setUI(new UIButtonUI());
folderButton.setToolTipText(Toolkit.i18nText("Fine-Design_Basic_Utils_New_Folder"));
folderButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent evt) {
if (currentDirectory == null) {
return;
}
if (access(currentDirectory)) {
new MkdirDialog();
} else {
FineJOptionPane.showMessageDialog(
FILEChooserPane.this,
Toolkit.i18nText("Fine-Design_Basic_App_Privilege_No") + "!",
Toolkit.i18nText("Fine-Design_Basic_App_File_Message"),
JOptionPane.WARNING_MESSAGE);
}
}
});
return folderButton;
}
/**
* 新建文件夹对话框
* 支持快捷键Enter,ESC
*/
private class MkdirDialog extends JDialog {
private UITextField nameField;
private UILabel warnLabel;
private UIButton confirmButton;
private MkdirDialog() {
this.setLayout(new BorderLayout());
this.setModal(true);
// 输入框前提示
UILabel newNameLabel = new UILabel(Toolkit.i18nText(
"Fine-Design_Basic_Enter_New_Folder_Name")
);
newNameLabel.setHorizontalAlignment(SwingConstants.RIGHT);
newNameLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 10));
newNameLabel.setPreferredSize(new Dimension(118, 15));
// 文件名输入框
nameField = new UITextField();
nameField.getDocument().addDocumentListener(new DocumentListener() {
public void changedUpdate(DocumentEvent e) {
validInput();
}
public void insertUpdate(DocumentEvent e) {
validInput();
}
public void removeUpdate(DocumentEvent e) {
validInput();
}
});
nameField.selectAll();
nameField.setPreferredSize(new Dimension(180, 20));
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 5));
topPanel.setBorder(BorderFactory.createEmptyBorder(15, 15, 0, 15));
topPanel.add(newNameLabel);
topPanel.add(nameField);
// 增加enter以及esc快捷键的支持
nameField.addKeyListener(new KeyAdapter() {
@Override
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_ESCAPE) {
dispose();
} else if (e.getKeyCode() == KeyEvent.VK_ENTER) {
if (confirmButton.isEnabled()) {
confirmClose();
}
}
}
});
// 重名提示
warnLabel = new UILabel();
warnLabel.setPreferredSize(new Dimension(300, 30));
warnLabel.setHorizontalAlignment(SwingConstants.LEFT);
warnLabel.setForeground(Color.RED);
warnLabel.setVisible(false);
JPanel midPanel = new JPanel(new BorderLayout());
midPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15));
midPanel.add(warnLabel, BorderLayout.WEST);
// 确认按钮
confirmButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Confirm"));
confirmButton.setPreferredSize(new Dimension(60, 25));
confirmButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
confirmClose();
}
});
// 取消按钮
UIButton cancelButton = new UIButton(Toolkit.i18nText("Fine-Design_Basic_Cancel"));
cancelButton.setPreferredSize(new Dimension(60, 25));
cancelButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
dispose();
}
});
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT));
bottomPanel.setBorder(BorderFactory.createEmptyBorder(0, 15, 0, 15));
bottomPanel.add(confirmButton);
bottomPanel.add(cancelButton);
this.add(
TableLayoutHelper.createTableLayoutPane(
new Component[][]{
new Component[]{topPanel},
new Component[]{midPanel},
new Component[]{bottomPanel}
},
new double[]{TableLayout.FILL, TableLayout.FILL, TableLayout.FILL},
new double[]{TableLayout.FILL}
),
BorderLayout.CENTER);
this.setSize(340, 180);
this.setTitle(Toolkit.i18nText("Fine-Design_Basic_Mkdir"));
this.setResizable(false);
this.setAlwaysOnTop(true);
this.setIconImage(BaseUtils.readImage("/com/fr/base/images/oem/logo.png"));
this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
GUICoreUtils.centerWindow(this);
this.setVisible(true);
}
private void confirmClose() {
String userInput = nameField.getText().trim();
// 处理不合法的文件夹名称
userInput = userInput.replaceAll("[\\\\/:*?\"<>|]", StringUtils.EMPTY);
if (currentDirectory.createFolder(userInput)) {
refreshSubFileListModel();
setSelectedFileName(userInput);
// ben:这里处理有些不妥,取文件时没有考虑filefilter,不过效果一样,取的时候应该用subfilelist得data
FILE[] allFiles = currentDirectory.listFiles();
int place = 0;
for (int i = 0; i < allFiles.length; i++) {
if (ComparatorUtils.equals(allFiles[i].getName(), userInput) && allFiles[i].isDirectory()) {
place = i;
break;
}
}
scrollPane.revalidate();
scrollPane.repaint();
int total = scrollPane.getVerticalScrollBar().getMaximum();
int value = total * place / subFileList.getModel().getSize();
scrollPane.getVerticalScrollBar().setValue(value);
} else {
FineJOptionPane.showConfirmDialog(FILEChooserPane.this,
Toolkit.i18nText("Fine-Design_Basic_Make_Failure"),
Toolkit.i18nText("Fine-Design_Basic_Error"),
JOptionPane.DEFAULT_OPTION,
JOptionPane.ERROR_MESSAGE);
}
this.dispose();
}
private void validInput() {
String userInput = nameField.getText().trim();
if (StringUtils.isEmpty(userInput)) {
confirmButton.setEnabled(false);
}
boolean duplicate = false;
// ben:这里处理有些不妥,取文件时没有考虑filefilter,不过效果一样,取的时候应该用subfilelist得data
FILE[] allFiles = currentDirectory.listFiles();
for (int i = 0; i < allFiles.length; i++) {
if (ComparatorUtils.equals(allFiles[i].getName(), userInput) && allFiles[i].isDirectory()) {
duplicate = true;
break;
}
}
if (duplicate) {
nameField.selectAll();
// 如果文件名已存在,则灰掉确认按钮
warnLabel.setText(
Toolkit.i18nText(
"Fine-Design_Basic_Folder_Name_Duplicate",
userInput));
warnLabel.setVisible(true);
confirmButton.setEnabled(false);
} else {
warnLabel.setVisible(false);
confirmButton.setEnabled(true);
}
}
}
}