Java 在SwingWorker中实现JScrollPane/JTextArea

Java 在SwingWorker中实现JScrollPane/JTextArea,java,implementation,jtextarea,swingworker,jscrollbar,Java,Implementation,Jtextarea,Swingworker,Jscrollbar,使用SwingWorker时,我的JScrollPane/JTextArea遇到一些问题。以下是我目前拥有的: JTextArea txtDirs; Task task; //EDT public void createGUI(){ txtDirs = new JTextArea(); txtDirs.setBounds(10, 56, 414, 125); txtDirs.setEditable(false); contentPane.add(new JScr

使用SwingWorker时,我的JScrollPane/JTextArea遇到一些问题。以下是我目前拥有的:

JTextArea txtDirs;
Task task;

//EDT
public void createGUI(){
    txtDirs = new JTextArea();
    txtDirs.setBounds(10, 56, 414, 125);
    txtDirs.setEditable(false);
    contentPane.add(new JScrollPane(txtDirs));

    task = new Task();
    task.execute();
}

class Task extends SwingWorker<Void, Void>{
    @Override
    public void doInBackground(){
        for(file : files){
            txtDirs.append(file.getAbsolutePath);
        }
    }

    @Override
    public void done(){
        closeWindow();
    }
}
编辑#2:

我对createGUI()方法进行了一些更改,以避免contentPane具有空布局:

public void createGUI(){
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle("Backup Progress");
    setBounds(100, 100, 450, 300);
    contentPane = new JPanel(new BorderLayout());
    contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
    setContentPane(contentPane);
    contentPane.setLayout(null);

    txtCopiedDirs = new JTextArea(10, 50);
    txtCopiedDirs.setEditable(false);
    scrollPane = new JScrollPane(txtCopiedDirs);
    contentPane.add(scrollPane, BorderLayout.CENTER);

    btnCancel = new JButton("Cancel");
    btnCancel.setBounds(169, 227, 89, 23);
    btnCancel.addActionListener(new ActionListener() {
        public void actionPerformed(ActionEvent e) {
            closeWindow();
        }
    });
    contentPane.add(btnCancel);

    progressBar = new JProgressBar(0, 100);
    progressBar.setBounds(10, 192, 414, 24);
    progressBar.setValue(0);
    contentPane.add(progressBar);

    lblCopying = new JLabel("Now backing up your files....");
    lblCopying.setBounds(10, 11, 157, 34);
    contentPane.add(lblCopying);

    setVisible(true);
    task = new Task();
    task.execute();
}

试试这个,我不知道它是否是线程安全的,试着在publish中调用你知道在
EDT中调用的

class Task extends SwingWorker<Void, String>{
    @Override
    public void doInBackground(){
        for(file : files){
            publish(file.getAbsolutePath); //or you can store them in an array and call it later
        }
    }

    @Override
    public void process(List<String> chunks){
           for(String filePath : chunks){
             txtDirs.append(filePath);
           }
    }

    @Override
    public void done(){
        closeWindow();
    }
}
类任务扩展SwingWorker{
@凌驾
公共无效doInBackground(){
用于(文件:文件){
publish(file.getAbsolutePath);//或者您可以将它们存储在数组中,稍后再调用它
}
}
@凌驾
公共作废流程(列表块){
for(字符串文件路径:块){
追加(文件路径);
}
}
@凌驾
公众假期结束(){
关闭窗口();
}
}

如果这不利于考虑发布

