Added ProgressDialog superclass
This commit is contained in:
parent
a879071dbd
commit
4a091297ed
5 changed files with 260 additions and 272 deletions
|
@ -26,7 +26,7 @@ public class FTLModManager {
|
||||||
private static final Logger log = LogManager.getLogger(FTLModManager.class);
|
private static final Logger log = LogManager.getLogger(FTLModManager.class);
|
||||||
|
|
||||||
private static final String APP_NAME = "Slipstream Mod Manager";
|
private static final String APP_NAME = "Slipstream Mod Manager";
|
||||||
private static final ComparableVersion APP_VERSION = new ComparableVersion( "1.1" );
|
private static final ComparableVersion APP_VERSION = new ComparableVersion( "???" );
|
||||||
private static final String APP_URL = "http://www.ftlgame.com/forum/viewtopic.php?f=12&t=17102";
|
private static final String APP_URL = "http://www.ftlgame.com/forum/viewtopic.php?f=12&t=17102";
|
||||||
private static final String APP_AUTHOR = "Vhati";
|
private static final String APP_AUTHOR = "Vhati";
|
||||||
|
|
||||||
|
|
|
@ -1,21 +1,11 @@
|
||||||
package net.vhati.modmanager.ui;
|
package net.vhati.modmanager.ui;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.Box;
|
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JProgressBar;
|
|
||||||
import javax.swing.JTextArea;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import net.vhati.ftldat.FTLDat;
|
import net.vhati.ftldat.FTLDat;
|
||||||
|
@ -24,60 +14,23 @@ import org.apache.logging.log4j.LogManager;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
|
||||||
|
|
||||||
public class DatExtractDialog extends JDialog implements ActionListener {
|
public class DatExtractDialog extends ProgressDialog {
|
||||||
|
|
||||||
private static final Logger log = LogManager.getLogger(DatExtractDialog.class);
|
private static final Logger log = LogManager.getLogger(DatExtractDialog.class);
|
||||||
|
|
||||||
private JProgressBar progressBar;
|
private boolean started = false;
|
||||||
private JTextArea statusArea;
|
|
||||||
private JButton continueBtn;
|
|
||||||
|
|
||||||
private boolean extracting = false;
|
|
||||||
private boolean done = false;
|
|
||||||
|
|
||||||
private File extractDir;
|
private File extractDir;
|
||||||
private File[] datFiles;
|
private File[] datFiles;
|
||||||
|
|
||||||
|
|
||||||
DatExtractDialog( Frame owner, File extractDir, File[] datFiles ) {
|
public DatExtractDialog( Frame owner, File extractDir, File[] datFiles ) {
|
||||||
super( owner, "Extracting...", true );
|
super( owner, false );
|
||||||
this.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE );
|
this.setTitle( "Extracting..." );
|
||||||
|
|
||||||
this.extractDir = extractDir;
|
this.extractDir = extractDir;
|
||||||
this.datFiles = datFiles;
|
this.datFiles = datFiles;
|
||||||
|
|
||||||
progressBar = new JProgressBar();
|
|
||||||
progressBar.setBorderPainted( true );
|
|
||||||
progressBar.setStringPainted( false );
|
|
||||||
|
|
||||||
JPanel progressHolder = new JPanel( new BorderLayout() );
|
|
||||||
progressHolder.setBorder( BorderFactory.createEmptyBorder( 10, 15, 0, 15 ) );
|
|
||||||
progressHolder.add( progressBar );
|
|
||||||
getContentPane().add( progressHolder, BorderLayout.NORTH );
|
|
||||||
|
|
||||||
statusArea = new JTextArea();
|
|
||||||
statusArea.setBorder( BorderFactory.createEtchedBorder() );
|
|
||||||
statusArea.setLineWrap( true );
|
|
||||||
statusArea.setWrapStyleWord( true );
|
|
||||||
statusArea.setEditable( false );
|
|
||||||
|
|
||||||
JPanel statusHolder = new JPanel( new BorderLayout() );
|
|
||||||
statusHolder.setBorder( BorderFactory.createEmptyBorder( 15, 15, 15, 15 ) );
|
|
||||||
statusHolder.add( statusArea );
|
|
||||||
getContentPane().add( statusHolder, BorderLayout.CENTER );
|
|
||||||
|
|
||||||
continueBtn = new JButton( "Continue" );
|
|
||||||
continueBtn.setEnabled( false );
|
|
||||||
continueBtn.addActionListener( this );
|
|
||||||
|
|
||||||
JPanel continueHolder = new JPanel();
|
|
||||||
continueHolder.setLayout( new BoxLayout( continueHolder, BoxLayout.X_AXIS ) );
|
|
||||||
continueHolder.setBorder( BorderFactory.createEmptyBorder( 0, 0, 10, 0 ) );
|
|
||||||
continueHolder.add( Box.createHorizontalGlue() );
|
|
||||||
continueHolder.add( continueBtn );
|
|
||||||
continueHolder.add( Box.createHorizontalGlue() );
|
|
||||||
getContentPane().add( continueHolder, BorderLayout.SOUTH );
|
|
||||||
|
|
||||||
this.setSize( 400, 160 );
|
this.setSize( 400, 160 );
|
||||||
this.setMinimumSize( this.getPreferredSize() );
|
this.setMinimumSize( this.getPreferredSize() );
|
||||||
this.setLocationRelativeTo( owner );
|
this.setLocationRelativeTo( owner );
|
||||||
|
@ -85,85 +38,25 @@ public class DatExtractDialog extends JDialog implements ActionListener {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts the background extraction thread.
|
* Starts the background extraction thread.
|
||||||
|
* Call this immediately before setVisible().
|
||||||
*/
|
*/
|
||||||
public void extract() {
|
public void extract() {
|
||||||
if ( extracting ) return;
|
if ( started ) return;
|
||||||
|
|
||||||
DatExtractThread t = new DatExtractThread( extractDir, datFiles );
|
DatExtractThread t = new DatExtractThread( extractDir, datFiles );
|
||||||
t.start();
|
t.start();
|
||||||
|
started = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed( ActionEvent e ) {
|
protected void setTaskOutcome( boolean outcome, Exception e ) {
|
||||||
Object source = e.getSource();
|
super.setTaskOutcome( outcome, e );
|
||||||
|
if ( !this.isShowing() ) return;
|
||||||
|
|
||||||
if ( source == continueBtn ) {
|
if ( succeeded )
|
||||||
this.setVisible( false );
|
setStatusText( "All resources extracted successfully." );
|
||||||
this.dispose();
|
else
|
||||||
}
|
setStatusText( String.format( "Error extracting dats: %s", e ) );
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setStatusText( String message ) {
|
|
||||||
statusArea.setText( message != null ? message : "..." );
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setProgress( final int n ) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
progressBar.setValue( n );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void setMaximum( final int n ) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
progressBar.setMaximum( n );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extractingInnerPath( final String innerPath ) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setStatusText( innerPath );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public void extractingEnded( final boolean success, final Exception e ) {
|
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if ( success )
|
|
||||||
setStatusText( "All resources extracted successfully." );
|
|
||||||
else
|
|
||||||
setStatusText( String.format( "Error extracting dats: %s", e ) );
|
|
||||||
|
|
||||||
done = true;
|
|
||||||
continueBtn.setEnabled( true );
|
|
||||||
|
|
||||||
if ( !DatExtractDialog.this.isShowing() ) {
|
|
||||||
// The window's not visible, no continueBtn to click.
|
|
||||||
DatExtractDialog.this.dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Shows or hides this component depending on the value of parameter b.
|
|
||||||
*
|
|
||||||
* If extracting has already completed, this method will do nothing.
|
|
||||||
*/
|
|
||||||
public void setVisible( boolean b ) {
|
|
||||||
if ( !done ) super.setVisible( b );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -193,27 +86,26 @@ public class DatExtractDialog extends JDialog implements ActionListener {
|
||||||
for ( File datFile : datFiles ) {
|
for ( File datFile : datFiles ) {
|
||||||
srcP = new FTLDat.FTLPack( datFile, false );
|
srcP = new FTLDat.FTLPack( datFile, false );
|
||||||
progress = 0;
|
progress = 0;
|
||||||
setProgress( progress );
|
|
||||||
List<String> innerPaths = srcP.list();
|
List<String> innerPaths = srcP.list();
|
||||||
setMaximum( innerPaths.size() );
|
setProgressLater( progress, innerPaths.size() );
|
||||||
|
|
||||||
for ( String innerPath : innerPaths ) {
|
for ( String innerPath : innerPaths ) {
|
||||||
extractingInnerPath( innerPath );
|
setStatusTextLater( innerPath );
|
||||||
if ( dstP.contains( innerPath ) ) {
|
if ( dstP.contains( innerPath ) ) {
|
||||||
log.info( "While extracting resources, this file was overwritten: "+ innerPath );
|
log.info( "While extracting resources, this file was overwritten: "+ innerPath );
|
||||||
dstP.remove( innerPath );
|
dstP.remove( innerPath );
|
||||||
}
|
}
|
||||||
is = srcP.getInputStream( innerPath );
|
is = srcP.getInputStream( innerPath );
|
||||||
dstP.add( innerPath, is );
|
dstP.add( innerPath, is );
|
||||||
setProgress( progress++ );
|
setProgressLater( progress++ );
|
||||||
}
|
}
|
||||||
srcP.close();
|
srcP.close();
|
||||||
}
|
}
|
||||||
extractingEnded( true, null );
|
setTaskOutcomeLater( true, null );
|
||||||
}
|
}
|
||||||
catch ( Exception ex ) {
|
catch ( Exception ex ) {
|
||||||
log.error( "Error extracting dats.", ex );
|
log.error( "Error extracting dats.", ex );
|
||||||
extractingEnded( false, ex );
|
setTaskOutcomeLater( false, ex );
|
||||||
}
|
}
|
||||||
finally {
|
finally {
|
||||||
try {if ( is != null ) is.close();}
|
try {if ( is != null ) is.close();}
|
||||||
|
|
|
@ -582,7 +582,7 @@ public class ManagerFrame extends JFrame implements ActionListener, HashObserver
|
||||||
resDat.datFile = new File( datsDir, "resource.dat" );
|
resDat.datFile = new File( datsDir, "resource.dat" );
|
||||||
resDat.bakFile = new File( backupDir, "resource.dat.bak" );
|
resDat.bakFile = new File( backupDir, "resource.dat.bak" );
|
||||||
|
|
||||||
ModPatchDialog patchDlg = new ModPatchDialog( this );
|
ModPatchDialog patchDlg = new ModPatchDialog( this, true );
|
||||||
patchDlg.setSuccessTask( new SpawnGameTask() );
|
patchDlg.setSuccessTask( new SpawnGameTask() );
|
||||||
|
|
||||||
log.info( "" );
|
log.info( "" );
|
||||||
|
|
|
@ -1,68 +1,19 @@
|
||||||
package net.vhati.modmanager.ui;
|
package net.vhati.modmanager.ui;
|
||||||
|
|
||||||
import java.awt.BorderLayout;
|
|
||||||
import java.awt.Frame;
|
import java.awt.Frame;
|
||||||
import java.awt.event.ActionEvent;
|
|
||||||
import java.awt.event.ActionListener;
|
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import javax.swing.BorderFactory;
|
|
||||||
import javax.swing.Box;
|
|
||||||
import javax.swing.BoxLayout;
|
|
||||||
import javax.swing.JButton;
|
|
||||||
import javax.swing.JDialog;
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JPanel;
|
|
||||||
import javax.swing.JProgressBar;
|
|
||||||
import javax.swing.JTextArea;
|
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
import net.vhati.modmanager.core.ModPatchObserver;
|
import net.vhati.modmanager.core.ModPatchObserver;
|
||||||
|
|
||||||
|
|
||||||
public class ModPatchDialog extends JDialog implements ActionListener, ModPatchObserver {
|
public class ModPatchDialog extends ProgressDialog implements ModPatchObserver {
|
||||||
|
|
||||||
private JProgressBar progressBar;
|
|
||||||
private JTextArea statusArea;
|
|
||||||
private JButton continueBtn;
|
|
||||||
|
|
||||||
private boolean done = false;
|
|
||||||
private boolean patchingSucceeded = false;
|
|
||||||
private Runnable successTask = null;
|
|
||||||
|
|
||||||
|
|
||||||
public ModPatchDialog( Frame owner ) {
|
public ModPatchDialog( Frame owner, boolean continueOnSuccess ) {
|
||||||
super( owner, "Patching...", true );
|
super( owner, true );
|
||||||
this.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE );
|
this.setTitle( "Patching..." );
|
||||||
|
|
||||||
progressBar = new JProgressBar();
|
|
||||||
progressBar.setBorderPainted( true );
|
|
||||||
|
|
||||||
JPanel progressHolder = new JPanel( new BorderLayout() );
|
|
||||||
progressHolder.setBorder( BorderFactory.createEmptyBorder( 10, 15, 0, 15 ) );
|
|
||||||
progressHolder.add( progressBar );
|
|
||||||
getContentPane().add( progressHolder, BorderLayout.NORTH );
|
|
||||||
|
|
||||||
statusArea = new JTextArea();
|
|
||||||
statusArea.setBorder( BorderFactory.createEtchedBorder() );
|
|
||||||
statusArea.setLineWrap( true );
|
|
||||||
statusArea.setWrapStyleWord( true );
|
|
||||||
statusArea.setEditable( false );
|
|
||||||
|
|
||||||
JPanel statusHolder = new JPanel( new BorderLayout() );
|
|
||||||
statusHolder.setBorder( BorderFactory.createEmptyBorder( 15, 15, 15, 15 ) );
|
|
||||||
statusHolder.add( statusArea );
|
|
||||||
getContentPane().add( statusHolder, BorderLayout.CENTER );
|
|
||||||
|
|
||||||
continueBtn = new JButton( "Continue" );
|
|
||||||
continueBtn.setEnabled( false );
|
|
||||||
continueBtn.addActionListener( this );
|
|
||||||
|
|
||||||
JPanel continueHolder = new JPanel();
|
|
||||||
continueHolder.setLayout( new BoxLayout( continueHolder, BoxLayout.X_AXIS ) );
|
|
||||||
continueHolder.setBorder( BorderFactory.createEmptyBorder( 0, 0, 10, 0 ) );
|
|
||||||
continueHolder.add( Box.createHorizontalGlue() );
|
|
||||||
continueHolder.add( continueBtn );
|
|
||||||
continueHolder.add( Box.createHorizontalGlue() );
|
|
||||||
getContentPane().add( continueHolder, BorderLayout.SOUTH );
|
|
||||||
|
|
||||||
this.setSize( 400, 160 );
|
this.setSize( 400, 160 );
|
||||||
this.setMinimumSize( this.getPreferredSize() );
|
this.setMinimumSize( this.getPreferredSize() );
|
||||||
|
@ -70,26 +21,6 @@ public class ModPatchDialog extends JDialog implements ActionListener, ModPatchO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void actionPerformed( ActionEvent e ) {
|
|
||||||
Object source = e.getSource();
|
|
||||||
|
|
||||||
if ( source == continueBtn ) {
|
|
||||||
this.setVisible( false );
|
|
||||||
this.dispose();
|
|
||||||
|
|
||||||
if ( done && patchingSucceeded && successTask != null ) {
|
|
||||||
successTask.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private void setStatusText( String message ) {
|
|
||||||
statusArea.setText( message != null ? message : "..." );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Updates the progress bar.
|
* Updates the progress bar.
|
||||||
*
|
*
|
||||||
|
@ -100,26 +31,7 @@ public class ModPatchDialog extends JDialog implements ActionListener, ModPatchO
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void patchingProgress( final int value, final int max ) {
|
public void patchingProgress( final int value, final int max ) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
this.setProgressLater( value, max );
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if ( value >= 0 && max >= 0 ) {
|
|
||||||
if ( progressBar.isIndeterminate() )
|
|
||||||
progressBar.setIndeterminate( false );
|
|
||||||
|
|
||||||
if ( progressBar.getMaximum() != max ) {
|
|
||||||
progressBar.setValue( 0 );
|
|
||||||
progressBar.setMaximum( max );
|
|
||||||
}
|
|
||||||
progressBar.setValue( value );
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
if ( !progressBar.isIndeterminate() )
|
|
||||||
progressBar.setIndeterminate( true );
|
|
||||||
progressBar.setValue( 0 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -129,12 +41,7 @@ public class ModPatchDialog extends JDialog implements ActionListener, ModPatchO
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void patchingStatus( final String message ) {
|
public void patchingStatus( final String message ) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
setStatusTextLater( message != null ? message : "..." );
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setStatusText( message != null ? message : "..." );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -142,12 +49,7 @@ public class ModPatchDialog extends JDialog implements ActionListener, ModPatchO
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void patchingMod( final File modFile ) {
|
public void patchingMod( final File modFile ) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
setStatusTextLater( String.format( "Installing mod \"%s\"...", modFile.getName() ) );
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
setStatusText( String.format( "Installing mod \"%s\"...", modFile.getName() ) );
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -156,46 +58,19 @@ public class ModPatchDialog extends JDialog implements ActionListener, ModPatchO
|
||||||
* If anything went wrong, e may be non-null.
|
* If anything went wrong, e may be non-null.
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void patchingEnded( final boolean success, final Exception e ) {
|
public void patchingEnded( boolean outcome, Exception e ) {
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
setTaskOutcomeLater( outcome, e );
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
if ( success )
|
|
||||||
setStatusText( "Patching completed." );
|
|
||||||
else
|
|
||||||
setStatusText( String.format( "Patching failed: %s", e ) );
|
|
||||||
|
|
||||||
done = true;
|
|
||||||
patchingSucceeded = success;
|
|
||||||
|
|
||||||
continueBtn.setEnabled( true );
|
|
||||||
|
|
||||||
if ( !ModPatchDialog.this.isShowing() ) {
|
|
||||||
// The window's not visible, no continueBtn to click.
|
|
||||||
ModPatchDialog.this.dispose();
|
|
||||||
|
|
||||||
if ( patchingSucceeded && successTask != null ) {
|
|
||||||
successTask.run();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
@Override
|
||||||
* Sets a runnable to trigger after patching successfully.
|
protected void setTaskOutcome( boolean outcome, Exception e ) {
|
||||||
*/
|
super.setTaskOutcome( outcome, e );
|
||||||
public void setSuccessTask( Runnable r ) {
|
if ( !this.isShowing() ) return;
|
||||||
successTask = r;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if ( succeeded == true )
|
||||||
* Shows or hides this component depending on the value of parameter b.
|
setStatusText( "Patching completed." );
|
||||||
*
|
else
|
||||||
* If patching has already completed, this method will do nothing.
|
setStatusText( String.format( "Patching failed: %s", e ) );
|
||||||
*/
|
|
||||||
public void setVisible( boolean b ) {
|
|
||||||
if ( !done ) super.setVisible( b );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
221
src/main/java/net/vhati/modmanager/ui/ProgressDialog.java
Normal file
221
src/main/java/net/vhati/modmanager/ui/ProgressDialog.java
Normal file
|
@ -0,0 +1,221 @@
|
||||||
|
package net.vhati.modmanager.ui;
|
||||||
|
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Frame;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.File;
|
||||||
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JProgressBar;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.SwingUtilities;
|
||||||
|
|
||||||
|
|
||||||
|
public class ProgressDialog extends JDialog implements ActionListener {
|
||||||
|
|
||||||
|
protected JProgressBar progressBar;
|
||||||
|
protected JTextArea statusArea;
|
||||||
|
protected JButton continueBtn;
|
||||||
|
|
||||||
|
protected boolean continueOnSuccess = false;
|
||||||
|
protected boolean done = false;
|
||||||
|
protected boolean succeeded = false;
|
||||||
|
protected Runnable successTask = null;
|
||||||
|
|
||||||
|
|
||||||
|
public ProgressDialog( Frame owner, boolean continueOnSuccess ) {
|
||||||
|
super( owner, true );
|
||||||
|
this.setDefaultCloseOperation( JDialog.DO_NOTHING_ON_CLOSE );
|
||||||
|
|
||||||
|
this.continueOnSuccess = continueOnSuccess;
|
||||||
|
|
||||||
|
progressBar = new JProgressBar();
|
||||||
|
progressBar.setBorderPainted( true );
|
||||||
|
|
||||||
|
JPanel progressHolder = new JPanel( new BorderLayout() );
|
||||||
|
progressHolder.setBorder( BorderFactory.createEmptyBorder( 10, 15, 0, 15 ) );
|
||||||
|
progressHolder.add( progressBar );
|
||||||
|
getContentPane().add( progressHolder, BorderLayout.NORTH );
|
||||||
|
|
||||||
|
statusArea = new JTextArea();
|
||||||
|
statusArea.setBorder( BorderFactory.createEtchedBorder() );
|
||||||
|
statusArea.setLineWrap( true );
|
||||||
|
statusArea.setWrapStyleWord( true );
|
||||||
|
statusArea.setEditable( false );
|
||||||
|
|
||||||
|
JPanel statusHolder = new JPanel( new BorderLayout() );
|
||||||
|
statusHolder.setBorder( BorderFactory.createEmptyBorder( 15, 15, 15, 15 ) );
|
||||||
|
statusHolder.add( statusArea );
|
||||||
|
getContentPane().add( statusHolder, BorderLayout.CENTER );
|
||||||
|
|
||||||
|
continueBtn = new JButton( "Continue" );
|
||||||
|
continueBtn.setEnabled( false );
|
||||||
|
continueBtn.addActionListener( this );
|
||||||
|
|
||||||
|
JPanel continueHolder = new JPanel();
|
||||||
|
continueHolder.setLayout( new BoxLayout( continueHolder, BoxLayout.X_AXIS ) );
|
||||||
|
continueHolder.setBorder( BorderFactory.createEmptyBorder( 0, 0, 10, 0 ) );
|
||||||
|
continueHolder.add( Box.createHorizontalGlue() );
|
||||||
|
continueHolder.add( continueBtn );
|
||||||
|
continueHolder.add( Box.createHorizontalGlue() );
|
||||||
|
getContentPane().add( continueHolder, BorderLayout.SOUTH );
|
||||||
|
|
||||||
|
this.setSize( 400, 160 );
|
||||||
|
this.setMinimumSize( this.getPreferredSize() );
|
||||||
|
this.setLocationRelativeTo( owner );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed( ActionEvent e ) {
|
||||||
|
Object source = e.getSource();
|
||||||
|
|
||||||
|
if ( source == continueBtn ) {
|
||||||
|
this.setVisible( false );
|
||||||
|
this.dispose();
|
||||||
|
|
||||||
|
if ( done && succeeded && successTask != null ) {
|
||||||
|
successTask.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the text area's content. (Thread-safe)
|
||||||
|
*
|
||||||
|
* @param message a string, or null
|
||||||
|
*/
|
||||||
|
public void setStatusTextLater( final String message ) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
setStatusText( message != null ? message : "..." );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setStatusText( String message ) {
|
||||||
|
statusArea.setText( message != null ? message : "..." );
|
||||||
|
statusArea.setCaretPosition( 0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the progress bar. (Thread-safe)
|
||||||
|
*
|
||||||
|
* If the arg is -1, the bar will become indeterminate.
|
||||||
|
*
|
||||||
|
* @param value the new value
|
||||||
|
*/
|
||||||
|
public void setProgressLater( final int value ) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if ( value >= 0 ) {
|
||||||
|
if ( progressBar.isIndeterminate() )
|
||||||
|
progressBar.setIndeterminate( false );
|
||||||
|
|
||||||
|
progressBar.setValue( value );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( !progressBar.isIndeterminate() )
|
||||||
|
progressBar.setIndeterminate( true );
|
||||||
|
progressBar.setValue( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the progress bar. (Thread-safe)
|
||||||
|
*
|
||||||
|
* If either arg is -1, the bar will become indeterminate.
|
||||||
|
*
|
||||||
|
* @param value the new value
|
||||||
|
* @param max the new maximum
|
||||||
|
*/
|
||||||
|
public void setProgressLater( final int value, final int max ) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
if ( value >= 0 && max >= 0 ) {
|
||||||
|
if ( progressBar.isIndeterminate() )
|
||||||
|
progressBar.setIndeterminate( false );
|
||||||
|
|
||||||
|
if ( progressBar.getMaximum() != max ) {
|
||||||
|
progressBar.setValue( 0 );
|
||||||
|
progressBar.setMaximum( max );
|
||||||
|
}
|
||||||
|
progressBar.setValue( value );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if ( !progressBar.isIndeterminate() )
|
||||||
|
progressBar.setIndeterminate( true );
|
||||||
|
progressBar.setValue( 0 );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Triggers a responce to the immediate task ending. (Thread-safe)
|
||||||
|
*
|
||||||
|
* If anything went wrong, e may be non-null.
|
||||||
|
*/
|
||||||
|
public void setTaskOutcomeLater( final boolean success, final Exception e ) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
setTaskOutcome( success, e );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void setTaskOutcome( final boolean outcome, final Exception e ) {
|
||||||
|
done = true;
|
||||||
|
succeeded = outcome;
|
||||||
|
|
||||||
|
if ( !ProgressDialog.this.isShowing() ) {
|
||||||
|
// The window's not visible, no continueBtn to click.
|
||||||
|
ProgressDialog.this.dispose();
|
||||||
|
|
||||||
|
if ( succeeded && successTask != null ) {
|
||||||
|
successTask.run();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( continueOnSuccess && succeeded && successTask != null ) {
|
||||||
|
ProgressDialog.this.setVisible( false );
|
||||||
|
ProgressDialog.this.dispose();
|
||||||
|
successTask.run();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
continueBtn.setEnabled( true );
|
||||||
|
continueBtn.requestFocusInWindow();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets a runnable to trigger after the immediate task ends successfully.
|
||||||
|
*/
|
||||||
|
public void setSuccessTask( Runnable r ) {
|
||||||
|
successTask = r;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows or hides this component depending on the value of parameter b.
|
||||||
|
*
|
||||||
|
* If the immediate task has already completed,
|
||||||
|
* this method will do nothing.
|
||||||
|
*/
|
||||||
|
public void setVisible( boolean b ) {
|
||||||
|
if ( !done ) super.setVisible( b );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Add table
Add a link
Reference in a new issue