[283] | 1 | package org.openstreetmap.josm.gui;
|
---|
| 2 |
|
---|
| 3 | import static org.openstreetmap.josm.tools.I18n.tr;
|
---|
| 4 |
|
---|
| 5 | import java.awt.EventQueue;
|
---|
| 6 | import java.awt.event.ActionEvent;
|
---|
| 7 | import java.awt.event.ActionListener;
|
---|
| 8 | import java.awt.event.WindowAdapter;
|
---|
| 9 | import java.awt.event.WindowEvent;
|
---|
| 10 | import java.io.FileNotFoundException;
|
---|
| 11 | import java.io.IOException;
|
---|
| 12 | import java.lang.reflect.InvocationTargetException;
|
---|
| 13 |
|
---|
| 14 | import javax.swing.JOptionPane;
|
---|
| 15 |
|
---|
| 16 | import org.openstreetmap.josm.Main;
|
---|
| 17 | import org.xml.sax.SAXException;
|
---|
| 18 |
|
---|
| 19 | /**
|
---|
| 20 | * Instanced of this thread will display a "Please Wait" message in middle of JOSM
|
---|
| 21 | * to indicate a progress beeing executed.
|
---|
| 22 | *
|
---|
| 23 | * @author Imi
|
---|
| 24 | */
|
---|
| 25 | public abstract class PleaseWaitRunnable implements Runnable {
|
---|
| 26 |
|
---|
| 27 | public String errorMessage;
|
---|
| 28 |
|
---|
| 29 | private boolean closeDialogCalled = false;
|
---|
| 30 | private boolean cancelled = false;
|
---|
| 31 |
|
---|
| 32 | private final String title;
|
---|
| 33 |
|
---|
| 34 | /**
|
---|
| 35 | * Create the runnable object with a given message for the user.
|
---|
| 36 | */
|
---|
| 37 | public PleaseWaitRunnable(String title) {
|
---|
| 38 | this.title = title;
|
---|
| 39 | Main.pleaseWaitDlg.cancel.addActionListener(new ActionListener(){
|
---|
| 40 | public void actionPerformed(ActionEvent e) {
|
---|
| 41 | if (!cancelled) {
|
---|
| 42 | cancelled = true;
|
---|
| 43 | cancel();
|
---|
| 44 | }
|
---|
| 45 | }
|
---|
| 46 | });
|
---|
| 47 | Main.pleaseWaitDlg.addWindowListener(new WindowAdapter(){
|
---|
| 48 | @Override public void windowClosing(WindowEvent e) {
|
---|
| 49 | if (!closeDialogCalled) {
|
---|
| 50 | if (!cancelled) {
|
---|
| 51 | cancelled = true;
|
---|
| 52 | cancel();
|
---|
| 53 | }
|
---|
| 54 | closeDialog();
|
---|
| 55 | }
|
---|
| 56 | }
|
---|
| 57 | });
|
---|
| 58 | }
|
---|
| 59 |
|
---|
| 60 | public final void run() {
|
---|
| 61 | try {
|
---|
| 62 | if (cancelled)
|
---|
| 63 | return; // since realRun isn't executed, do not call to finish
|
---|
| 64 |
|
---|
| 65 | // reset dialog state
|
---|
| 66 | Main.pleaseWaitDlg.setTitle(title);
|
---|
| 67 | errorMessage = null;
|
---|
| 68 | closeDialogCalled = false;
|
---|
| 69 |
|
---|
| 70 | // show the dialog
|
---|
| 71 | synchronized (this) {
|
---|
| 72 | EventQueue.invokeLater(new Runnable() {
|
---|
| 73 | public void run() {
|
---|
| 74 | synchronized (PleaseWaitRunnable.this) {
|
---|
| 75 | PleaseWaitRunnable.this.notifyAll();
|
---|
| 76 | }
|
---|
| 77 | Main.pleaseWaitDlg.setVisible(true);
|
---|
| 78 | }
|
---|
| 79 | });
|
---|
| 80 | try {wait();} catch (InterruptedException e) {}
|
---|
| 81 | }
|
---|
| 82 |
|
---|
| 83 | realRun();
|
---|
| 84 | } catch (SAXException x) {
|
---|
| 85 | x.printStackTrace();
|
---|
| 86 | errorMessage = tr("Error while parsing")+": "+x.getMessage();
|
---|
| 87 | } catch (FileNotFoundException x) {
|
---|
| 88 | x.printStackTrace();
|
---|
| 89 | errorMessage = tr("File not found")+": "+x.getMessage();
|
---|
| 90 | } catch (IOException x) {
|
---|
| 91 | x.printStackTrace();
|
---|
| 92 | errorMessage = x.getMessage();
|
---|
| 93 | } finally {
|
---|
| 94 | closeDialog();
|
---|
| 95 | }
|
---|
| 96 | }
|
---|
| 97 |
|
---|
| 98 | /**
|
---|
| 99 | * User pressed cancel button.
|
---|
| 100 | */
|
---|
| 101 | protected abstract void cancel();
|
---|
| 102 |
|
---|
| 103 | /**
|
---|
| 104 | * Called in the worker thread to do the actual work. When any of the
|
---|
| 105 | * exception is thrown, a message box will be displayed and closeDialog
|
---|
| 106 | * is called. finish() is called in any case.
|
---|
| 107 | */
|
---|
| 108 | protected abstract void realRun() throws SAXException, IOException;
|
---|
| 109 |
|
---|
| 110 | /**
|
---|
| 111 | * Finish up the data work. Is guaranteed to be called if realRun is called.
|
---|
| 112 | * Finish is called in the gui thread just after the dialog disappeared.
|
---|
| 113 | */
|
---|
| 114 | protected abstract void finish();
|
---|
| 115 |
|
---|
| 116 | /**
|
---|
| 117 | * Close the dialog. Usually called from worker thread.
|
---|
| 118 | */
|
---|
| 119 | public void closeDialog() {
|
---|
| 120 | if (closeDialogCalled)
|
---|
| 121 | return;
|
---|
| 122 | closeDialogCalled = true;
|
---|
| 123 | try {
|
---|
| 124 | Runnable runnable = new Runnable(){
|
---|
| 125 | public void run() {
|
---|
| 126 | try {
|
---|
| 127 | finish();
|
---|
| 128 | } finally {
|
---|
| 129 | Main.pleaseWaitDlg.setVisible(false);
|
---|
| 130 | Main.pleaseWaitDlg.dispose();
|
---|
| 131 | }
|
---|
| 132 | if (errorMessage != null)
|
---|
| 133 | JOptionPane.showMessageDialog(Main.parent, errorMessage);
|
---|
| 134 | }
|
---|
| 135 | };
|
---|
| 136 |
|
---|
| 137 | // make sure, this is called in the dispatcher thread ASAP
|
---|
| 138 | if (EventQueue.isDispatchThread())
|
---|
| 139 | runnable.run();
|
---|
| 140 | else
|
---|
| 141 | EventQueue.invokeAndWait(runnable);
|
---|
| 142 |
|
---|
| 143 | } catch (InterruptedException e) {
|
---|
| 144 | } catch (InvocationTargetException e) {
|
---|
| 145 | throw new RuntimeException(e);
|
---|
| 146 | }
|
---|
| 147 | }
|
---|
| 148 | }
|
---|