2012-07-25 3 views
-1

내 문제가 해결되었습니다.SaxParser와 함께 jProgressBar 사용

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(); 
    } 
} 
} 

MonitoredInputStream :

/** 
* 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); 
} 
} 

이 사용 방법 : 여기에 코드입니다

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

      public void finished() { 
       frame_progressbar.setVisible(false); 
      } 
     }; 
     worker.start(); 
: 근로자를 사용하는 방법

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가 완료 될 때까지 doWorkWkn을 실행합니다. 그 후 jFrame이 보이지 않도록 설정됩니다. doWorkWkn()은 파일을 읽고 변경 될 때마다 진행 막대를 업데이트하는 changeListener를 추가합니다.

답변

1

스윙은 NOT 스레드 안전합니다.

EventDispatchingThread을 파일 읽기로 차단하므로 UI가 업데이트되지 않습니다. 이렇게하면 진행률 표시 줄이 화면에서 업데이트되지 않습니다. @LanguagesNamedAfterCofee 제안으로

, 당신은 파일의 실제 읽기를 수행하고 UI를 업데이트하는 업데이트 방법 (publishsetProgress을)의 허용하도록 SwingWorker를 사용해야합니다.

+0

고마워! 그것은 작동합니다! 저녁에 솔루션을 게시합니다. – poldi

0

diamond operator<> 인 코드를 사용하는 경우 일치하는 제네릭으로이 문제를 해결해야합니다.

처럼은 그냥 <> 발생을 검색하고이를 해결 List<String> foo = new ArrayList<>();

List<String> foo = new ArrayList<String>();에 변환.

+0

도움 주셔서 감사합니다. 위 코드에 더 많은 코드를 추가했습니다. jProgressBar는 업데이트되지 않고 작업이 완료 될 때까지 0 %로 유지됩니다. 그 후 100 %를 보여줍니다. 이유를 알고 계십니까? 나는 이유를 알 수 없다 ... – poldi

+2

@ user1552265 SwingWorker 사용 – LanguagesNamedAfterCofee