Java 在SwingWorker中实现JScrollPane/JTextArea
使用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
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);
}
}