demo简略需求
项目背景
很多文件重复存放,除了管理混乱,还会对患有强迫症用户的身心造成10000点的伤害...其实就是360云盘当时上传了有上传,造成很多重复的图片+视频,前阵子360个人云盘“倒闭”,电脑日夜兼程,始终把图片下了下来,下下来后,作为重度强迫症患者的我,看着无数张图片里面n多重复文件,吃不香睡不着....
点击“载入”,默认载入上次目录,若是第一次,默认载入文档图片目录,同时弹出“选择路径”菜单。选择需要载入的文件目录后,如果跟现载入的不一样,则中断载入操作,重新载入新路径。若一样,则继续载入;
图片预览,默认显示第一张,如果用户点击选择某一张,则图片预览变为用户选中的;
点击去重,弹出“重速度”(多线程),“重性能”(单线程)
点击撤销,恢复去重时删除的文件
去重:先判断文件名(除去“ - 副本”、“(1)”之类结尾的字符)是否重复,再判断文件大小+文件类型是否一样,如果都一样,则计算文件的md5值,通过md5值来判断。
第一次启动时,弹出倒计时框,提示去重撤销需要创建一个隐藏文件,如果不需要撤销,可以打钩,不创建隐藏文件,而是直接删除;
弹出免责声明,数据无价,请确认再去重(删除)。
UI样图,如下图
------------------------------------------------------------------------------------------
想用java写个桌面小demo,就布局都差点写吐血了,最终还是没学好,哎,都怪学艺不精
界面实现代码
package zuiquchong;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
/**
* @author 苏宝伢 E-mail:by.su@qq.com
* @version 创建时间: 2017年4月5日 下午12:47:32
*/
public class RemovalUI extends JFrame{
JPanel JPanelTitle,JPanelTextArea,JPanelLblPreview,JPanelOperation,JPanelContainer,JPanelLblStatusBar;
JButton btnLoader,btnRemoval,btnCancel,btnHistory;
JTextArea displayContent;
JLabel lblTitle,lblPreviewContent,lblStatusBar;
public RemovalUI(){
super("最去重文件管理器");
initialization();
}
public static void main(String[] args) {
new RemovalUI();
}
//初始化UI窗体
public void initialization(){
buildComponent();
addComponentToPanel();
componentStyle();
uiLayout();
this.setSize(800, 600);
this.setResizable(false); //不能改变大小
this.setVisible(true); //设置窗口可见
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//创建各组件对象
public void buildComponent(){
JPanelTextArea = new JPanel();
JPanelContainer = new JPanel();
JPanelLblPreview = new JPanel();
JPanelOperation = new JPanel();
JPanelTitle = new JPanel();
JPanelLblStatusBar = new JPanel();
displayContent = new JTextArea(30,48);
lblTitle = new JLabel("最去重文件管理器",SwingConstants.CENTER);
lblPreviewContent = new JLabel();
btnLoader = new JButton("载入");
btnRemoval = new JButton("去重");
btnCancel = new JButton("撤销");
btnHistory = new JButton("历史记录");
lblStatusBar = new JLabel("by不最醉不龟归 | e-mail:by.su@qq.com",SwingConstants.RIGHT);
}
//往容器中添加组件
public void addComponentToPanel(){
this.add(JPanelTitle);
//this.add(JPanelTextArea);
this.add(JPanelContainer);
this.add(JPanelLblStatusBar);
JPanelTitle.add(lblTitle);
JPanelTextArea.add(displayContent);
JPanelLblStatusBar.add(lblStatusBar);
}
//窗体布局
public void uiLayout(){
//==============总体布局================================
this.setLayout(new BorderLayout(10,10));//边界布局
this.add(JPanelTextArea,BorderLayout.WEST);
this.add(JPanelContainer,BorderLayout.EAST);
this.add(JPanelTitle,BorderLayout.NORTH);
this.add(JPanelLblStatusBar,BorderLayout.SOUTH);
//===============右侧布局================================
JPanelContainer.setLayout(new GridLayout(2,1));//网格布局
JPanelContainer.add(lblPreviewContent);
JPanelContainer.add(JPanelOperation);
//================右下布局===============================
JPanelOperation.setLayout(null);//无布局,绝对布局
JPanelOperation.add(btnLoader);
JPanelOperation.add(btnRemoval);
JPanelOperation.add(btnCancel);
JPanelOperation.add(btnHistory);
btnLoader.setBounds(260,30,120,30);
btnRemoval.setBounds(260,80,120,30);
btnCancel.setBounds(260,130,120,30);
btnHistory.setBounds(260,180,120,30);
}
//组件样式
public void componentStyle(){
lblTitle.setFont(new java.awt.Font("",1,20));//设置lblTitle字体和大小
lblTitle.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));//设置lblTitle边框,上左下右
lblPreviewContent.setIcon(new ImageIcon("D://DSC_0675.jpg"));
lblPreviewContent.setSize(10,10);
btnLoader.setPreferredSize(new Dimension(30,30));
btnLoader.setBorderPainted(false);
btnRemoval.setBorderPainted(false);
btnCancel.setBorderPainted(false);
btnHistory.setBorderPainted(false);
//lblStatusBar.setBorder(BorderFactory.createEmptyBorder(580, 560, 0, 0));//状态栏个人信息向右对齐
}
}
-----------未完待续
package zuiquchong;
import java.io.File;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
/**
* @author 苏宝伢 E-mail:by.su@qq.com
* @version 创建时间: 2017年4月10日 下午2:25:10
*/
public class FileOperation {
//String strFilePath;
//显示目录下所有文件夹和文件,待用递归完善
public List displayFile(String strFilePath){
File f = new File(strFilePath);
File[] fileList = f.listFiles();
List fileNameList = new ArrayList<>();
for(File file:fileList){
fileNameList.add(file.getAbsolutePath());
}
return fileNameList;
}
}
package zuiquchong;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.FocusEvent;
import java.awt.event.FocusListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
import javax.swing.event.CaretEvent;
import javax.swing.event.CaretListener;
/**
* @author 苏宝伢 E-mail:by.su@qq.com
* @version 创建时间: 2017年4月5日 下午12:47:32
*/
public class RemovalUI extends JFrame{
JPanel JPanelTitle,JPanelTextArea,JPanelLblPreview,JPanelOperation,JPanelContainer,JPanelLblStatusBar;
JButton btnLoader,btnRemoval,btnRecovery,btnHistory;
JTextArea displayContent;
JScrollPane scroll;
JLabel lblTitle,lblPreviewContent,lblStatusBar;
public RemovalUI(){
super("最去重文件管理器");
initialization();
}
public static void main(String[] args) {
new RemovalUI();
}
//初始化UI窗体
public void initialization(){
buildComponent();
addComponentToPanel();
componentStyle();
uiLayout();
this.setSize(800, 600);
this.setResizable(false); //不能改变大小
this.setVisible(true); //设置窗口可见
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//创建各组件对象、添加监听对象、注册监听
public void buildComponent(){
JPanelTextArea = new JPanel();
JPanelTextArea = new JPanel();
JPanelContainer = new JPanel();
JPanelLblPreview = new JPanel();
JPanelOperation = new JPanel();
JPanelTitle = new JPanel();
JPanelLblStatusBar = new JPanel();
displayContent = new JTextArea(29,48);
scroll = new JScrollPane(displayContent);//添加滚动条
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);//添加垂直方向滚动条
scroll.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED); //添加水平方向滚动条
lblTitle = new JLabel("最去重文件管理器",SwingConstants.CENTER);
lblPreviewContent = new JLabel();
btnLoader = new JButton("载入");
btnRemoval = new JButton("去重");
btnRecovery = new JButton("撤销");
btnHistory = new JButton("历史记录");
lblStatusBar = new JLabel("by不最醉不龟归 | e-mail:by.su@qq.com",SwingConstants.RIGHT);
//---创建监听对象
ButtonListener uiEvent = new ButtonListener();
FocusEventListener focusEvent = new FocusEventListener();
MouseEventListener mouseEvent = new MouseEventListener();
//注册监听btnLoader
btnLoader.addActionListener(uiEvent);
//注册监听btnRemoval
btnRemoval.addActionListener(uiEvent);
//注册监听btnCancel
btnRecovery.addActionListener(uiEvent);
//注册监听btnHistory
btnHistory.addActionListener(uiEvent);
//注册监听
displayContent.addFocusListener(focusEvent);
displayContent.addMouseListener(mouseEvent);
}
//往容器中添加组件
public void addComponentToPanel(){
this.add(JPanelTitle);
this.add(JPanelContainer);
this.add(JPanelLblStatusBar);
JPanelTitle.add(lblTitle);
JPanelTextArea.add(scroll);
//JPanelTextArea.add(displayContent);
JPanelLblStatusBar.add(lblStatusBar);
}
//窗体布局
public void uiLayout(){
//==============总体布局================================
this.setLayout(new BorderLayout(10,10));//边界布局
this.add(JPanelTextArea,BorderLayout.WEST);
this.add(JPanelContainer,BorderLayout.EAST);
this.add(JPanelTitle,BorderLayout.NORTH);
this.add(JPanelLblStatusBar,BorderLayout.SOUTH);
//===============右侧布局================================
JPanelContainer.setLayout(new GridLayout(2,1));//网格布局
JPanelContainer.add(lblPreviewContent);
JPanelContainer.add(JPanelOperation);
//================右下布局===============================
JPanelOperation.setLayout(null);//无布局,绝对布局
JPanelOperation.add(btnLoader);
JPanelOperation.add(btnRemoval);
JPanelOperation.add(btnRecovery);
JPanelOperation.add(btnHistory);
btnLoader.setBounds(260,30,120,30);
btnRemoval.setBounds(260,80,120,30);
btnRecovery.setBounds(260,130,120,30);
btnHistory.setBounds(260,180,120,30);
}
//组件样式
public void componentStyle(){
lblTitle.setFont(new java.awt.Font("",1,20));//设置lblTitle字体和大小
lblTitle.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));//设置lblTitle边框,上左下右
lblPreviewContent.setIcon(new ImageIcon("D://bysu//个人知识拓展//机器学习//PB1636 王者归来:OpenCV3使用Java开发手册//PB1636//samples//DSC_0675.jpg"));
lblPreviewContent.setSize(10,10);
btnLoader.setPreferredSize(new Dimension(30,30));
btnLoader.setBorderPainted(false);
btnRemoval.setBorderPainted(false);
btnRecovery.setBorderPainted(false);
btnHistory.setBorderPainted(false);
//lblStatusBar.setBorder(BorderFactory.createEmptyBorder(580, 560, 0, 0));//状态栏个人信息向右对齐
}
//Button按钮的内部监听类
class ButtonListener implements ActionListener{
String strPath = "D:\\Users\\EX-SUBAOYA001\\Documents";
@Override
public void actionPerformed(ActionEvent e){
Object source = e.getSource();
if(source == btnLoader){ //点击载入
displayContent.setText("");
FileOperation f = new FileOperation();
List list = f.displayFile(strPath);
for(Object obj:list){
displayContent.append((String)obj);
displayContent.append("\r\n");
}
//打开一个文件对话框
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );
int chooseValue = fc.showOpenDialog(null);
if(chooseValue==JFileChooser.APPROVE_OPTION){
String chooseFilePath = fc.getSelectedFile().getPath();
if(!chooseFilePath.equals(strPath)){
displayContent.setText("");
list = f.displayFile(chooseFilePath);
for(Object obj:list){
displayContent.append((String)obj);
displayContent.append("\r\n");
}
strPath = chooseFilePath;
}else{
System.out.println("选中的文件目录与现在的一样");
}
}else{
System.out.println("没有选中文件夹");
}
}else if(source == btnRemoval){ //点击去重
System.out.println("btnRemoval");
}else if(source == btnRecovery){ //点击撤销
System.out.println("btnCancel");
}else{ //显示历史记录
System.out.println("btnHistory");
}
}
}
//FocusEvent焦点触发
class FocusEventListener implements FocusListener{
@Override
public void focusGained(FocusEvent e) {
Object source = e.getSource();
if(source == displayContent){
if(displayContent.getText()!=""){
System.out.println("点击文本编辑框" + displayContent.getRows());
}else{
System.out.println("文本框非空");
}
}
}
@Override
public void focusLost(FocusEvent e) {
}
}
//鼠标监听类
class MouseEventListener implements MouseListener{
FileOperation f = new FileOperation();
int count =0;
@Override
public void mouseClicked(MouseEvent e) {
Object source = e.getSource();
if(source == displayContent){
System.out.println(getRowText(displayContent.getText()));
}
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
}
//JTextArea内容
FileOperation f = new FileOperation();
//显示JTextArea控件中所在行的内容
public String getRowText(String text){
public int rows = 0;
displayContent.addCaretListener(new CaretListener() {
public void caretUpdate(CaretEvent e) {
try {
int offset = e.getDot() ; //获得插入符的位置。
//getLineOfOffset(int offset) 将组件文本中的偏移量转换为行号
int row = displayContent.getLineOfOffset(offset);
//getLineStartOffset(int line) 取得给定行起始处的偏移量。
//getLineEndOffset(int line) 取得给定行结尾处的偏移量。
int column = e.getDot() - displayContent.getLineStartOffset(row);
// 在状态栏中显示当前光标所在行号、所在列号
System.out.println("Line: " + (row + 1) + ", Column: " + (column+1));
row = displayContent.getLineStartOffset(row+1);
System.out.println(row +"fffff");
} catch (Exception ex) {
ex.printStackTrace();
}
}
});
String getText="";
String regex = "\n";
Pattern p =Pattern.compile(regex);
String[] r = p.split(text);
if(!((r[rows-1].trim()).equals(""))){
getText = r[rows-1];
}
return getText;
}
}
/*package zuiquchong;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingConstants;
*//**
* @author 苏宝伢 E-mail:by.su@qq.com
* @version 创建时间: 2017年4月5日 下午12:47:32
*//*
public class RemovalUI extends JFrame{
JPanel JPanelTitle,JPanelTextArea,JPanelLblPreview,JPanelOperation,JPanelContainer,JPanelLblStatusBar;
JButton btnLoader,btnRemoval,btnCancel,btnHistory;
JTextArea displayContent;
JScrollPane scroll;
JLabel lblTitle,lblPreviewContent,lblStatusBar;
public RemovalUI(){
super("最去重文件管理器");
initialization();
}
public static void main(String[] args) {
new RemovalUI();
}
//初始化UI窗体
public void initialization(){
buildComponent();
addComponentToPanel();
componentStyle();
uiLayout();
this.setSize(800, 600);
this.setResizable(false); //不能改变大小
this.setVisible(true); //设置窗口可见
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
//创建各组件对象、添加监听对象、注册监听
public void buildComponent(){
JPanelTextArea = new JPanel();
JPanelTextArea = new JPanel();
JPanelContainer = new JPanel();
JPanelLblPreview = new JPanel();
JPanelOperation = new JPanel();
JPanelTitle = new JPanel();
JPanelLblStatusBar = new JPanel();
displayContent = new JTextArea(30,48);
scroll = new JScrollPane(displayContent);//添加滚动条
scroll.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
lblTitle = new JLabel("最去重文件管理器",SwingConstants.CENTER);
lblPreviewContent = new JLabel();
btnLoader = new JButton("载入");
btnRemoval = new JButton("去重");
btnCancel = new JButton("撤销");
btnHistory = new JButton("历史记录");
lblStatusBar = new JLabel("by不最醉不龟归 | e-mail:by.su@qq.com",SwingConstants.RIGHT);
//---创建监听对象
ButtonListener uiEvent = new ButtonListener();
//注册监听btnLoader
btnLoader.addActionListener(uiEvent);
//注册监听btnRemoval
btnRemoval.addActionListener(uiEvent);
//注册监听btnCancel
btnCancel.addActionListener(uiEvent);
//注册监听btnHistory
btnHistory.addActionListener(uiEvent);
}
//往容器中添加组件
public void addComponentToPanel(){
this.add(JPanelTitle);
this.add(JPanelContainer);
this.add(JPanelLblStatusBar);
JPanelTitle.add(lblTitle);
JPanelTextArea.add(displayContent);
JPanelLblStatusBar.add(lblStatusBar);
}
//窗体布局
public void uiLayout(){
//==============总体布局================================
this.setLayout(new BorderLayout(10,10));//边界布局
this.add(JPanelTextArea,BorderLayout.WEST);
this.add(JPanelContainer,BorderLayout.EAST);
this.add(JPanelTitle,BorderLayout.NORTH);
this.add(JPanelLblStatusBar,BorderLayout.SOUTH);
//===============右侧布局================================
JPanelContainer.setLayout(new GridLayout(2,1));//网格布局
JPanelContainer.add(lblPreviewContent);
JPanelContainer.add(JPanelOperation);
//================右下布局===============================
JPanelOperation.setLayout(null);//无布局,绝对布局
JPanelOperation.add(btnLoader);
JPanelOperation.add(btnRemoval);
JPanelOperation.add(btnCancel);
JPanelOperation.add(btnHistory);
btnLoader.setBounds(260,30,120,30);
btnRemoval.setBounds(260,80,120,30);
btnCancel.setBounds(260,130,120,30);
btnHistory.setBounds(260,180,120,30);
}
//组件样式
public void componentStyle(){
lblTitle.setFont(new java.awt.Font("",1,20));//设置lblTitle字体和大小
lblTitle.setBorder(BorderFactory.createEmptyBorder(10, 0, 0, 0));//设置lblTitle边框,上左下右
lblPreviewContent.setIcon(new ImageIcon("D://bysu//个人知识拓展//机器学习//PB1636 王者归来:OpenCV3使用Java开发手册//PB1636//samples//DSC_0675.jpg"));
lblPreviewContent.setSize(10,10);
btnLoader.setPreferredSize(new Dimension(30,30));
btnLoader.setBorderPainted(false);
btnRemoval.setBorderPainted(false);
btnCancel.setBorderPainted(false);
btnHistory.setBorderPainted(false);
//lblStatusBar.setBorder(BorderFactory.createEmptyBorder(580, 560, 0, 0));//状态栏个人信息向右对齐
}
//内部监听类
class ButtonListener implements ActionListener{
@Override
public void actionPerformed(ActionEvent e){
Object source = e.getSource();
if(source == btnLoader){
displayContent.setText("");
String strPath = "D:/Users/EX-SUBAOYA001/Documents";
FileOperation f = new FileOperation();
List list = f.displayFile(strPath);
for(Object obj:list){
displayContent.append((String)obj);
displayContent.append("\r\n");
}
//打开一个文件对话框
JFileChooser fc = new JFileChooser();
fc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES );
fc.showOpenDialog(null);
String chooseFilePath = fc.getSelectedFile().getPath();
if(chooseFilePath!=strPath){
displayContent.setText("");
list = f.displayFile(chooseFilePath);
for(Object obj:list){
displayContent.append((String)obj);
displayContent.append("\r\n");
}
}else{
}
}else if(source == btnRemoval){
System.out.println("btnRemoval");
}else if(source == btnCancel){
System.out.println("btnCancel");
}else{
System.out.println("btnHistory");
}
}
}
}*/
public String getRowText(String text){
int rows = 0;
class MyCaretListener implements CaretListener{
int tempResult = 0;
@Override
public void caretUpdate(CaretEvent e) {
try {
int offset = e.getDot() ; //获得插入符的位置。
//getLineOfOffset(int offset) 将组件文本中的偏移量转换为行号
int row = displayContent.getLineOfOffset(offset);
//getLineStartOffset(int line) 取得给定行起始处的偏移量。
//getLineEndOffset(int line) 取得给定行结尾处的偏移量。
int column = e.getDot() - displayContent.getLineStartOffset(row);
// 在状态栏中显示当前光标所在行号、所在列号
System.out.println("Line: " + (row + 1) + ", Column: " + (column+1));
tempResult = displayContent.getLineStartOffset(row+1);
System.out.println(row +"fffff");
} catch (Exception ex) {
ex.printStackTrace();
}
}
public int getResult(){//为了从内部类中取出结果
return tempResult;
}
}
MyCaretListener mycaretListener = new MyCaretListener();
displayContent.addCaretListener(mycaretListener);
rows = mycaretListener.getResult();
String getText="";
String regex = "\n";
Pattern p =Pattern.compile(regex);
String[] r = p.split(text);
if(!((r[rows-1].trim()).equals(""))){
getText = r[rows-1];
}
return getText;
}