- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
使用 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();
}
}
这不是确切的代码,但它应该可以让您了解其要点。不管怎样,问题是 JScrollPane 根本没有出现,尽管 doInBackground() 方法中的代码确实运行了。我希望它与后台任务中的更新(txtDirs.append(file.getAbsolutePath())
)有关。但是,我不太确定在这种情况下如何使其发挥作用。该框架按预期显示,但完全是空白的。 Task
类中应该有一个“process”方法吗?那是“txtDirs.append(file.getAbsolutePath())
”应该放置的地方吗?恐怕我对 SwingWorkers 的使用相当陌生,所以任何帮助将不胜感激。
编辑:
经过一番困惑后,我决定简单地发布我的完整代码。我知道它有问题,而且我可能误解了评论中提到的一些内容,所以我希望发布此内容能让有人指出我所犯的任何明显错误。
完整代码:
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JButton;
import javax.swing.JProgressBar;
import javax.swing.JLabel;
import javax.swing.SwingWorker;
import org.apache.commons.io.FileUtils;
@SuppressWarnings("serial")
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");
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
txtCopiedDirs = new JTextArea(10, 50);
txtCopiedDirs.setEditable(false);
contentPane.add(new JScrollPane(txtCopiedDirs));
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();
}
/**
* Swing Worker class
*/
class Task extends SwingWorker<Void, String>{
@Override
public Void doInBackground(){
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);
publish(file.getAbsolutePath() + "\n");
}
if(getDirSize(file) >= ONE_PERCENT){
currentPercent = getDirSize(file)/ONE_PERCENT;
progressBar.setValue((int)currentPercent);
currentSize = 0;
} else {
currentSize = currentSize + getDirSize(file);
if(currentSize >= ONE_PERCENT){
currentPercent = currentSize/ONE_PERCENT;
currentPercent++;
progressBar.setValue((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);
}
}
编辑#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();
}
最佳答案
setBounds
,而是使用 JTextArea(rows, cols)
publish
并覆盖process
。 process
在 EDT 的内容中调用看看Concurrency in Swing了解更多详情
导致您的问题的可能原因包括...
BorderLayout
时向框架添加其他组件,不指定位置约束(BorderLayout.CENTER
除外)已更新
主要问题是 contentPane
正在使用 null
布局和滚动 Pane 的默认边界是 0x0
位置 0x0
宽度和高度。
最好的选择是不使用WinodwBuilder并学习如何使用layout managers
用示例更新
这是一个使用两个布局管理器的示例,BorderLayout
作为基本布局和 GridBagLayout
为额外的组件提供一些额外的支持。
基本经验法则。如果它是 UI 组件,特别是如果它在屏幕上(或者您不知道它是否在屏幕上),则必须仅从 EDT 的上下文中更新它。
这意味着调用progressBar.setValue
来自doInBackground
内违反了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 - 在 SwingWorker 中实现 JScrollPane/JTextArea,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20778551/
我有一个 SwingWorker 如下: public class MainWorker extends SwingWorker(Void, MyObject) { : : } 我从
我正在尝试从另一个 SwingWorker (MainWorker) 执行 SwingWorker (SubWorker),然后我希望 MainWorker 等待 SubWorker 完成。同时,Ma
我试图在 SO 上找到我的问题的答案,但由于它们的丰富性和多样性,我有点困惑。这是我的问题:我的应用程序比较两个文件并在 Swing.JTextPane 中打印结果。我使用按钮调用处理文件的代码,为了
我使用一个扩展 SwingWorker 的类,如下所示: public class Analyzer extends SwingWorker { String source; public A
我有一个作为 Java SwingWorker 运行的套接字服务器。 SwingWorker 接收传入的连接,并在连接后将套接字移交给负责连接的执行器。 Executor 调用将通过 run() 方法
我需要运行两个 SwingWorker。其中一个只能在另一个完成后才能运行。我可以像这样运行它们吗? class TestWorker { private FirstWorker worker
我对SwingWorker有疑问它是done()方法。我有一个通过 SPI 支持插件的应用程序,所以我基本上无法更改插件的行为。这些插件必须实现的接口(interface)包含方法 List getC
jList 模型中包含的数据由 swingworker 更新。问题是我在独立的 *.java 文件中对 SwingWorker 类进行了子类化。所以我无法访问 GUI 组件(在本例中为模型和 jLis
我正在创建一个进度条来监控图像下载。图像下载不起作用 - 它会生成一个大小为 0 字节的文件。如果我将代码移至没有 SwingWorker 的独立类,则图像下载可以正常工作。我已经玩了一段时间了,但我
首先,我需要通知您,我正在尽最大努力学习如何使用 Java 编写代码。这有点困难,但是,我相信我做到了。我过去曾提交过几个关于 SwingWorkers 等的问题。每一个我都以为我拥有它,但后来发现我
假设一个应用程序读取数据文件,从用户获取一些输入(通过 GUI),从大型数据库获取附加数据并执行冗长的分析。 按照建议,我将耗时的部分(数据库管理和实际分析)删除到了 SwingWorker 实例中。
我有几个 SwingWorker 正在运行,它们都需要 OpenNLP 进行计算。OpenNLP 需要一些时间进行初始化,所以我想知道最好的方法是什么?我想在每个 SwingWorker 中启动一个
我有一个小 gui 程序,它在启动时从 Excel 文件中读取数据,其中一些数据需要转到相关的组合框。我知道如何通过为每个组合框使用单独的 SwingWorker 来做到这一点: public cla
有人能告诉我为什么在这个使用 SwingWorker 的简单演示中,屏幕闪烁,好像按钮不断跳跃一样? (关于改进多线程部分的反馈也值得赞赏)。 import java.awt.EventQueue;
在 Netbeans 中,我创建了一个 GUI 项目,该项目使用框架前端,我可以添加组件并双击以编辑其事件。我指的是具有“源”、“设计”和“历史”选项卡的窗口。 以下是组件和关系: 1- 打开文件选择
有没有办法在调用“swingWorker.execute”之前将数据(例如对象)传递给 swingWorker? 最佳答案 通常,我通过使 SwingWorker 的构造函数需要所需的对象来处理此问题
我有这样的代码 try { ServerSocket serverSocket = null; try { serverSocket = new
如何获取代码当前运行的SwingWorker?您可以使用 Thread.currentThread() 来获取 Thread 实例,但我需要 SwingWorker 实例。 代码来自评论 privat
我有一个扩展 SwingWorker 的类。在它的后台线程中,如果成功更改布局并向框架添加新面板,我应该登录。因此 Swing Worker 执行以下 3 项任务: 登录 更改布局 添加/删除面板。
我有一个 swingworker,我想用它从 doInBackground() swingworker 方法中调用另一个对象的大型且复杂的方法。 看起来像这样: public class HostGa
我是一名优秀的程序员,十分优秀!