Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/342.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在GUI中运行程序很慢_Java_Swing - Fatal编程技术网

Java 在GUI中运行程序很慢

Java 在GUI中运行程序很慢,java,swing,Java,Swing,我正在创建一个程序来抓取一个包含图像的网站,并将这些图像文件名和属性放在一个列表上,问题是,每当我尝试使用GUI从URL获取数据时,该程序大约需要20-30秒来显示表模型上的信息,但当我在没有GUI的情况下运行它时(仅控制台和简单的系统输出println)只需2-4秒,有时甚至更快。以下是我的GUI代码: public class ImageDownloader extends JFrame { private JPanel contentPane; private JTextField ur

我正在创建一个程序来抓取一个包含图像的网站,并将这些图像文件名和属性放在一个列表上,问题是,每当我尝试使用GUI从URL获取数据时,该程序大约需要20-30秒来显示表模型上的信息,但当我在没有GUI的情况下运行它时(仅控制台和简单的系统输出println)只需2-4秒,有时甚至更快。以下是我的GUI代码:

public class ImageDownloader extends JFrame {

private JPanel contentPane;
private JTextField urlTextField;
private JButton btnCheck;
private JButton btnDownload;
private JButton btnDownloadAll;
private JTable table;

private String imgUrl;
private String url;

Document document;
Elements media;

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

public ImageDownloader() {
    setTitle("Image Downloader");
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setBounds(100, 100, 565, 300);
    contentPane = new JPanel();
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    contentPane.setLayout(new BorderLayout(0, 0));
    setContentPane(contentPane);

    JPanel panel = new JPanel();
    FlowLayout flowLayout = (FlowLayout) panel.getLayout();
    flowLayout.setAlignment(FlowLayout.LEFT);
    contentPane.add(panel, BorderLayout.NORTH);

    JLabel lblWebsiteUrl = new JLabel("Website URL:");
    panel.add(lblWebsiteUrl);

    urlTextField = new JTextField();
    panel.add(urlTextField);
    urlTextField.setColumns(30);

    btnCheck = new JButton("Check");
    btnCheck.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            List<Images> images = new ArrayList<>();

            url = urlTextField.getText();

            if(url.isEmpty()) {
                JOptionPane.showMessageDialog(ImageDownloader.this, "Please enter a website URL", "Input Error", JOptionPane.ERROR_MESSAGE);
            } else {

                try {
                    document = Jsoup.connect(urlTextField.getText()).userAgent("Mozilla").timeout(10 * 1000).get();

                    media = document.select("[src]");

                    for(Element src : media) {
                        if(src.tagName().equals("img")) {
                            imgUrl = src.attr("abs:src");
                            URL url = new URL(imgUrl);
                            long size = url.openConnection().getContentLengthLong();
                            images.add(new Images(src.tagName(), src.attr("abs:src"), src.attr("width"), src.attr("height"), size));
                        }
                    }

                    ImageDownloaderTableModel tableModel = new ImageDownloaderTableModel(images);

                    table.setModel(tableModel);
                } catch (IOException e1) {
                    JOptionPane.showMessageDialog(ImageDownloader.this, "Error loading website, The site that you are trying to reach is either down or does not exist..", "Error Loading", JOptionPane.ERROR_MESSAGE);
                    e1.printStackTrace();
                }
            }
        }
    });
    panel.add(btnCheck);

    JPanel panel_1 = new JPanel();
    contentPane.add(panel_1, BorderLayout.SOUTH);

    btnDownloadAll = new JButton("Download All");
    btnDownloadAll.addActionListener(new ActionListener() {

        public void actionPerformed(ActionEvent arg0) {
            try {
                media = document.select("img");

                for(Element src : media) {
                    String strImgUrl = src.attr("abs:src");
                    downloadImage(strImgUrl);
                }
            } catch(Exception ex) {
                ex.printStackTrace();
            }
        }           
    });
    panel_1.add(btnDownloadAll);

    btnDownload = new JButton("Download");
    panel_1.add(btnDownload);

    JScrollPane scrollPane = new JScrollPane();
    contentPane.add(scrollPane, BorderLayout.CENTER);

    table = new JTable();
    scrollPane.setViewportView(table);
}

