在我进步时附加数据而不是一次进行

时间:2016-03-23 13:04:59

标签: java swing

我正在编写一个swing应用程序。这里的任务是从给定的URL下载文件,然后获取它们的计数。该程序无任何问题/错误。

问题是我的框架中有一个测试区,下载file 1时我希望文本区域显示downloaded file 1,文件2显示​​downloaded file 1等等。 ..

目前在我的程序中,消息会一次显示。我的意思是,如果我有10个文件,它会显示。

downloaded file 1
downloaded file 2
.
.
.
.
.
downloaded file 10

但只有在下载了所有10个文件后才会显示。要查看是否存在任何其他问题,我已在sysout代码下方添加了textarea。令我惊讶的是,sysout被打印10次,我的意思是每次处理文件时都会触发,但textarea一次附加所有数据。

以下是我的代码。

GuiForPDFs

import java.awt.BorderLayout;

public class GuiForPDFs extends JFrame {

    private JPanel contentPane;
    private JTextField srcTextField;
    private JTextArea textArea;

    /**
     * Launch the application.
     */
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                try {
                    GuiForPDFs frame = new GuiForPDFs();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    FileDownloadTest downloadTest = new FileDownloadTest();

    public GuiForPDFs() {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 552, 358);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        setContentPane(contentPane);
        contentPane.setLayout(null);

        srcTextField = new JTextField();
        srcTextField.setBounds(10, 26, 399, 20);
        contentPane.add(srcTextField);
        srcTextField.setColumns(10);

        JButton srcBtn = new JButton("Source Excel");
        srcBtn.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                JFileChooser fChoose = new JFileChooser();
                if (fChoose.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) {
                    srcTextField.setText(fChoose.getSelectedFile().getAbsolutePath());
                } else {
                    System.out.println("No Selection");
                }
            }
        });

        textArea = new JTextArea();
        textArea.setEditable(false);
        textArea.setBounds(10, 106, 516, 203);
        contentPane.add(textArea);

        srcBtn.setBounds(419, 25, 107, 23);
        contentPane.add(srcBtn);

        JButton dNcButton = new JButton("Process");
        dNcButton.addActionListener(new ActionListener() {
            public void actionPerformed(ActionEvent arg0) {
                try {
                    downloadTest.fileDownloadTest(srcTextField.getText(), textArea);
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (InterruptedException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
        });
        dNcButton.setBounds(212, 70, 89, 23);
        contentPane.add(dNcButton);

    }
}

FileDownloadTest

import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.MalformedURLException;
import java.net.URL;

import javax.swing.JTextArea;

import org.apache.commons.io.FileUtils;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class FileDownloadTest {

    public void fileDownloadTest(String src, JTextArea textArea) throws IOException, InterruptedException {
        String path = src;
        FileInputStream fin = new FileInputStream(new File(path));
        XSSFWorkbook workbook = new XSSFWorkbook(fin);
        XSSFSheet sheet = workbook.getSheetAt(0);
        int rows = sheet.getPhysicalNumberOfRows();
        System.out.println("rows are " + rows);
        XSSFCell cell;
        // Make sure that this directory exists
        String dirName = src.substring(0, src.lastIndexOf("\\"));
        File f = new File(dirName);
        if (!f.exists()) {
            f.mkdir();
        }
        System.out.println(f.getAbsolutePath() + " is Directory Name " + src + " is the file");
        for (int i = 1; i < rows; i++) {
            XSSFCell url = sheet.getRow(i).getCell(0);
            String URLString = url.toString();
            cell = sheet.getRow(i).getCell(7);
            String fileName = URLString.substring(URLString.lastIndexOf("/") + 1);
            int pageNumbers = downloadFiles(dirName, url.toString().replace("http", "https"));
            if (cell == null) {
                cell = sheet.getRow(i).createCell(1);
            }
            cell.setCellType(Cell.CELL_TYPE_NUMERIC);
            cell.setCellValue(pageNumbers);
            FileOutputStream fileOut = new FileOutputStream(path);
            workbook.write(fileOut);
            fileOut.close();
            textArea.append("downloaded " + fileName + "\n");
            System.out.println("Done");
        }
        workbook.close();
        fin.close();

    }

    public static int downloadFiles(String dirName, String urlString) {
        System.out.println("Downloading \'" + urlString + "\' PDF document...");
        String fileName = urlString.substring(urlString.lastIndexOf("/") + 1);
        System.out.println(fileName + " is file name");
        try {
            saveFileFromUrlWithJavaIO(dirName + "\\" + fileName, urlString);
        } catch (IOException e) {
            e.printStackTrace();
        }
        System.out.println("Downloaded \'" + urlString + "\' PDF document...");
        int pageNumber = 0;
        try {
            pageNumber = getNoOfPages(dirName + "\\" + fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return pageNumber;
    }

    public static int getNoOfPages(String fileName) throws IOException {
        PDDocument document = PDDocument.load(new File(fileName));
        int numberOfPages = document.getNumberOfPages();
        return numberOfPages;
    }

    public static void saveFileFromUrlWithJavaIO(String fileName, String fileUrl)
            throws MalformedURLException, IOException {
        BufferedInputStream in = null;
        FileOutputStream fout = null;
        try {
            in = new BufferedInputStream(new URL(fileUrl).openStream());
            fout = new FileOutputStream(fileName);

            byte data[] = new byte[1024];
            int count;
            while ((count = in.read(data, 0, 1024)) != -1) {
                fout.write(data, 0, count);
            }
        } finally {
            if (in != null)
                in.close();
            if (fout != null)
                fout.close();
        }
    }

    public static void saveFileFromUrlWithCommonsIO(String fileName, String fileUrl)
            throws MalformedURLException, IOException {
        FileUtils.copyURLToFile(new URL(fileUrl), new File(fileName));
    }

}

请告诉我如何解决这个问题。

由于

2 个答案:

答案 0 :(得分:1)

以上评论是正确的,您在向文本区域添加文本时在EDT上。这是因为您从 dNcButton ActionListener 实现中调用 downloadTest.fileDownloadTest

离开EDT的好习惯是你有一个长时间运行的操作,并且下载文件通常是作为你不想做的事情的一个例子。美国东部时间。

网上有很多关于如何离开EDT的资源,包括很多这个伟大的网站;

On Event Dispatch Thread---want to get off of it

Make thread run on non EDT (event dispatch thread) thread from EDT

答案 1 :(得分:0)

与其他评论一样,您需要在EDT上仅保留与UI相关的任务。否则,如果您的用户正在下载100个文件,则UI将锁定,直到下载任务完成。 SwingWorker是为Swing应用程序执行此操作的完美类。这是一个简单的例子:

// Run your FileDownloadTest inside a SwingWorker
// or have the class extend SwingWorker
new SwingWorker<Void, String>() {

    @Override
    protected Void doInBackground() throws Exception {
        //Perform downloading here (done off the EDT)
        //Call publish(downloadedFileName) to be sent to the process method()
        return null;
    }

    @Override
    protected void process(List<String> chunks) {
        // Modify textArea (done on the EDT)
        StringBuilder downloadedFiles = new StringBuilder();
        for (String fileName : chunks) {
            downloadedFiles.append("downloaded" + fileName + "\n");
        }
        textArea.setText(downloadedFiles);
    }

    @Override
    protected void done() {
        //Anything you want to happen after doInBackground() finishes
    }
}.execute();