/*
* Copyright 2010-2015 Institut Pasteur.
*
* This file is part of Icy.
*
* Icy is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Icy is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with Icy. If not, see <http://www.gnu.org/licenses/>.
*/
package icy.gui.frame.progress;
import icy.common.listener.ProgressListener;
import icy.system.thread.ThreadUtil;
import icy.util.StringUtil;
import java.awt.BorderLayout;
import javax.swing.BorderFactory;
import javax.swing.JProgressBar;
/**
* A progress TaskFrame (thread safe)
*
* @author fab & stephane
*/
public class ProgressFrame extends TaskFrame implements ProgressListener, Runnable
{
/**
* gui
*/
JProgressBar progressBar;
/**
* length (in bytes) of download
*/
protected double length;
/**
* current position (in bytes) of download
*/
protected double position;
/**
* current message
*/
protected String message;
/**
* current tooltip
*/
protected String tooltip;
/**
* internals
*/
// private final SingleProcessor processor;
public ProgressFrame(final String message)
{
super("");
// default
length = 100d;
position = -1d;
// processor = new SingleProcessor(true);
this.message = message;
ThreadUtil.invokeLater(new Runnable()
{
@Override
public void run()
{
progressBar = new JProgressBar();
progressBar.setString(buildMessage(message));
progressBar.setStringPainted(true);
progressBar.setIndeterminate(true);
progressBar.setBorder(BorderFactory.createEmptyBorder());
progressBar.setMinimum(0);
// this is enough for a smooth progress
progressBar.setMaximum(1000);
mainPanel.setLayout(new BorderLayout());
mainPanel.add(progressBar, BorderLayout.CENTER);
pack();
}
});
}
protected String buildMessage(String message)
{
return " " + message + " ";
}
@Override
public void run()
{
// don't spent too much time in EDT
ThreadUtil.sleep(10);
updateDisplay();
}
public void refresh()
{
// refresh (need single delayed execution)
ThreadUtil.runSingle(this);
}
protected void updateDisplay()
{
// repacking need to be done on EDT
ThreadUtil.invokeNow(new Runnable()
{
@Override
public void run()
{
// position information
if ((position != -1d) && (length > 0d))
{
// remove indeterminate state
if (progressBar.isIndeterminate())
progressBar.setIndeterminate(false);
// set progress
final int value = (int) (position * 1000d / length);
if (progressBar.getValue() != value)
progressBar.setValue(value);
}
else
{
// set indeterminate state
if (!progressBar.isIndeterminate())
progressBar.setIndeterminate(true);
}
final String text = buildMessage(message);
// set progress message
if (!StringUtil.equals(progressBar.getString(), text))
{
progressBar.setString(text);
// so component is resized according to its string length
progressBar.invalidate();
// repack frame
pack();
}
// set tooltip
if (!StringUtil.equals(progressBar.getToolTipText(), tooltip))
progressBar.setToolTipText(tooltip);
}
});
}
public String getMessage()
{
return message;
}
public void setMessage(String value)
{
if (message != value)
{
message = value;
refresh();
}
}
// we want tooltip set on the progress component only
@Override
public void setToolTipText(String value)
{
if (tooltip != value)
{
tooltip = value;
refresh();
}
}
/**
* @return the length
*/
public double getLength()
{
return length;
}
/**
* @param value
* the length to set
*/
public void setLength(double value)
{
if (length != value)
{
length = value;
refresh();
}
}
/**
* @return the position
*/
public double getPosition()
{
return position;
}
/**
* increment progress position
*/
public void incPosition()
{
setPosition(position + 1);
}
/**
* @param value
* the position to set
*/
public void setPosition(double value)
{
if (position != value)
{
position = value;
refresh();
}
}
/**
* @deprecated use {@link #setPosition(double)} instead
*/
@Deprecated
public void setProgress(int value)
{
setPosition(value);
}
@Override
public boolean notifyProgress(double position, double length)
{
setPosition(position);
setLength(length);
return true;
}
}