package com.kartoflane.common.selfpatch;
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
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.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.SwingUtilities;
/**
* Appropriated from Slipstream Mod Manager's ProgressDialog
*/
@SuppressWarnings("serial")
class SPSwingDownloadDialog extends JDialog implements SPDownloadWindow, ActionListener {
private final JScrollPane statusScroll;
private final JProgressBar progressBar;
private final JTextArea statusArea;
private final JButton continueBtn;
private Thread taskThread = null;
private boolean done = false;
private boolean succeeded = false;
public SPSwingDownloadDialog() {
super( null, "Downloading...", ModalityType.APPLICATION_MODAL );
setDefaultCloseOperation( DISPOSE_ON_CLOSE );
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.setLineWrap( true );
statusArea.setWrapStyleWord( true );
statusArea.setFont( statusArea.getFont().deriveFont( 13f ) );
statusArea.setEditable( false );
statusScroll = new JScrollPane( statusArea );
JPanel statusHolder = new JPanel( new BorderLayout() );
statusHolder.setBorder( BorderFactory.createEmptyBorder( 15, 15, 15, 15 ) );
statusHolder.add( statusScroll );
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 );
setSize( 400, 160 );
this.setMinimumSize( this.getPreferredSize() );
this.setLocationRelativeTo( null );
setResizable( false );
}
@Override
public void actionPerformed( ActionEvent e ) {
Object source = e.getSource();
if ( source == continueBtn ) {
this.setVisible( false );
this.dispose();
}
}
/**
* 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 response 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 ( !this.isShowing() ) {
// The window's not visible, no continueBtn to click.
this.dispose();
}
continueBtn.setEnabled( true );
continueBtn.requestFocusInWindow();
}
@Override
public void taskProgress( int value, int max ) {
this.setProgressLater( value, max );
}
@Override
public void taskStatus( String message ) {
setStatusTextLater( message != null ? message : "..." );
}
@Override
public void taskFinished( boolean outcome, Exception e ) {
setTaskOutcomeLater( outcome, e );
}
@Override
public void dispose() {
if ( !done ) {
if ( taskThread != null ) {
taskThread.interrupt();
}
setProgressLater( 0, 100 );
setStatusTextLater( "Aborted by user." );
setTaskOutcomeLater( false, null );
}
else {
super.dispose();
}
}
@Override
public void spShow() {
setVisible( true );
}
@Override
public void setTaskThread( Thread thread ) {
taskThread = thread;
}
}