package bs.util.tool.commongui.plugins.more;
import java.awt.BorderLayout;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import org.mozilla.universalchardet.UniversalDetector;
import bs.util.io.PropertiesUtils;
import bs.util.tool.commongui.GuiJPanel;
import bs.util.tool.commongui.GuiUtils;
import bs.util.tool.commongui.utils.FileUtils;
import bs.util.tool.commongui.utils.SearchFileNameParams;
/**
* 文本编码识别.
*/
public class JUniversalChardet extends GuiJPanel {
private static final long serialVersionUID = 1L;
/**
* 探测文本/文件夹路径表单.
*/
private JTextField detectPathTextField = new JTextField();
/**
* 探测文本/文件夹路径选择.
*/
private JFileChooser detectPath_Chooser = new JFileChooser();
/**
* 探测按钮.
*/
private JButton detectButton;
/**
* 取样大小表单.
*/
private JTextField detectSizeTextField = new JTextField("4096", 7);
/**
* 文件名包含字符表单.
*/
private JTextField fileNameContainsTextField;
/**
* 文件名不包含字符表单.
*/
private JTextField fileNameNotContainsTextField;
/**
* 文件名是否支持正则.
*/
private boolean fileNameSupportRegex = true;
/**
* 探测结果文本域.
*/
private JTextArea resultTextArea = createJTextArea(GuiUtils.font14_un);
public JUniversalChardet() {
// 主面板:边界布局,分North、Center两部分,North用于放置输入及条件控件,Center是放置探测结果输出
setLayout(new BorderLayout());
// 输入及条件Panel
JPanel inputPanel = new JPanel(new GridLayout(2, 1));
// 探测文本/文件夹表单、探测按钮Panel
JPanel fileChooAndDetectPanel = new JPanel(new BorderLayout());
// 探测文本/文件夹表单
addJLabel(fileChooAndDetectPanel, " 探测文本/文件夹: ", GuiUtils.font14_cn, BorderLayout.WEST);
JPanel fileChooPanel = new JPanel(new BorderLayout());
fileChooPanel.add(new JPanel(), BorderLayout.NORTH);
addJTextField(fileChooPanel, detectPathTextField, GuiUtils.font14_un, BorderLayout.CENTER);
fileChooPanel.add(new JPanel(), BorderLayout.SOUTH);
fileChooAndDetectPanel.add(fileChooPanel, BorderLayout.CENTER);
JPanel buttonFlowPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
addJButton(buttonFlowPanel, "浏览", "", GuiUtils.font12_cn,
buttonBrowseListener(detectPath_Chooser, detectPathTextField));
// 探测按钮
detectButton = createJButton("探测", "", GuiUtils.font14b_cn);
detectButton.addMouseListener(new MouseListener() {
public void mouseReleased(MouseEvent event) {
String path = detectPathTextField.getText().trim();
File file = new File(path);
if (!file.exists()) {
showMessage("探测文本/文件夹不存在!", "警告", JOptionPane.WARNING_MESSAGE);
return;
}
Map<String, Object> paramsMap = new HashMap<String, Object>();
paramsMap.put("fileNameContainsText", fileNameContainsTextField.getText().trim());
paramsMap.put("fileNameNotContainsText", fileNameNotContainsTextField.getText().trim());
paramsMap.put("fileNameSupportRegex", fileNameSupportRegex);
detectButton.setEnabled(false);
resultTextArea.setText("");
try {
int detectLength = Integer.parseInt(detectSizeTextField.getText().trim());
if (!file.isDirectory()) {
appendDetectResult(resultTextArea, file, detectLength);
} else {
List<File> files = new ArrayList<File>();
FileUtils.loopDirectory(file, files, new SearchFileNameParams(paramsMap));
for (File fFile : files) {
appendDetectResult(resultTextArea, fFile, detectLength);
}
resultTextArea.append("\nCount files: " + files.size());
}
} catch (NumberFormatException e) {
showMessage("取样大小必须是正整数!", "警告", JOptionPane.WARNING_MESSAGE);
} catch (IOException e) {
showExceptionMessage(e);
}
detectButton.setEnabled(true);
}
public void mousePressed(MouseEvent e) {
resultTextArea.setText("");
}
public void mouseExited(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseClicked(MouseEvent e) {
}
});
buttonFlowPanel.add(detectButton);
// 探测路径选择控件
detectPath_Chooser.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES); // 可选择文件/文件夹
fileChooAndDetectPanel.add(buttonFlowPanel, BorderLayout.EAST);
inputPanel.add(fileChooAndDetectPanel);
// 高级条件Panel
JPanel advancePanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
// 取样大小
addJLabel(advancePanel, " ", GuiUtils.font12_cn);
addJLabel(advancePanel, "取样大小: ", GuiUtils.font14_cn);
addJTextField(advancePanel, detectSizeTextField, GuiUtils.font14_cn);
addJLabel(advancePanel, "Byte", GuiUtils.font14_cn);
// 文件名包含(不包含)字符
String confPropsFile = "conf/JUniversalChardet/searchFiletypes.properties";
String containsFiletypes = "";
String notContainsFiletypes = "";
try {
Properties confProperties = PropertiesUtils.getProperties(GuiUtils.getActualPath(confPropsFile));
containsFiletypes = confProperties.getProperty("ContainsFiletypes").trim();
notContainsFiletypes = confProperties.getProperty("NotContainsFiletypes").trim();
} catch (IOException e) {
logLoadPropertiesException(confPropsFile, e);
}
addJLabel(advancePanel, " 文件名包含字符: ", GuiUtils.font14_cn);
String fileNameContains = containsFiletypes.length() > 0 ? "\\.(" + containsFiletypes.replace(",", "|") + ")$"
: "";
fileNameContainsTextField = new JTextField(fileNameContains, 15);
addJTextField(advancePanel, fileNameContainsTextField, GuiUtils.font14_un);
addJLabel(advancePanel, " 文件名不包含字符: ", GuiUtils.font14_cn);
String fileNameNotContains = notContainsFiletypes.length() > 0 ? "\\.("
+ notContainsFiletypes.replace(",", "|") + ")$" : "";
fileNameNotContainsTextField = new JTextField(fileNameNotContains, 15);
addJTextField(advancePanel, fileNameNotContainsTextField, GuiUtils.font14_un);
// 是否支持正则
addJCheckBox(advancePanel, "支持正则", true, GuiUtils.font14_cn, new ActionListener() {
public void actionPerformed(ActionEvent event) {
fileNameSupportRegex = ((JCheckBox) event.getSource()).isSelected();
}
});
inputPanel.add(advancePanel);
add(inputPanel, BorderLayout.NORTH);
// 探测结果输出
JPanel detectLogPanel = new JPanel(new BorderLayout());
detectLogPanel.add(new JScrollPane(resultTextArea));
add(detectLogPanel, BorderLayout.CENTER);
}
/**
* append探测文本编码结果.
*/
private void appendDetectResult(JTextArea resultTextArea, File file, int detectLength) throws IOException {
resultTextArea.append(file.getAbsolutePath() + " Charset: " + detectFileCharset(file, detectLength)
+ "\n");
}
/**
* 探测文本编码.
*/
public static String detectFileCharset(File file, int detectLength) throws IOException {
String charset = null;
FileInputStream fis = null;
try {
byte[] buf = new byte[detectLength];
fis = new FileInputStream(file);
UniversalDetector detector = new UniversalDetector(null);
int nread;
while ((nread = fis.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread);
}
detector.dataEnd();
charset = detector.getDetectedCharset();
detector.reset();
} finally {
if (fis != null) {
fis.close();
}
}
return charset;
}
}