All Downloads are FREE. Search and download functionalities are using the official Maven repository.

uk.ac.starlink.table.gui.ProgressBarStarTable Maven / Gradle / Ivy

There is a newer version: 4.3
Show newest version
package uk.ac.starlink.table.gui;

import java.io.IOException;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BooleanSupplier;
import java.util.function.LongSupplier;
import javax.swing.JProgressBar;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import uk.ac.starlink.table.ProgressRowSplittable;
import uk.ac.starlink.table.RowSequence;
import uk.ac.starlink.table.RowSplittable;
import uk.ac.starlink.table.StarTable;
import uk.ac.starlink.table.WrapperRowSequence;
import uk.ac.starlink.table.WrapperStarTable;

/**
 * A WrapperStarTable which behaves the same as its base, except that 
 * UI intervention is permitted on any RowSequence which is taken out on it.
 * It provides two services:
 * 
    *
  1. Iteration using {@link #getRowSequence} or {@link #getRowSplittable} * will update a supplied {@link javax.swing.JProgressBar} as it goes. *
  2. Iteration can be forced to terminate based on the behaviour of * a given BooleanSupplier. *
  3. *
* *

You might think this should be based on a * {@link javax.swing.BoundedRangeModel} (JProgressBar's model) instead, * but unfortunately that doesn't allow you use of * indeterminate progress states. * * @author Mark Taylor (Starlink) */ public class ProgressBarStarTable extends WrapperStarTable { private JProgressBar progBar_; private BooleanSupplier isCancelled_; private String label_; private static final int INTERVAL = 250; /** * Constructor with default cancellation control. * Iteration is cancelled if the calling thread is interrupted. * This may be appropriate for single-threaded iteration * (using a RowSequence), * but is unlikely to achieve cancellation of multi-threaded iteration * (using a RowSplittable). * * @param baseTable table supplying data * @param progBar progress bar to update */ public ProgressBarStarTable( StarTable baseTable, JProgressBar progBar ) { this( baseTable, progBar, Thread::interrupted ); } /** * Constructor with supplied cancellation control. * * @param baseTable table supplying data * @param progBar progress bar to update * @param isCancelled object controlling cancellation: * if it supplies a true value, * the next method of any * RowSequence or * RowSplittable taken out on * this table will (probably, at some point) * throw IOExceptions */ public ProgressBarStarTable( StarTable baseTable, JProgressBar progBar, BooleanSupplier isCancelled ) { super( baseTable ); setProgressBar( progBar ); isCancelled_ = isCancelled; } /** * Sets the progress bar which this table controls. * * @param progBar progress bar */ public void setProgressBar( JProgressBar progBar ) { progBar_ = progBar; } /** * Returns the progress bar which this table controls. * * @return progress bar */ public JProgressBar getProgressBar() { return progBar_; } /** * Sets a label which will be visible in the progress bar when a * RowSequence acquired from this table is being iterated over. * * @param label label text */ public void setActiveLabel( String label ) { label_ = label; progBar_.setStringPainted( label != null && label.trim().length() > 0 ); } /** * Returns the text of the label which is visible in the progress bar * when a RowSequence acquired from this table is active. * * @return label text */ public String getActiveLabel() { return label_; } public RowSequence getRowSequence() throws IOException { setZero( true ); return new WrapperRowSequence( baseTable.getRowSequence() ) { long irow; Timer timer = startProgressTimer( () -> irow ); public boolean next() throws IOException { if ( isCancelled_.getAsBoolean() ) { timer.stop(); throw new IOException( "Cancelled" ); } else { irow++; return super.next(); } } public void close() throws IOException { timer.stop(); setZero( false ); super.close(); } }; } public RowSplittable getRowSplittable() throws IOException { setZero( true ); ProgressRowSplittable.Target target = new ProgressRowSplittable.Target() { AtomicLong irow = new AtomicLong(); Timer timer = startProgressTimer( () -> irow.get() ); public void updateCount( long count ) throws IOException { if ( isCancelled_.getAsBoolean() ) { timer.stop(); throw new IOException( "Cancelled" ); } irow.set( count ); } public void done( long count ) { timer.stop(); setZero( false ); } }; return new ProgressRowSplittable( super.getRowSplittable(), target ); } /** * Returns a running timer that will update the progress bar periodically. * * @param counter yields the current row count * @return started timer */ private Timer startProgressTimer( final LongSupplier counter ) { Timer timer = new Timer( INTERVAL, evt -> { if ( progBar_ != null ) { progBar_.setValue( (int) counter.getAsLong() ); } } ); timer.setInitialDelay( 0 ); timer.setCoalesce( true ); timer.start(); return timer; } /** * Resets the progress bar to its minimum. * * @param labelOn if true, display the active label in the progress bar; * if false, remove it */ private void setZero( final boolean labelOn ) { SwingUtilities.invokeLater( new Runnable() { public void run() { if ( progBar_ != null ) { progBar_.setMinimum( 0 ); progBar_.setValue( 0 ); long nrow = getRowCount(); boolean determinate = nrow > 0 && nrow < Integer.MAX_VALUE; progBar_.setIndeterminate( ! determinate ); if ( determinate ) { progBar_.setMaximum( (int) nrow ); } progBar_.setString( labelOn ? label_ : "" ); } } } ); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy