-1

我的问题解决了。这是代码:

SwingWorker 类:

package ths.turnier;

import javax.swing.SwingUtilities;

/**
* This is the 3rd version of SwingWorker (also known as
* SwingWorker 3), an abstract class that you subclass to
* perform GUI-related work in a dedicated thread.  For
* instructions on using this class, see:
* 
* http://java.sun.com/docs/books/tutorial/uiswing/misc/threads.html
*
* Note that the API changed slightly in the 3rd version:
* You must now invoke start() on the SwingWorker after
* creating it.
*/
public abstract class SwingWorker {
private Object value;  // see getValue(), setValue()
private Thread thread;

/** 
 * Class to maintain reference to current worker thread
 * under separate synchronization control.
 */
private static class ThreadVar {
    private Thread thread;
    ThreadVar(Thread t) { thread = t; }
    synchronized Thread get() { return thread; }
    synchronized void clear() { thread = null; }
}

private ThreadVar threadVar;

/** 
 * Get the value produced by the worker thread, or null if it 
 * hasn't been constructed yet.
 */
protected synchronized Object getValue() { 
    return value; 
}

/** 
 * Set the value produced by worker thread 
 */
private synchronized void setValue(Object x) { 
    value = x; 
}

/** 
 * Compute the value to be returned by the <code>get</code> method. 
 */
public abstract Object construct();

/**
 *           public void run() { finished(); } Called on the event dispatching thread (not on the worker thread)
 * after the <code>construct</code> method has returned.
 */
public void finished() {
}

/**
 * A new method that interrupts the worker thread.  Call this method
 * to force the worker to stop what it's doing.
 */
public void interrupt() {
    Thread t = threadVar.get();
    if (t != null) {
        t.interrupt();
    }
    threadVar.clear();
}

/**
 * Return the value created by the <code>construct</code> method.  
 * Returns null if either the constructing thread or the current
 * thread was interrupted before a value was produced.
 * 
 * @return the value created by the <code>construct</code> method
 */
public Object get() {
    while (true) {  
        Thread t = threadVar.get();
        if (t == null) {
            return getValue();
        }
        try {
            t.join();
        }
        catch (InterruptedException e) {
            Thread.currentThread().interrupt(); // propagate
            return null;
        }
    }
}


/**
 * Start a thread that will call the <code>construct</code> method
 * and then exit.
 */
public SwingWorker() {
    final Runnable doFinished = new Runnable() {
       public void run() { finished(); }
    };

    Runnable doConstruct = new Runnable() { 
        public void run() {
            try {
                setValue(construct());
            }
            finally {
                threadVar.clear();
            }

            SwingUtilities.invokeLater(doFinished);
        }
    };

    Thread t = new Thread(doConstruct);
    threadVar = new ThreadVar(t);
}

/**
 * Start the worker thread.
 */
public void start() {
    Thread t = threadVar.get();
    if (t != null) {
        t.start();
    }
}
}

监控输入流:

/**
* A class that monitors the read progress of an input stream.
* 
* @author Hermia Yeung "Sheepy"
* @since 2012-04-05 18:42
*/ 
public class MonitoredInputStream extends FilterInputStream {
private volatile long mark = 0;
private volatile long lastTriggeredLocation = 0;
private volatile long location = 0;
private final int threshold;
private final List<ChangeListener> listeners = new ArrayList<ChangeListener>(4);

/**
* Creates a MonitoredInputStream over an underlying input stream.
* @param in Underlying input stream, should be non-null because of no public setter
* @param threshold Min. position change (in byte) to trigger change event.
*/
public MonitoredInputStream(InputStream in, int threshold) {
  super(in);
  this.threshold = threshold;
}

/**
* Creates a MonitoredInputStream over an underlying input stream.
* Default threshold is 16KB, small threshold may impact performance impact on larger streams.
* @param in Underlying input stream, should be non-null because of no public setter
*/
public MonitoredInputStream(InputStream in) {
  super(in);
  this.threshold = 1024*16;
}

public void addChangeListener(ChangeListener l) { if (!listeners.contains(l)) listeners.add(l); }
public void removeChangeListener(ChangeListener l) { listeners.remove(l); }
public long getProgress() { return location; }

protected void triggerChanged( final long location ) {
  if ( threshold > 0 && Math.abs( location-lastTriggeredLocation ) < threshold ) return;
  lastTriggeredLocation = location;
  if (listeners.size() <= 0) return;
  try {
     final ChangeEvent evt = new ChangeEvent(this);
     for (ChangeListener l : listeners) l.stateChanged(evt);
  } catch (ConcurrentModificationException e) {
     triggerChanged(location);  // List changed? Let's re-try.
  }
}


@Override public int read() throws IOException {
  final int i = super.read();
  if ( i != -1 ) triggerChanged( location++ );
  return i;
}

@Override public int read(byte[] b, int off, int len) throws IOException {
  final int i = super.read(b, off, len);
  if ( i > 0 ) triggerChanged( location += i );
  return i;
}

@Override public long skip(long n) throws IOException {
  final long i = super.skip(n);
  if ( i > 0 ) triggerChanged( location += i );
  return i;
}

@Override public void mark(int readlimit) {
  super.mark(readlimit);
  mark = location;
}

@Override public void reset() throws IOException {
  super.reset();
  if ( location != mark ) triggerChanged( location = mark );
}
}

如何使用这个:

void updateProgressWknAdd(final int i)
{
Runnable doSetProgress = new Runnable() {
public void run() {
progressWknAdd.setValue(i);
}
};
SwingUtilities.invokeLater(doSetProgress);
}

   Object doWorkWkn(String pfad) {
// Code which reads file + setting the max of jprogressbar to file size. and:
final MonitoredInputStream mis = new MonitoredInputStream(fis);
        mis.addChangeListener( new ChangeListener() { @Override public void stateChanged(ChangeEvent e) {
        updateProgressWknRead((int) mis.getProgress()); 
        }});
}

如何使用工人:

    SwingWorker worker = new SwingWorker() {
            public Object construct() {
                return doWorkWkn(pfad_zur_datei);
            }

            public void finished() {
                frame_progressbar.setVisible(false);
            }
        };
        worker.start();

swingWorker 运行 doWorkWkn 直到完成。之后,将 jFrame 设置为不可见。doWorkWkn() 读取文件并添加一个 changeListener,它会在每次更改时更新进度条。

4

2 回答 2

1

Swing不是线程安全的。

UI 不会更新,因为您在读取文件时阻塞了EventDispatchingThread。这会阻止进度条在屏幕上更新。

正如@LanguagesNamedAfterCofee 所建议的那样,您应该使用SwingWorker来执行文件的实际读取并允许它的更新方法(publishsetProgress)来更新 UI。

于 2012-07-26T03:02:17.957 回答
0

在您使用的代码中的某处,您使用的diamond operator<>您必须将其解析为匹配的泛型。

像转换List<String> foo = new ArrayList<>();List<String> foo = new ArrayList<String>();

只需搜索<>事件并解决它。

于 2012-07-25T22:15:22.873 回答