Reputation: 521
I have tried to add progress bar in status line of the window, where there are already many text items on status line (for e.g. current time). I want to make progress in progressbar while loading data to one of the frame (called data) of the window. I have few problems regarding this. (I am quite new to SWT, so kindly bear with me.)
in makeProgress method I try to make progress in progress bar. Following is my code
public class Progress extends ContributionItem {
private static org.eclipse.swt.widgets.ProgressBar progressBar;
public Progress(final String id) {
super(id);
}
@Override
public void fill(final Composite parent) {
if (progressBar == null) {
progressBar = new ProgressBar(parent, SWT.None);
}
progressBar.setVisible(false);
}
public void makeProgress(final int loaded_data, final int total_data) {
logger.log("progressitem do progress", new String [] {""});
Display.getDefault().asyncExec(new Runnable() {
public void run() {
Progress.progressBar.setVisible(true);
Progress.progressBar.setMaximum(total_data);
Progress.progressBar.setSelection(loaded_data);
}});
if (loaded_data == total_data) {
//When all of the data are loaded, make progress bar disappear
Display.getDefault().asyncExec(new Runnable() {
public void run() {
Progress.progressBar.setVisible(false);
}});
}
}
}
where makeProgress called by a class which handles statusbar like following: change is a type of
if (change.getChange() == hasChanged.UPDATE_PROGRESS) {
progress.makeProgress(change.getLoaded_data(), change.getTotal_data);
Problems:
1) My progress bar is progressing very slow. May be proper use of threads required ?
2) Although I tried, I am not quite clear with the difference between Display.getDefault.asyncExec and syncExec.
3) Another issue is, when progress bar is progressing, The whole GUI is not responsive. How can I make progressbar independent of other views on the GUI ?
I would really appreciate any pointers or suggestions regarding this.
Upvotes: 0
Views: 8255
Reputation: 1
I use the following implementation to add a progress bar to the status line contribution item:
try {
/** launch the progress monitor that is reading the image file */
ModalContext.run( new IRunnableWithProgress( )
{
@Override
public void run(IProgressMonitor progressMonitor)
{
progressMonitor.beginTask( "Reading: " + filename, IProgressMonitor.UNKNOWN );
manager.read( filename );
progressMonitor.done( );
}
}, true, getStatusLineManager( ).getProgressMonitor( ), Display.getDefault( ) );
} catch (MyException e)
{
throw new Error("An error occurred updating the component.", e);
}
Upvotes: 0
Reputation: 183
I would like to answer for your questions
1) My progress bar is progressing very slow. May be proper use of threads required ? Yes you need to manage them .
2) Although I tried, I am not quite clear with the difference between Display.getDefault.asyncExec and syncExec. syncExec work one after another where asyncExec work parallel way
3) Another issue is, when progress bar is progressing, The whole GUI is not responsive. How can I make progressbar independent of other views on the GUI ?
Check following code, how to do this. fully functional
public static void main(String[] args) {
Display display = new Display();
Shell baseComposit = new Shell(display);
RowLayout layout = new RowLayout();
layout.type = SWT.VERTICAL;
baseComposit.setLayout(layout);
ProgressBar bar = new ProgressBar(baseComposit, SWT.None);
bar.setLayoutData(new RowData(1000, 25));
Text helloWorldTest = new Text(baseComposit, SWT.NONE);
helloWorldTest.setLayoutData(new RowData(500, 25));
helloWorldTest.pack();
Button button = new Button(baseComposit, SWT.NONE);
button.setText("START");
button.setLayoutData(new RowData(50, 40));
button.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
bar.setMaximum(10000);
for (int i = 1; i < 10000; i++) {
int count = i;
bar.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
bar.setSelection(count);
try {
Thread.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
helloWorldTest.getDisplay().asyncExec(new Runnable() {
@Override
public void run() {
helloWorldTest.setText(Integer.toString(count));
}
});
}
}
});
Button clear = new Button(baseComposit, SWT.VERTICAL);
clear.setText("CLEAR");
clear.setLayoutData(new RowData(50, 40));
clear.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
bar.setSelection(0);
helloWorldTest.setText("");
}
});
baseComposit.open();
while (!baseComposit.isDisposed()) {
if (!display.readAndDispatch())
display.sleep();
}
display.dispose();
}
Upvotes: 0
Reputation: 1
I wanted to post this example of adding a progress bar to an existing composite. All of the examples I see start with a new shell and main function.
public class MainScaleComposite extends Composite {
public boolean calStarted=false;
public boolean calFinished=false;
public MainScaleComposite(Shell parent, int style) {
super(parent,style);
log = Logger.getLogger(MainScaleComposite.class.getName()); // get the logger for this class
private void startCalThread(){
final StringBuffer sb = new StringBuffer("");
if (calStarted==false){
new Thread(new Runnable()
{
@Override
public void run()
{
try
{
calStarted=true;
append(sb,service.ExecuteCommand.executeProcess("<<your program here>>",0,null));
calFinished=true;
}
catch (InterruptedException e)
{
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}).start();
}
}
private void StartTimer(){
final Display display = this.getDisplay();
final ProgressBar bar = new ProgressBar (this, SWT.SMOOTH);
bar.setBounds (300, 170, 200, 32);
display.timerExec(100, new Runnable() {
int i = 0;
@Override
public void run() {
if (bar.isDisposed()) return;
bar.setSelection(i++);
if (i < bar.getMaximum()) display.timerExec(100, this);
}
});
startCalThread();
while (!calFinished) {
if (!display.readAndDispatch ()) display.sleep ();
}
}
Upvotes: 0
Reputation: 36894
Ok, here is a simple example with a ProgressBar
that's updated continuously from another thread. The GUI is still responsive throughout:
private static Shell shell;
private static ProgressBar progressBar;
public static void main(String[] args)
{
Display display = new Display();
shell = new Shell(SWT.SHELL_TRIM);
shell.setText("StackOverflow");
shell.setLayout(new GridLayout(1, false));
setUpContent();
setUpStatusBar();
updateProgressBar();
shell.pack();
shell.setSize(400, 200);
shell.open();
while (!shell.isDisposed())
{
if (!display.readAndDispatch())
{
display.sleep();
}
}
display.dispose();
}
private static void updateProgressBar()
{
new Thread(new Runnable()
{
private int progress = 0;
private static final int INCREMENT = 10;
@Override
public void run()
{
while (!progressBar.isDisposed())
{
Display.getDefault().asyncExec(new Runnable()
{
@Override
public void run()
{
if (!progressBar.isDisposed())
progressBar.setSelection((progress += INCREMENT) % (progressBar.getMaximum() + INCREMENT));
}
});
try
{
Thread.sleep(1000);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
}
}
}).start();
}
private static void setUpStatusBar()
{
Composite statusBar = new Composite(shell, SWT.BORDER);
statusBar.setLayout(new GridLayout(2, false));
statusBar.setLayoutData(new GridData(SWT.FILL, SWT.END, true, false));
progressBar = new ProgressBar(statusBar, SWT.SMOOTH);
progressBar.setLayoutData(new GridData(SWT.BEGINNING, SWT.CENTER, true, false));
progressBar.setMaximum(100);
Label status = new Label(statusBar, SWT.NONE);
status.setText("Some status message");
status.setLayoutData(new GridData(SWT.END, SWT.CENTER, true, false));
}
private static void setUpContent()
{
Composite content = new Composite(shell, SWT.NONE);
content.setLayout(new GridLayout(2, false));
content.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
Text text = new Text(content, SWT.BORDER | SWT.MULTI);
text.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true));
}
My guess why your application freezes and the progress isn't updated smoothly is that it's doing heavy computational / long running tasks on the main thread instead of a separate thread.
Upvotes: 3