我试图实现一个进度条,用于确定Java中另一个线程的(近似)完成百分比。现在我有两个线程同时运行,但我不确定如何链接到另一个线程。我需要它从0开始,到另一个朋友完成时,我希望进度条说100。这是我到目前为止。我几乎整天都在寻找解决方案,但似乎找不到任何东西。建议?
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileSystemView;
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.*;
import java.io.File;
public class ProgressBarTest extends JFrame {
JButton browse, search;
JTextField directory;
JProgressBar progressBar;
File file;
JList<File> results;
JScrollPane scrollPane;
// Launch the app
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
new ProgressBarTest();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
// Create the app
private ProgressBarTest() {
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setTitle("We are testing the JProgressBar");
browse = new JButton("Browse");
browse.setActionCommand("browse");
browse.addActionListener(new ButtonListener());
search = new JButton("Search");
search.setActionCommand("search");
search.addActionListener(new ButtonListener());
directory = new JTextField(20);
directory.setEnabled(false);
file = new File(System.getProperty("user.home"));
results = new JList<File>(file.listFiles());
results.setCellRenderer(new MyCellRenderer());
results.setLayoutOrientation(JList.HORIZONTAL_WRAP);
results.setVisibleRowCount(-1);
scrollPane = new JScrollPane(results, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
scrollPane.setPreferredSize(new Dimension(408, 100));
progressBar = new JProgressBar(0,100);
progressBar.setValue(0);
progressBar.setStringPainted(true);
JPanel panel1 = new JPanel();
panel1.add(browse);
panel1.add(directory);
panel1.add(search);
JPanel panel2 = new JPanel();
panel2.add(scrollPane);
JPanel panel3 = new JPanel();
panel3.add(progressBar);
this.add(panel1, BorderLayout.PAGE_START);
this.add(panel2, BorderLayout.CENTER);
this.add(panel3, BorderLayout.PAGE_END);
this.pack();
this.setLocationRelativeTo(null);
this.setVisible(true);
}
private class MyCellRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
JLabel l = (JLabel)c;
File f = (File)value;
l.setText(f.getName());
l.setPreferredSize(new Dimension(130, 20));
l.setIcon(FileSystemView.getFileSystemView().getSystemIcon(f));
l.setBorder(new EmptyBorder(3,3,3,3));
return l;
}
}
private class ButtonListener implements ActionListener {
@Override
public void actionPerformed(ActionEvent event) {
if(event.getActionCommand().equals("browse")) {
JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
chooser.setDialogTitle("Search what?");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.showOpenDialog(null);
directory.setText(chooser.getSelectedFile().getPath());
} else if (event.getActionCommand().equals("search")) {
FileThread ft = new FileThread();
ft.start();
ProgressBarThread pbt = new ProgressBarThread();
pbt.start();
}
}
}
private class FileThread extends Thread {
public void run() {
file = new File(directory.getText().trim());
results.setListData(file.listFiles());
}
}
private class ProgressBarThread extends Thread {
public void run() {
for (int i = 0; i <= 100; i++) {
progressBar.setValue(i);
progressBar.setString(Integer.toString(i));
try {
Thread.sleep(50);
} catch(InterruptedException err) {
err.printStackTrace();
}
}
}
}
}
我知道我必须用确定第一个线程的百分比/时间的东西取出for循环。只是不确定这是怎么做的。
答案 0 :(得分:0)
关键是
例如,我尝试使用下面的代码执行上述操作,一个递归列出目录和子目录中的文件,但我还不是100%满意。它使用所选目录的主子目录的完成,但它以某种方式冻结GUI,这意味着我仍然在事件线程上调用cpu或占用时间的代码。这里需要做更多的工作......
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.io.FileFilter;
import java.util.List;
import java.util.concurrent.ExecutionException;
import javax.swing.*;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileSystemView;
@SuppressWarnings("serial")
public class ProgressBarTest2 extends JPanel {
private static final int PREF_W = 420;
private static final int PREF_H = 200;
private JProgressBar progressBar = new JProgressBar(0, 100);
private DefaultListModel<File> fileListModel = new DefaultListModel<>();
private JList<File> results = new JList<>(fileListModel);
private Action browseAction = new BrowseAction("Browse", KeyEvent.VK_B);
private JButton browseButton = new JButton(browseAction);
public ProgressBarTest2() {
progressBar.setValue(0);
progressBar.setStringPainted(true);
results.setCellRenderer(new MyCellRenderer());
results.setLayoutOrientation(JList.HORIZONTAL_WRAP);
results.setVisibleRowCount(-1);
JScrollPane scrollPane = new JScrollPane(results);
scrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
JPanel topPanel = new JPanel();
topPanel.add(browseButton);
setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
setLayout(new BorderLayout(3, 3));
add(topPanel, BorderLayout.PAGE_START);
add(scrollPane, BorderLayout.CENTER);
add(progressBar, BorderLayout.PAGE_END);
}
@Override
public Dimension getPreferredSize() {
Dimension superSz = super.getPreferredSize();
if (isPreferredSizeSet()) {
return superSz;
}
int prefW = Math.max(superSz.width, PREF_W);
int prefH = Math.max(superSz.height, PREF_H);
return new Dimension(prefW, prefH);
}
public void workerIsDone() {
browseAction.setEnabled(true);
}
private class BrowseAction extends AbstractAction {
private FileWorker fileWorker;
public BrowseAction(String name, int mnemonic) {
super(name);
putValue(MNEMONIC_KEY, mnemonic);
}
@Override
public void actionPerformed(ActionEvent e) {
setEnabled(false);
progressBar.setValue(0);
JFileChooser chooser = new JFileChooser(System.getProperty("user.home"));
chooser.setDialogTitle("Search what?");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
int choice = chooser.showOpenDialog(null);
if (choice != JFileChooser.APPROVE_OPTION) {
return;
}
File file = chooser.getSelectedFile();
if (file == null) {
return;
}
if (!file.isDirectory()) {
file = file.getParentFile();
if (file == null || !file.isDirectory()) {
return;
}
}
fileWorker = new FileWorker(file);
fileWorker.addPropertyChangeListener(new FileWorkerListener());
fileWorker.execute();
}
}
class FileWorkerListener implements PropertyChangeListener {
@Override
public void propertyChange(PropertyChangeEvent evt) {
if ("progress".equals(evt.getPropertyName())) {
int progress = (int) evt.getNewValue();
progressBar.setValue(progress);
} else if ("state".equals(evt.getPropertyName())) {
if (SwingWorker.StateValue.DONE == evt.getNewValue()) {
workerIsDone();
FileWorker worker = (FileWorker) evt.getSource();
try {
worker.get();
} catch (InterruptedException | ExecutionException e) {
e.printStackTrace();
}
}
}
}
}
class FileWorker extends SwingWorker<Void, File> {
private MyFileFilter dirFilter = new MyFileFilter(true);
private MyFileFilter nonDirFilter = new MyFileFilter(false);
private File file;
public FileWorker(File file) {
this.file = file;
}
@Override
protected Void doInBackground() throws Exception {
fileListModel.clear();
File[] files = file.listFiles(nonDirFilter);
for (File file2 : files) {
publish(file2);
}
File[] dirs = file.listFiles(dirFilter);
for (int i = 0; i < dirs.length; i++) {
recurseThruDirs(dirs[i]);
int prog = (100 * i) / dirs.length;
setProgress(prog);
}
setProgress(100);
return null;
}
private void recurseThruDirs(File file) {
if (file == null) {
return;
}
File[] files = file.listFiles(nonDirFilter);
if (files != null && files.length > 0) {
for (File file2 : files) {
publish(file2);
}
}
File[] dirs = file.listFiles(dirFilter);
if (dirs != null && dirs.length > 0) {
for (int i = 0; i < dirs.length; i++) {
recurseThruDirs(dirs[i]);
}
}
}
@Override
protected void process(List<File> chunks) {
for (File file : chunks) {
fileListModel.addElement(file);
}
}
}
class MyFileFilter implements FileFilter {
private boolean directory;
public MyFileFilter(boolean directory) {
this.directory = directory;
}
@Override
public boolean accept(File pathname) {
return directory == pathname.isDirectory();
}
}
private class MyCellRenderer extends DefaultListCellRenderer {
public Component getListCellRendererComponent(JList<?> list, Object value, int index,
boolean isSelected, boolean cellHasFocus) {
Component c = super.getListCellRendererComponent(list, value, index, isSelected,
cellHasFocus);
JLabel l = (JLabel) c;
File f = (File) value;
l.setText(f.getName());
l.setPreferredSize(new Dimension(130, 20));
l.setIcon(FileSystemView.getFileSystemView().getSystemIcon(f));
l.setBorder(new EmptyBorder(3, 3, 3, 3));
return l;
}
}
private static void createAndShowGui() {
ProgressBarTest2 mainPanel = new ProgressBarTest2();
JFrame frame = new JFrame("ProgressBarTest2");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(mainPanel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> createAndShowGui());
}
}