Concurrent file download assistant

Posted by SuperCam on Fri, 11 Feb 2022 18:33:53 +0100

Personal project - Concurrent file download assistant

Expected and actual time consumption of each module

PSP2.1Personal Software Process StagesEstimated time (minutes)Actual time (minutes)
Planningplan6030
· Estimate·Estimate how long this task will take14401080
Developmentdevelopment1080
· Analysis·Demand analysis (including learning new technologies)360240
· Design Spec·Generate design documents6060
· Design Review·Design review (review design documents with colleagues)6060
· Coding Standard·Code specifications (develop appropriate specifications for current development)6030
· Design·Specific design60120
· Coding·Specific coding360300
· Code Review·Code review6030
· Test·Test (self test, modify code, submit modification)60240
Reportingreport360360
· Test Report·Test report180180
· Size Measurement·Calculation workload90120
· Postmortem & Process Improvement Plan·Summarize afterwards and put forward the process improvement plan9060
total15001470

requirement analysis

After obtaining the project requirements of the third stage, first make an overall analysis of the project requirements. The project focus of the third phase has been obtained.
In the third stage, the key requirements to be realized are: graphical interface. The requirement of this requirement is to get rid of the console input and output that must be relied on in the first two stages,
The running results of the program are displayed in the form of graphical interface. And equipped with appropriate prompt methods to remind users that the download is complete.
Another key project demand point is to obtain the clipboard data to facilitate users to copy and paste links and improve the user experience.
Another project requirement that needs to be paid attention to is to save some basic configuration data for users' convenience.

Train of thought description

The first is to determine the graphical interface layout of the project, which is directly related to the user experience. After some design, the basic layout of the graphical interface of the project is established.

After determining the interface layout, what needs to be done is to add components according to the idea and set the location of components. In this part, I searched relevant information on the Internet and adopted Java Swing
Technology to add and design the graphical interface, it takes time to focus on learning the page layout and the specific use methods of each component.
The realization of the function of obtaining the data of the shear board only needs to search the methods needed to obtain the data of the shear board on the Internet. The idea here is very direct.
The key information of the new configuration file is saved here. Because you need to save the past design, you can't simply set it as the default value,
Local data storage must be involved. Finally chose to store it in a Txt file, you only need to obtain the data of the txt file every time you open and run the software, which is convenient and fast.

Design and implementation process

In the process of function realization in this stage, a class is mainly added to realize relevant functions. Class contains the required graphical components and related methods. The relationship between classes after adding classes is:

The calling process of the overall sequence diagram of the project is as follows:

Use Jprofiler for performance monitoring, (simulate a read file download) the results are as follows:

The real-time monitoring of threads is as follows:

The real-time monitoring of cpu is as follows:

New code description (all meaningful warnings have been eliminated):

###App class

import javax.swing.*;
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import java.io.*;

public class App{
    private JButton commit;
    private JRadioButton linkChoose;
    private JRadioButton fileChoose;
    private JTextField filePath;
    private JTextField httpText;
    private JButton quit;
    private JTextField ipText;
    private JTextField portText;
    private JTextField remoteText;
    private JTextField fileText;
    private JTextField threadCount;
    private JTextField localText;
    private JPanel panel1;
    private JTextField usernameText;
    private JPasswordField passwordText;

