FolderCompareFrame with good layout

21ca發表於2016-12-16

點選(此處)摺疊或開啟

  1. import java.awt.BorderLayout;
  2. import java.awt.Dimension;
  3. import java.awt.event.ActionEvent;
  4. import java.awt.event.ActionListener;
  5. import java.awt.event.MouseEvent;
  6. import java.awt.event.MouseListener;
  7. import java.io.File;
  8. import java.io.FileInputStream;
  9. import java.io.FileOutputStream;
  10. import java.io.IOException;
  11. import java.security.MessageDigest;
  12. import java.security.NoSuchAlgorithmException;
  13. import java.util.ArrayList;
  14. import java.util.Arrays;
  15. import java.util.Collections;
  16. import java.util.LinkedHashSet;
  17. import java.util.List;
  18. import java.util.Properties;
  19. import java.util.Set;

  20. import javax.swing.DefaultListModel;
  21. import javax.swing.JButton;
  22. import javax.swing.JComponent;
  23. import javax.swing.JFileChooser;
  24. import javax.swing.JFrame;
  25. import javax.swing.JLabel;
  26. import javax.swing.JList;
  27. import javax.swing.JPanel;
  28. import javax.swing.JScrollPane;
  29. import javax.swing.JTextField;
  30. import javax.swing.plaf.basic.BasicBorders;


  31. public class FolderCompareFrame2 extends JFrame implements ActionListener, MouseListener {

  32.     private static final String[] SUFFIX_FILTER = new String[] {".java", ".properties", ".xml", ".jsp", ".sql", ".jar", ".php" };
  33.     private static final String[] EXCLUDE_FILTER = new String[] {"/test/", "/integration/", "/target/"};
  34.     
  35.     private static final long serialVersionUID = 3278358999317656288L;
  36.     private static final String notepadPlusCmd = "C:/Program Files (x86)/Notepad++/notepad++.exe";
  37.     
  38.     private static final String CMD_SELECT_SOURCE = "source";
  39.     private static final String CMD_SELECT_TARGET = "target";
  40.     private static final String CMD_COMPARE = "compare";

  41.     private JTextField sourceInput;
  42.     private JTextField targetInput;

  43.     private JList<String> resultList;
  44.     private DefaultListModel<String> resultListModel = new DefaultListModel<String>();
  45.     
  46.     private String sourceFolder;
  47.     private String targetFolder;
  48.     
  49.     private JFileChooser fileChooser = new JFileChooser();
  50.     
  51.     public FolderCompareFrame2() {
  52.         setSize(800, 600);
  53.         fileChooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
  54.         
  55.         setDefaultCloseOperation(EXIT_ON_CLOSE);
  56.         setTitle("Folder Compare");
  57.         setLayout(new BorderLayout());
  58.         addTopPanel();
  59.         addResultList();
  60.         loadSettings();
  61.         setVisible(true);

  62.     }
  63.     
  64.     private void addTopPanel() {
  65.         JPanel topPanel = new JPanel(new BorderLayout(10, 0));
  66.         
  67.         JPanel inputPanel = new JPanel(new BorderLayout());
  68.         addSourceFolderInput(inputPanel);
  69.         addTargetFolderInput(inputPanel);
  70.         JButton compareButton = new JButton("Compare");
  71.         compareButton.setActionCommand(CMD_COMPARE);
  72.         compareButton.addActionListener(this);

  73.         topPanel.add(inputPanel, BorderLayout.CENTER);
  74.         topPanel.add(compareButton, BorderLayout.EAST);
  75.         
  76.         add(topPanel, BorderLayout.NORTH);
  77.         
  78.     }

  79.     private void loadSettings() {
  80.         Properties props = new Properties();
  81.         try {
  82.             props.load(new FileInputStream(this.getClass().getSimpleName() + ".config"));
  83.             sourceInput.setText(props.getProperty("folder1"));
  84.             targetInput.setText(props.getProperty("folder2"));
  85.         } catch (Exception e) {
  86.             e.printStackTrace();
  87.         }
  88.     }
  89.     
  90.     private void saveSettings() {
  91.         Properties props = new Properties();
  92.         try {
  93.             props.put("folder1", sourceInput.getText());
  94.             props.put("folder2", targetInput.getText());
  95.             props.store(new FileOutputStream(this.getClass().getSimpleName() + ".config"), null);
  96.         } catch (Exception e) {
  97.             e.printStackTrace();
  98.         }
  99.     }

  100.     private void addResultList() {
  101.         resultList = new JList<String>();
  102.         JScrollPane pane = new JScrollPane(resultList);
  103.         pane.setBorder(BasicBorders.getTextFieldBorder());
  104.         add(pane, BorderLayout.CENTER);
  105.         resultList.addMouseListener(this);
  106.         resultList.setModel(resultListModel);
  107.     }

  108.     private void addTargetFolderInput(JComponent p) {
  109.         JPanel panel = new JPanel();
  110.         p.add(panel, BorderLayout.SOUTH);
  111.         panel.setLayout(new BorderLayout());
  112.         
  113.         JLabel label = new JLabel("Target:");
  114.         label.setPreferredSize(new Dimension(60, 0));
  115.         panel.add(label, BorderLayout.WEST);
  116.         
  117.         targetInput = new JTextField();
  118.         panel.add(targetInput, BorderLayout.CENTER);
  119.         
  120.         JButton button = new JButton("...");
  121.         button.setActionCommand(CMD_SELECT_TARGET);
  122.         button.addActionListener(this);
  123.         panel.add(button, BorderLayout.EAST);
  124.     }

  125.     private void addSourceFolderInput(JComponent p) {
  126.         JPanel panel = new JPanel();
  127.         p.add(panel, BorderLayout.NORTH);
  128.         panel.setLayout(new BorderLayout());

  129.         JLabel label = new JLabel("Source:");
  130.         label.setPreferredSize(new Dimension(60, 0));
  131.         panel.add(label, BorderLayout.WEST);
  132.         
  133.         sourceInput = new JTextField();
  134.         panel.add(sourceInput, BorderLayout.CENTER);
  135.         
  136.         JButton button = new JButton("...");
  137.         button.setActionCommand(CMD_SELECT_SOURCE);
  138.         button.addActionListener(this);
  139.         panel.add(button, BorderLayout.EAST);
  140.     }

  141.     public static void main(String[] args) {
  142.         new FolderCompareFrame2();
  143.     }

  144.     @Override
  145.     public void actionPerformed(ActionEvent e) {
  146.         if (e.getActionCommand() == CMD_SELECT_SOURCE) {
  147.             fileChooser.setCurrentDirectory(new File(sourceInput.getText()));
  148.             int result = fileChooser.showOpenDialog(FolderCompareFrame2.this);
  149.             if(result == JFileChooser.APPROVE_OPTION) {
  150.                 sourceInput.setText(fileChooser.getSelectedFile().getAbsolutePath());
  151.             }
  152.         } else if (e.getActionCommand() == CMD_SELECT_TARGET) {
  153.             fileChooser.setCurrentDirectory(new File(targetInput.getText()));
  154.             int result = fileChooser.showOpenDialog(FolderCompareFrame2.this);
  155.             if(result == JFileChooser.APPROVE_OPTION) {
  156.                 targetInput.setText(fileChooser.getSelectedFile().getAbsolutePath());
  157.             }
  158.         } else if (e.getActionCommand() == CMD_COMPARE) {
  159.             sourceFolder = sourceInput.getText().replaceAll("\\\\", "/");
  160.             if (!sourceFolder.endsWith("/")) {
  161.                 sourceFolder = sourceFolder + "/";
  162.             }
  163.             targetFolder = targetInput.getText().replaceAll("\\\\", "/");
  164.             if (!targetFolder.endsWith("/")) {
  165.                 targetFolder = targetFolder + "/";
  166.             }
  167.             saveSettings();
  168.             resultListModel.clear();;
  169.             compare(sourceFolder, targetFolder);
  170.         }
  171.     }
  172.     
  173.     /**
  174.      * Start NotePad++
  175.      * @param sourceFile
  176.      * @param targetFile
  177.      */
  178.     private void compareFile(String sourceFile, String targetFile) {
  179.         ProcessBuilder pb = new ProcessBuilder(notepadPlusCmd, sourceFile, targetFile);
  180.         try {
  181.             pb.start();
  182.         } catch (Exception e) {
  183.             e.printStackTrace();
  184.         }
  185.     }
  186.     
  187.     private boolean endWith(String file, String[] suffix) {
  188.         for (String s : suffix) {
  189.             if (file.endsWith(s)) {
  190.                 return true;
  191.             }
  192.         }
  193.         return false;
  194.     }
  195.     
  196.     private boolean containString(String file, String[] containString) {
  197.         for (String s : containString) {
  198.             if (file.contains(s)) {
  199.                 return true;
  200.             }
  201.         }
  202.         return false;
  203.     }
  204.     
  205.     private List<String> list(File folder) {
  206.         if (folder.isFile()) {
  207.             return Collections.singletonList(folder.getAbsolutePath().replace("\\", "/"));
  208.         }
  209.         List<String> list = new ArrayList<String>();
  210.         for (File f : folder.listFiles()) {
  211.             list.addAll(list(f));
  212.         }
  213.         return list;
  214.     }

  215.     private void compare(String source, String target) {
  216.         System.out.println("Compare File: " + source + " with " + target);
  217.         File sourceFile = new File(source);
  218.         File targetFile = new File(target);
  219.         
  220.         if (!sourceFile.exists() || !targetFile.exists()) {
  221.             //Source file or target file not exist.
  222.             if ((sourceFile.isFile() || targetFile.isFile())
  223.                     && endWith(source, SUFFIX_FILTER) && !containString(source, EXCLUDE_FILTER)) {
  224.                 resultListModel.addElement(source.substring(sourceFolder.length()));
  225.             }
  226.             
  227.             //Source file is a folder, target folder not exist.
  228.             if (sourceFile.isDirectory()) {
  229.                 for (String f : list(sourceFile)) {
  230.                     if (endWith(f, SUFFIX_FILTER) && !containString(f, EXCLUDE_FILTER)) {
  231.                         resultListModel.addElement(f.substring(sourceFolder.length()));
  232.                     }
  233.                 }
  234.             }
  235.             
  236.             if (targetFile.isDirectory()) {
  237.                 for (String f : list(targetFile)) {
  238.                     if (endWith(f, SUFFIX_FILTER) && !containString(f, EXCLUDE_FILTER)) {
  239.                         resultListModel.addElement(f.substring(targetFolder.length()));
  240.                     }
  241.                 }
  242.             }
  243.             
  244.         } else if (sourceFile.isFile() && targetFile.isFile() && endWith(source, SUFFIX_FILTER)
  245.                 && !containString(source, EXCLUDE_FILTER) && !fileMatch(sourceFile, targetFile)) {
  246.             resultListModel.addElement(source.substring(sourceFolder.length()));
  247.         } else if (sourceFile.isDirectory() && targetFile.isDirectory()) {
  248.             if (!source.endsWith("/")) {
  249.                 source = source + "/";
  250.             }
  251.             if (!target.endsWith("/")) {
  252.                 target = target + "/";
  253.             }
  254.             
  255.             Set<String> subFolders = new LinkedHashSet<String>();
  256.             subFolders.addAll(Arrays.asList(sourceFile.list()));
  257.             subFolders.addAll(Arrays.asList(targetFile.list()));
  258.             for (String subFolder : subFolders) {
  259.                 compare(source + subFolder, target + subFolder);
  260.             }
  261.         }
  262.     }

  263.     private boolean fileMatch(File sourceFile, File targetFile) {
  264.         if (sourceFile.length() != targetFile.length()) {
  265.             return false;
  266.         }
  267.         
  268.         try {
  269.             if (!Arrays.equals(md5(readFileToByteArray(sourceFile)), md5(readFileToByteArray(targetFile)))) {
  270.                 return false;
  271.             }
  272.         } catch (IOException e) {
  273.             e.printStackTrace();
  274.             return false;
  275.         }
  276.         
  277.         return true;
  278.     }

  279.     private byte[] md5(byte[] buf) {
  280.         try {
  281.             MessageDigest md5 = MessageDigest.getInstance("MD5");
  282.             return md5.digest(buf);
  283.         } catch (NoSuchAlgorithmException e) {
  284.             throw new IllegalArgumentException();
  285.         }
  286.     }

  287.     private byte[] readFileToByteArray(File f) throws IOException {
  288.         FileInputStream input = new FileInputStream(f);
  289.         try {
  290.             if (f.isFile() && f.canRead()) {
  291.                 int size = (int)f.length();
  292.                 byte[] data = new byte[size];
  293.                 
  294.                 int offset = 0;
  295.          int readed;
  296.     
  297.          while (offset < size && (readed = input.read(data, offset, size - offset)) != -1) {
  298.          offset += readed;
  299.          }
  300.                 return data;
  301.             } else {
  302.                 return null;
  303.             }
  304.         } finally {
  305.             input.close();
  306.         }
  307.     }

  308.     @Override
  309.     public void mouseClicked(MouseEvent e) {
  310.         if (e.getClickCount() == 2 && resultList.getSelectedIndex() >= 0) {
  311.             String file = (String) resultList.getSelectedValue();
  312.             compareFile(sourceFolder + file, targetFolder + file);
  313.         }
  314.     }
  315.     public void mousePressed(MouseEvent e) {}    
  316.     public void mouseReleased(MouseEvent e) {}
  317.     public void mouseEntered(MouseEvent e) {}
  318.     public void mouseExited(MouseEvent e) {}
  319. }


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10742815/viewspace-2130753/,如需轉載,請註明出處,否則將追究法律責任。

相關文章