public static void downloadImage(String imgUrl) {
    String strImgUrl = imgUrl.substring(imgUrl.lastIndexOf("/") + 1);

    try {
        URL urlImage = new URL(imgUrl);
        InputStream in = urlImage.openStream();

        byte[] buffer = new byte[4096];
        int n = -1;

        OutputStream os = new FileOutputStream(strImgUrl);

        while((n = in.read(buffer)) != -1) {
            os.write(buffer, 0, n);
        }

        os.close();

        System.out.println("Saved..");
    } catch(IOException ex) {
        ex.printStackTrace();
    }
}
}
公共类ImageDownloader扩展JFrame{
私有JPanel内容窗格;
私有JTextField urlTextField;
私人JButton btnCheck;
私有JButton btnDownload;
私有JButton btnDownloadAll;
专用JTable表;
私有字符串imgUrl;
私有字符串url;
文件;
媒体元素;
公共静态void main(字符串[]args){
invokeLater(新的Runnable(){
公开募捐{
试一试{
ImageDownloader框架=新ImageDownloader();
frame.setVisible(true);
}捕获(例外e){
e、 printStackTrace();
}
}
});
}
公共图像下载程序(){
setTitle(“图像下载程序”);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
立根(100100565300);
contentPane=newjpanel();
setboorder(新的EmptyBorder(5,5,5,5));
setLayout(新的BorderLayout(0,0));
setContentPane(contentPane);
JPanel面板=新的JPanel();
FlowLayout=(FlowLayout)panel.getLayout();
flowLayout.setAlignment(flowLayout.LEFT);
添加(面板,BorderLayout.NORTH);
JLabel lblWebsiteUrl=新的JLabel(“网站URL:”);
panel.add(lblWebsiteUrl);
urlTextField=新的JTextField();
panel.add(urlTextField);
urlTextField.setColumns(30);
btnCheck=新的JButton(“检查”);
btnCheck.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件e){
列表图像=新的ArrayList();
url=urlTextField.getText();
if(url.isEmpty()){
JOptionPane.showMessageDialog(ImageDownloader.this,“请输入网站URL”,“输入错误”,JOptionPane.Error\u消息);
}否则{
试一试{
document=Jsoup.connect(urlTextField.getText()).userAgent(“Mozilla”).timeout(10*1000.get();
媒体=文档。选择(“[src]”);
对于(元素src:media){
if(src.tagName().equals(“img”)){
imgUrl=src.attr(“abs:src”);
URL=新URL(imgUrl);
long size=url.openConnection().getContentLengthLong();
添加(新图像(src.tagName()、src.attr(“abs:src”)、src.attr(“宽度”)、src.attr(“高度”)、大小);
}
}
ImageDownloaderTableModel tableModel=新的ImageDownloaderTableModel(图像);
table.setModel(tableModel);
}捕获(IOE1异常){
JOptionPane.showMessageDialog(ImageDownloader.this,“加载网站时出错,您试图访问的网站已关闭或不存在…”,“加载错误”,JOptionPane.Error\u消息);
e1.printStackTrace();
}
}
}
});
面板。添加(BTN检查);
JPanel panel_1=新的JPanel();
contentPane.add(面板1,BorderLayout.SOUTH);
btnDownloadAll=newjbutton(“下载全部”);
btnDownloadAll.addActionListener(新ActionListener(){
已执行的公共无效操作(操作事件arg0){
试一试{
媒体=文件。选择(“img”);
对于(元素src:media){
字符串strImgUrl=src.attr(“abs:src”);
下载图像(strImgUrl);
}
}捕获(例外情况除外){
例如printStackTrace();
}
}           
});
面板1.添加(btnDownloadAll);
btnDownload=新的JButton(“下载”);
面板1.添加(btnDownload);
JScrollPane scrollPane=新的JScrollPane();
添加(滚动窗格,BorderLayout.CENTER);
table=新的JTable();
scrollPane.setViewportView(表);
}
公共静态void downloadImage(字符串imgUrl){
stringstrimgurl=imgUrl.substring(imgUrl.lastIndexOf(“/”)+1);
试一试{
URL urlImage=新URL(imgUrl);
InputStream in=urlImage.openStream();
字节[]缓冲区=新字节[4096];
int n=-1;
OutputStream os=新文件OutputStream(strImgUrl);
而((n=in.read(buffer))!=-1){
写操作(缓冲区,0,n);
}
os.close();
System.out.println(“保存的…”);
}捕获(IOEX异常){
例如printStackTrace();
}
}
}

答案很简单,也很明显。当你在GUI模式下运行你的应用程序时,会有一个额外的线程用于可视化和图形,以及所有你拥有的组件,比如
JPanel
JButton
。这些都会占用程序的额外处理,并且在你的网络线程和nd您的主GUI线程

另一方面,控制台打印不需要繁重的图形处理,因此可以运行得更快


另外,好吧,联网是一种阻塞操作,即在网络调用完成之前,所有其他操作都必须等待。这就是为什么上下文从GUI线程转移到网络线程,然后再转移回来。

答案非常简单和明显。当你在GUI模式下运行应用程序时,会有一个额外的线程用于可视化和图形化ics和所有您拥有的组件,如
JPanel
JButton
。这些组件占用了程序的额外处理,并且在网络线程和主GUI线程之间存在上下文切换

另一方面,控制台打印不需要hea