    public static void main(String[] args) {//Start method
        JFrame frame = new JFrame("App");
        frame.setContentPane(new App().panel1);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }
    public void init(){//Initialization method
        File file = new File("\\property.txt");//Get the previously stored configuration data
        try {
            if(file.exists()){
                BufferedReader reader = new BufferedReader(new FileReader(file));
                String readLine = reader.readLine();
                if(readLine!=null){//Cut the string according to the stored format to obtain the configuration information
                    String[] s = readLine.split(" ");
                    threadCount.setText(s[0]);
                    localText.setText(s[1]);
                }
            }
        } catch (IOException e) {
            JOptionPane.showMessageDialog(null,"Initialization error");
            e.printStackTrace();
        }
    }
    public App() {
        init();//First call the initialization method
        linkChoose.addActionListener(e -> {//Turn on the monitoring method and the monitoring button. When the mode of input link is selected, close the input box of the input file
            httpText.setEnabled(true);
            ipText.setEnabled(true);
            portText.setEnabled(true);
            remoteText.setEnabled(true);
            fileText.setEnabled(true);
            usernameText.setEnabled(true);
            passwordText.setEnabled(true);

            filePath.setEnabled(false);
        });
        fileChoose.addActionListener(e -> {//When selecting the input file, close the input box of the input link
            filePath.setEnabled(true);

            httpText.setEnabled(false);
            ipText.setEnabled(false);
            portText.setEnabled(false);
            remoteText.setEnabled(false);
            fileText.setEnabled(false);
            usernameText.setEnabled(false);
            passwordText.setEnabled(false);
        });
        commit.addActionListener(e -> {//Listen to the submit button and click to start the download
            if(!"".equals(filePath.getText())){//Judge whether the file path input box is empty
                JOptionPane.showMessageDialog(null,"We are trying our best to download. Please wait patiently for the completion window");
                FileDown fileDown = new FileDown(filePath.getText(),localText.getText(),Integer.parseInt(threadCount.getText()));
                try {
                    fileDown.down();
                } catch (IOException ex) {
                    JOptionPane.showMessageDialog(null,"Incorrect input");
                    ex.printStackTrace();
                }
                JOptionPane.showMessageDialog(null,"Download complete");

            }
            else{
                if(!"".equals(httpText.getText())){//Determine whether the http link input box is empty
                    JOptionPane.showMessageDialog(null,"We are trying our best to download. Please wait patiently for the completion window");
                    System.out.println(httpText.getText().equals(""));
                    HttpDownLoad downLoad = new HttpDownLoad(Integer.parseInt(threadCount.getText()));
                    downLoad.down(httpText.getText(),localText.getText());
                    JOptionPane.showMessageDialog(null,"Download complete!");
                }
                if(!"".equals(ipText.getText())){//Judge whether the ip input box of ftp is empty
                    JOptionPane.showMessageDialog(null,"We are trying our best to download. Please wait patiently for the completion window");
                    System.out.println(ipText.getText());
                    FtpDownLoad ftpDownLoad = new FtpDownLoad(ipText.getText(),Integer.parseInt(portText.getText()),usernameText.getText(),new String(passwordText.getPassword()),Integer.parseInt(threadCount.getText()));
                    ftpDownLoad.downLoad(remoteText.getText(),fileText.getText(),localText.getText());
                    JOptionPane.showMessageDialog(null,"Download complete");
                }
                if("".equals(httpText.getText())&&"".equals(ipText.getText())){
                    JOptionPane.showMessageDialog(null,"You cannot enter a null value");
                }//When all are empty, a prompt message will pop up
            }
        });

        quit.addActionListener(e -> {//Listen to the exit button and click save. After exiting, the set configuration information will be obtained and stored in txt file
            File file = new File("/property.txt");
            if(file.exists()){
                boolean result = file.delete();
                if(!result){
                    System.out.println("Failed to delete history");
                }
            }
            boolean result = false;
            try {
                result = file.createNewFile();
            } catch (IOException ex) {
                JOptionPane.showMessageDialog(null,"Failed to create file");
                ex.printStackTrace();
            }
            if(!result){
                System.out.println("Failed to create storage file");
            }
            try {
                FileWriter writer = new FileWriter(file);
                if((threadCount.getText()!=null)&&(localText.getText()!=null)){
                    String property = threadCount.getText()+" "+localText.getText();
                    writer.write(property);
                }
                writer.close();
            } catch (FileNotFoundException ex) {
                JOptionPane.showMessageDialog(null, "Error in default profile path");
                ex.printStackTrace();
            } catch (IOException ioException) {
                JOptionPane.showMessageDialog(null, "write error");
                ioException.printStackTrace();
            }
            System.exit(0);
        });
        filePath.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                filePath.paste();
            }
        });

//From here down is the function implementation of each input text box to obtain the content of the clipboard.
        localText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                localText.paste();
            }
        });
        httpText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                httpText.paste();
            }
        });
        ipText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                ipText.paste();
            }
        });
        portText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                portText.paste();
            }
        });
        usernameText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                usernameText.paste();
            }
        });
        passwordText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                passwordText.paste();
            }
        });
        remoteText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                remoteText.paste();
            }
        });
        fileText.addFocusListener(new FocusAdapter() {
            @Override
            public void focusGained(FocusEvent e) {
                fileText.paste();
            }
        });
    }
}

The core code is shown above. Please explain it briefly. The basic idea is to add graphical components, and then add the monitoring method of the corresponding graphical components. Code for obtaining shear plate data in each input box
It is realized when clicking the input box. After clicking, the data in the input box will be automatically obtained and pasted. The function of obtaining saved configuration files is implemented when creating the interface,
Written in the init method. As for the Save button, I use the relevant methods of File class to store the configuration data locally and save the past configuration information.

Mental journey and harvest of the project

Choosing this project is not a small challenge for me. At least from the intuitive feeling when choosing the project at that time, this project is the one I feel the least familiar with.
I also encountered a lot of difficulties in the overall completion of the project. It took me a lot of effort to solve these difficulties, but the final result is quite impressive. I think the completion is quite good.
I didn't encounter too many problems during the completion of the first and third phases of the project. Personally, I think my biggest regret is that I didn't complete the function of magnetic link download in the second phase,
As I wrote in the second stage blog, I made great efforts in this part, but the results were not satisfactory. In the end, I stopped to ask tracker for peer ip.
But regret is learning and regret is growth. In the future, I will also remember the difficulties I encountered in this project, and resolutely refuse to lose, don't give up, and work hard.

Topics: Java intellij-idea