package org.basex.gui.dialog; import org.basex.core.Command; import static org.basex.core.Text.*; import org.basex.gui.GUI; import org.basex.gui.layout.*; import org.basex.util.Performance; import org.basex.util.Util; import javax.swing.*; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; /** * Dialog window for displaying the progress of a command execution. * * @author BaseX Team 2005-12, BSD License * @author Christian Gruen */ public final class DialogProgress extends Dialog implements ActionListener { /** Maximum value of progress bar. */ private static final int MAX = 600; /** Refresh action. */ private final Timer timer = new Timer(100, this); /** Information label. */ private final BaseXLabel info; /** Memory usage. */ private final BaseXMem mem; /** Executed command. */ private final Command command; /** Progress bar. */ private final JProgressBar bar; /** * Default constructor. * @param main main window * @param title dialog title * @param cmd progress reference */ DialogProgress(final GUI main, final String title, final Command cmd) { super(main, title, false); info = new BaseXLabel(" ", true, true); set(info, BorderLayout.NORTH); if(cmd.supportsProg()) { bar = new JProgressBar(0, MAX); set(bar, BorderLayout.CENTER); } else { bar = null; } BaseXLayout.setWidth(info, MAX); final BaseXBack s = new BaseXBack(new BorderLayout()).border(10, 0, 0, 0); final BaseXBack m = new BaseXBack(new TableLayout(1, 2, 5, 0)); mem = new BaseXMem(this, false); m.add(new BaseXLabel(MEMUSED_C)); m.add(mem); s.add(m, BorderLayout.WEST); if(cmd.stoppable()) { final BaseXButton cancel = new BaseXButton(B_CANCEL, this); s.add(cancel, BorderLayout.EAST); } set(s, BorderLayout.SOUTH); command = cmd; timer.start(); finish(null); } @Override public void cancel() { command.stop(); close(); } @Override public void close() { dispose(); } @Override public void dispose() { timer.stop(); super.dispose(); } @Override public void actionPerformed(final ActionEvent e) { setTitle(command.title()); final String detail = command.detail(); info.setText(detail.isEmpty() ? " " : detail); mem.repaint(); if(bar != null) bar.setValue((int) (command.progress() * MAX)); } /** * Runs the specified commands, decorated by a progress dialog, and * calls {@link Dialog#action} if the dialog is closed. * @param d reference to the dialog window * @param t dialog title (may be an empty string) * @param cmds commands to be run */ public static void execute(final Dialog d, final String t, final Command... cmds) { execute(d, t, null, cmds); } /** * Runs the specified commands, decorated by a progress dialog, and * calls {@link Dialog#action} if the dialog is closed. * @param d reference to the dialog window * @param t dialog title (may be an empty string) * @param post post-processing step * @param cmds commands to be run */ public static void execute(final Dialog d, final String t, final Runnable post, final Command... cmds) { // start database creation thread new Thread() { @Override public void run() { d.setEnabled(false); final GUI gui = d.gui; for(final Command cmd : cmds) { // reset views final boolean newData = cmd.newData(gui.context); if(newData) gui.notify.init(); // open wait dialog final DialogProgress wait = new DialogProgress(gui, t, cmd); wait.setAlwaysOnTop(true); // execute command final Performance perf = new Performance(); gui.updating = cmd.updating(gui.context); final boolean ok = cmd.run(gui.context); gui.updating = false; final String info = cmd.info(); // return status information final String time = perf.toString(); gui.info.setInfo(info, cmd, time, ok); gui.info.reset(); gui.status.setText(Util.info(TIME_NEEDED_X, time)); // close progress window and show error if command failed wait.dispose(); if(!ok) Dialog.error(gui, info.equals(INTERRUPTED) ? CREATION_CANCELED : info); // initialize views if database was closed before if(newData) gui.notify.init(); else if(cmd.updating(gui.context)) gui.notify.update(); } d.setEnabled(true); d.action(d); if(post != null) post.run(); } }.start(); } }