UL>
  • 不要使用
    setBounds
    ,而是使用
  • 不要从EDT外部修改任何UI组件,而是使用
    publish
    并覆盖
    process
    <代码>过程
  • 在EDT的内容中调用 请查看以了解更多详细信息

    你的问题可能的原因包括

    • 在使用
      边框布局时向框架添加其他组件,而不指定位置约束(除了
      边框布局.CENTER
    • 在添加组件之前调用visible
    已更新

    主要问题是,
    contentPane
    使用的是
    null
    布局,滚动窗格的默认边界是
    0x0
    位置按
    0x0
    宽度和高度

    最好的选择是不要使用WinodwBuilder并学习如何使用它

    使用示例更新

    这是一个使用两个布局管理器的示例,
    BorderLayout
    作为基本布局,
    gridbagloayout
    为额外组件提供一些额外的支持

    基本经验法则。如果它是一个UI组件,特别是如果它在屏幕上(或者你不知道它是否在屏幕上),你必须只从EDT的上下文中更新它

    这意味着从
    doInBackground
    中调用
    progressBar.setValue
    违反了Swing的单线程规则
    SwingWorker
    通过其
    PropertyChange
    支持提供进度更新

    import java.awt.BorderLayout;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowEvent;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingWorker;
    import javax.swing.border.EmptyBorder;
    
    public class BasicCopy extends JFrame {
    
        private JPanel contentPane;
        private JTextArea txtCopiedDirs;
        private JButton btnCancel;
        private JProgressBar progressBar;
        private JLabel lblCopying;
        private String mainDrive;
        private String backupDrive;
        private String username;
        private String backupDir;
        long totalSize = 0L;        //total size of directories/files
        long currentSize = 0L;      //current size of files counting up to ONE_PERCENT
        long currentPercent = 0L;   //current progress in %
        long ONE_PERCENT;       //totalSize / 100
        Task task;
    
        public BasicCopy() {
        }
    
        public BasicCopy(String inDrive, String outDrive, String username, long space) {
            mainDrive = inDrive;
            backupDrive = outDrive;
            this.username = username;
            totalSize = space * 1048576;
            ONE_PERCENT = totalSize / 100;
            createGUI();
        }
    
        public void createGUI() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setTitle("Backup Progress");
            contentPane = new JPanel();
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            setContentPane(contentPane);
            contentPane.setLayout(new BorderLayout());
    
            txtCopiedDirs = new JTextArea(10, 50);
            txtCopiedDirs.setEditable(false);
            contentPane.add(new JScrollPane(txtCopiedDirs));
    
            JPanel controls = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(4, 4, 4, 4);
    
            lblCopying = new JLabel("Now backing up your files....");
            contentPane.add(lblCopying, gbc);
    
            gbc.gridy++;
    
            progressBar = new JProgressBar(0, 100);
            progressBar.setValue(0);
            contentPane.add(progressBar, gbc);
    
            gbc.gridy++;
    
            btnCancel = new JButton("Cancel");
            btnCancel.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    closeWindow();
                }
            });
            controls.add(btnCancel, gbc);
            contentPane.add(controls, BorderLayout.SOUTH);
    
            setLocationRelativeTo(null);
            pack();
            setVisible(true);
            task = new Task();
            task.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                        progressBar.setValue((int) evt.getNewValue());
                    }
                }
            });
            task.execute();
        }
    
        /**
         * Swing Worker class
         */
        class Task extends SwingWorker<Void, String> {
    
            @Override
            public Void doInBackground() throws Exception {
                setProgress(0);
    
                //Create Backup Directory
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy_HMMSS");
                String timestamp = sdf.format(date);
                backupDir = backupDrive + ":\\" + "Backup_" + timestamp;
                File backupDirectory = new File(backupDir);
                backupDirectory.mkdir();
    
                //Copy Files
                //Main directories
                String pics = mainDrive + ":\\Users\\" + username + "\\Pictures\\";
                String docs = mainDrive + ":\\Users\\" + username + "\\Documents\\";
                String vids = mainDrive + ":\\Users\\" + username + "\\Videos\\";
                String musc = mainDrive + ":\\Users\\" + username + "\\Music\\";
                //Backup directories
                String bkPics = backupDir + "\\Pictures\\";
                String bkDocs = backupDir + "\\Documents\\";
                String bkVids = backupDir + "\\Documents\\";
                String bkMusc = backupDir + "\\Pictures\\";
    
                String[] directories = {pics, docs, vids, musc};
                String[] bkDirectories = {bkPics, bkDocs, bkVids, bkMusc};
    
                //Loop through directories and copy files
                for (int i = 0; i < directories.length; i++) {
                    File dir = new File(directories[i]);
                    File dest = new File(bkDirectories[i]);
                    for (File file : dir.listFiles()) {
                        try{
                        if (file.isFile()) {
                            FileUtils.copyFileToDirectory(file, dest);
                            publish(file.getAbsolutePath() + "\n");
                        } else if (file.isDirectory()) {
                            FileUtils.copyDirectoryToDirectory(file, dest);
                            Thread.sleep(1000);
                            publish(file.getAbsolutePath() + "\n");
                        }
                        if (getDirSize(file) >= ONE_PERCENT) {
                            currentPercent = getDirSize(file) / ONE_PERCENT;
                            setProgress((int) currentPercent);
                            currentSize = 0;
                        } else {
                            currentSize = currentSize + getDirSize(file);
                            if (currentSize >= ONE_PERCENT) {
                                currentPercent = currentSize / ONE_PERCENT;
                                currentPercent++;
                                setProgress((int) currentPercent);
                                currentSize = 0;
                            }
                        }
                        } catch (IOException e){
                            e.printStackTrace();
                        }
                    }
                }
                return null;
            }
    
            @Override
            public void process(List<String> chunks) {
                for (String path : chunks) {
                    txtCopiedDirs.append(path);
                }
            }
    
            @Override
            public void done() {
                closeWindow();
            }
        }
    
        public static Long getDirSize(File file) {
            long size = 0L;
    
            if (file.isFile() && file != null) {
                size += file.isDirectory() ? getDirSize(file) : file.length();
            } else if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    size += f.isDirectory() ? getDirSize(f) : file.length();
                }
            }
            return size;
        }
    
        /* Close current window */
        public void closeWindow() {
            WindowEvent close = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);
            System.exit(0);
        }
    }
    
    导入java.awt.BorderLayout;
    导入java.awt.GridBagConstraints;
    导入java.awt.GridBagLayout;
    导入java.awt.Insets;
    导入java.awt.Toolkit;
    导入java.awt.event.ActionEvent;
    导入java.awt.event.ActionListener;
    导入java.awt.event.WindowEvent;
    导入java.beans.PropertyChangeEvent;
    导入java.beans.PropertyChangeListener;
    导入java.io.File;
    导入java.text.simpleDataFormat;
    导入java.util.Date;
    导入java.util.List;
    导入javax.swing.JButton;
    导入javax.swing.JFrame;
    导入javax.swing.JLabel;
    导入javax.swing.JPanel;
    导入javax.swing.JProgressBar;
    导入javax.swing.JScrollPane;
    导入javax.swing.JTextArea;
    导入javax.swing.SwingWorker;
    导入javax.swing.border.EmptyBorder;
    公共类BasicCopy扩展了JFrame{
    私有JPanel内容窗格;
    私人JTextArea txtCopiedDirs;
    私人JButton btnCancel;
    私人JProgressBar progressBar;
    私人JLabel lblCopying;
    专用字符串主驱动器;
    专用字符串备份驱动器;
    私有字符串用户名;
    私有字符串backupDir;
    long totalSize=0L;//目录/文件的总大小
    long currentSize=0L;//文件的当前大小最多为百分之一
    long currentPercent=0L;//当前进度,单位为%
    长百分之一;//totalSize/100
    任务;
    公共基本副本(){
    }
    公共基本副本(字符串inDrive、字符串OUTDIVE、字符串用户名、长空格){
    主驱动=独立驱动;
    备份驱动器=输出驱动器;
    this.username=用户名;
    totalSize=space*1048576;
    百分之一=总尺寸/100;
    createGUI();
    }
    public void createGUI(){
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setTitle(“备份进度”);
    contentPane=newjpanel();
    setboorder(新的EmptyBorder(5,5,5,5));
    setContentPane(contentPane);
    setLayout(新的BorderLayout());
    txtCopiedDirs=新的JTextArea(10,50);
    txtCopiedDirs.setEditable(false);
    添加(新的JScrollPane(txtCopiedDirs));
    JPanel controls=newjpanel(newgridbaglayout());
    GridBagConstraints gbc=新的GridBagConstraints();
    gbc.gridx=0;
    gbc.gridy=0;
    gbc.插图=新插图(4,4,4,4);
    lblCopying=newjlabel(“现在正在备份文件…”);
    contentPane.add(lblCopying,gbc);
    gbc.gridy++;
    progressBar=新的JProgressBar(01100);
    progressBar.setValue(0);
    contentPane.add(progressBar,gbc);
    gbc.gridy++;
    btnCancel=新的JButton(“取消”);
    btnCancel.addActionListener(新ActionListener(){
    已执行的公共无效操作(操作事件e){
    关闭窗口();
    }
    });
    添加控件(btnCancel、gbc);
    添加(控件,BorderLayout.SOUTH);
    setLocationRelativeTo(空);
    包装();
    setVisible(真);
    任务=新任务();
    task.addPropertyChangeListener(新的PropertyChangeListener(){
    @凌驾
    公共作废属性更改(属性更改事件evt){
    if(“progress.equalsIgnoreCase(evt.getPropertyName())){
    progressBar.setValue((int)evt.getNewValue());
    }
    }
    });
    task.execute();
    }
    /**
    *摇摆工人阶级
    */
    类任务扩展SwingWorker{
    @凌驾
    公众的
    
    import java.awt.BorderLayout;
    import java.awt.GridBagConstraints;
    import java.awt.GridBagLayout;
    import java.awt.Insets;
    import java.awt.Toolkit;
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    import java.awt.event.WindowEvent;
    import java.beans.PropertyChangeEvent;
    import java.beans.PropertyChangeListener;
    import java.io.File;
    import java.text.SimpleDateFormat;
    import java.util.Date;
    import java.util.List;
    import javax.swing.JButton;
    import javax.swing.JFrame;
    import javax.swing.JLabel;
    import javax.swing.JPanel;
    import javax.swing.JProgressBar;
    import javax.swing.JScrollPane;
    import javax.swing.JTextArea;
    import javax.swing.SwingWorker;
    import javax.swing.border.EmptyBorder;
    
    public class BasicCopy extends JFrame {
    
        private JPanel contentPane;
        private JTextArea txtCopiedDirs;
        private JButton btnCancel;
        private JProgressBar progressBar;
        private JLabel lblCopying;
        private String mainDrive;
        private String backupDrive;
        private String username;
        private String backupDir;
        long totalSize = 0L;        //total size of directories/files
        long currentSize = 0L;      //current size of files counting up to ONE_PERCENT
        long currentPercent = 0L;   //current progress in %
        long ONE_PERCENT;       //totalSize / 100
        Task task;
    
        public BasicCopy() {
        }
    
        public BasicCopy(String inDrive, String outDrive, String username, long space) {
            mainDrive = inDrive;
            backupDrive = outDrive;
            this.username = username;
            totalSize = space * 1048576;
            ONE_PERCENT = totalSize / 100;
            createGUI();
        }
    
        public void createGUI() {
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setTitle("Backup Progress");
            contentPane = new JPanel();
            contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
            setContentPane(contentPane);
            contentPane.setLayout(new BorderLayout());
    
            txtCopiedDirs = new JTextArea(10, 50);
            txtCopiedDirs.setEditable(false);
            contentPane.add(new JScrollPane(txtCopiedDirs));
    
            JPanel controls = new JPanel(new GridBagLayout());
            GridBagConstraints gbc = new GridBagConstraints();
            gbc.gridx = 0;
            gbc.gridy = 0;
            gbc.insets = new Insets(4, 4, 4, 4);
    
            lblCopying = new JLabel("Now backing up your files....");
            contentPane.add(lblCopying, gbc);
    
            gbc.gridy++;
    
            progressBar = new JProgressBar(0, 100);
            progressBar.setValue(0);
            contentPane.add(progressBar, gbc);
    
            gbc.gridy++;
    
            btnCancel = new JButton("Cancel");
            btnCancel.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent e) {
                    closeWindow();
                }
            });
            controls.add(btnCancel, gbc);
            contentPane.add(controls, BorderLayout.SOUTH);
    
            setLocationRelativeTo(null);
            pack();
            setVisible(true);
            task = new Task();
            task.addPropertyChangeListener(new PropertyChangeListener() {
                @Override
                public void propertyChange(PropertyChangeEvent evt) {
                    if ("progress".equalsIgnoreCase(evt.getPropertyName())) {
                        progressBar.setValue((int) evt.getNewValue());
                    }
                }
            });
            task.execute();
        }
    
        /**
         * Swing Worker class
         */
        class Task extends SwingWorker<Void, String> {
    
            @Override
            public Void doInBackground() throws Exception {
                setProgress(0);
    
                //Create Backup Directory
                Date date = new Date();
                SimpleDateFormat sdf = new SimpleDateFormat("MM-dd-yyyy_HMMSS");
                String timestamp = sdf.format(date);
                backupDir = backupDrive + ":\\" + "Backup_" + timestamp;
                File backupDirectory = new File(backupDir);
                backupDirectory.mkdir();
    
                //Copy Files
                //Main directories
                String pics = mainDrive + ":\\Users\\" + username + "\\Pictures\\";
                String docs = mainDrive + ":\\Users\\" + username + "\\Documents\\";
                String vids = mainDrive + ":\\Users\\" + username + "\\Videos\\";
                String musc = mainDrive + ":\\Users\\" + username + "\\Music\\";
                //Backup directories
                String bkPics = backupDir + "\\Pictures\\";
                String bkDocs = backupDir + "\\Documents\\";
                String bkVids = backupDir + "\\Documents\\";
                String bkMusc = backupDir + "\\Pictures\\";
    
                String[] directories = {pics, docs, vids, musc};
                String[] bkDirectories = {bkPics, bkDocs, bkVids, bkMusc};
    
                //Loop through directories and copy files
                for (int i = 0; i < directories.length; i++) {
                    File dir = new File(directories[i]);
                    File dest = new File(bkDirectories[i]);
                    for (File file : dir.listFiles()) {
                        try{
                        if (file.isFile()) {
                            FileUtils.copyFileToDirectory(file, dest);
                            publish(file.getAbsolutePath() + "\n");
                        } else if (file.isDirectory()) {
                            FileUtils.copyDirectoryToDirectory(file, dest);
                            Thread.sleep(1000);
                            publish(file.getAbsolutePath() + "\n");
                        }
                        if (getDirSize(file) >= ONE_PERCENT) {
                            currentPercent = getDirSize(file) / ONE_PERCENT;
                            setProgress((int) currentPercent);
                            currentSize = 0;
                        } else {
                            currentSize = currentSize + getDirSize(file);
                            if (currentSize >= ONE_PERCENT) {
                                currentPercent = currentSize / ONE_PERCENT;
                                currentPercent++;
                                setProgress((int) currentPercent);
                                currentSize = 0;
                            }
                        }
                        } catch (IOException e){
                            e.printStackTrace();
                        }
                    }
                }
                return null;
            }
    
            @Override
            public void process(List<String> chunks) {
                for (String path : chunks) {
                    txtCopiedDirs.append(path);
                }
            }
    
            @Override
            public void done() {
                closeWindow();
            }
        }
    
        public static Long getDirSize(File file) {
            long size = 0L;
    
            if (file.isFile() && file != null) {
                size += file.isDirectory() ? getDirSize(file) : file.length();
            } else if (file.isDirectory()) {
                for (File f : file.listFiles()) {
                    size += f.isDirectory() ? getDirSize(f) : file.length();
                }
            }
            return size;
        }
    
        /* Close current window */
        public void closeWindow() {
            WindowEvent close = new WindowEvent(this, WindowEvent.WINDOW_CLOSING);
            Toolkit.getDefaultToolkit().getSystemEventQueue().postEvent(close);
            System.exit(0);
        }
    }