001 // License: GPL. Copyright 2007 by Immanuel Scholz and others 002 package org.openstreetmap.josm.gui; 003 004 import static org.openstreetmap.josm.tools.I18n.tr; 005 006 import java.awt.Component; 007 import java.awt.GridBagConstraints; 008 import java.awt.GridBagLayout; 009 import java.awt.event.ActionListener; 010 import java.awt.event.ComponentEvent; 011 import java.awt.event.ComponentListener; 012 013 import javax.swing.BorderFactory; 014 import javax.swing.BoundedRangeModel; 015 import javax.swing.JButton; 016 import javax.swing.JDialog; 017 import javax.swing.JLabel; 018 import javax.swing.JOptionPane; 019 import javax.swing.JPanel; 020 import javax.swing.JProgressBar; 021 import javax.swing.JScrollPane; 022 import javax.swing.JTextArea; 023 import javax.swing.UIManager; 024 025 import org.openstreetmap.josm.Main; 026 import org.openstreetmap.josm.gui.progress.PleaseWaitProgressMonitor.ProgressMonitorDialog; 027 import org.openstreetmap.josm.tools.GBC; 028 import org.openstreetmap.josm.tools.ImageProvider; 029 030 public class PleaseWaitDialog extends JDialog implements ProgressMonitorDialog { 031 032 private final JProgressBar progressBar = new JProgressBar(); 033 034 public final JLabel currentAction = new JLabel(""); 035 private final JLabel customText = new JLabel(""); 036 public final BoundedRangeModel progress = progressBar.getModel(); 037 private JButton btnCancel; 038 private JButton btnInBackground; 039 /** the text area and the scroll pane for the log */ 040 private JTextArea taLog = new JTextArea(5,50); 041 private JScrollPane spLog; 042 043 private void initDialog() { 044 setLayout(new GridBagLayout()); 045 JPanel pane = new JPanel(new GridBagLayout()); 046 pane.setBorder(BorderFactory.createEmptyBorder(10,10,10,10)); 047 pane.add(currentAction, GBC.eol().fill(GBC.HORIZONTAL)); 048 pane.add(customText, GBC.eol().fill(GBC.HORIZONTAL)); 049 pane.add(progressBar, GBC.eop().fill(GBC.HORIZONTAL)); 050 JPanel buttons = new JPanel(); 051 buttons.setLayout(new GridBagLayout()); 052 btnCancel = new JButton(tr("Cancel")); 053 btnCancel.setIcon(ImageProvider.get("cancel")); 054 btnCancel.setToolTipText(tr("Click to cancel the current operation")); 055 buttons.add(btnCancel); 056 btnInBackground = new JButton(tr("In background")); 057 btnInBackground.setToolTipText(tr("Click to run job in background")); 058 buttons.add(btnInBackground, GBC.std().fill(GBC.VERTICAL).insets(5, 0, 0, 0)); 059 pane.add(buttons, GBC.eol().anchor(GBC.CENTER)); 060 GridBagConstraints gc = GBC.eol().fill(GBC.BOTH); 061 gc.weighty = 1.0; 062 gc.weightx = 1.0; 063 pane.add(spLog = new JScrollPane(taLog), gc); 064 spLog.setVisible(false); 065 setContentPane(pane); 066 setCustomText(""); 067 setLocationRelativeTo(getParent()); 068 addComponentListener(new ComponentListener() { 069 public void componentHidden(ComponentEvent e) {} 070 public void componentMoved(ComponentEvent e) {} 071 public void componentShown(ComponentEvent e) {} 072 public void componentResized(ComponentEvent ev) { 073 int w = getWidth(); 074 if(w > 200) { 075 Main.pref.putInteger("progressdialog.size",w); 076 } 077 } 078 }); 079 } 080 081 public PleaseWaitDialog(Component parent) { 082 super(JOptionPane.getFrameForComponent(parent), ModalityType.DOCUMENT_MODAL); 083 initDialog(); 084 } 085 086 public void setIndeterminate(boolean newValue) { 087 UIManager.put("ProgressBar.cycleTime", UIManager.getInt("ProgressBar.repaintInterval") * 100); 088 progressBar.setIndeterminate(newValue); 089 } 090 091 protected void adjustLayout() { 092 invalidate(); 093 pack(); 094 setSize(Main.pref.getInteger("progressdialog.size", 600), getSize().height); 095 } 096 097 /** 098 * Sets a custom text line below currentAction. Can be used to display additional information 099 * @param text 100 */ 101 public void setCustomText(String text) { 102 if(text == null || text.trim().length() == 0) { 103 customText.setVisible(false); 104 adjustLayout(); 105 return; 106 } 107 customText.setText(text); 108 if (!customText.isVisible()) { 109 customText.setVisible(true); 110 adjustLayout(); 111 } 112 } 113 114 public void setCurrentAction(String text) { 115 currentAction.setText(text); 116 } 117 118 /** 119 * Appends a log message to the progress dialog. If the log area isn't visible yet 120 * it becomes visible. The height of the progress dialog is slightly increased too. 121 * 122 * @param message the message to append to the log. Ignore if null or white space only. 123 */ 124 public void appendLogMessage(String message) { 125 if (message == null || message.trim().length() ==0 ) 126 return; 127 if (!spLog.isVisible()) { 128 spLog.setVisible(true); 129 taLog.setVisible(true); 130 adjustLayout(); 131 } 132 taLog.append(message); 133 taLog.append("\n"); 134 spLog.getVerticalScrollBar().setValue(spLog.getVerticalScrollBar().getMaximum()); 135 } 136 137 /** 138 * Sets whether the cancel button is enabled or not 139 * 140 * @param enabled true, if the cancel button is enabled; false otherwise 141 */ 142 public void setCancelEnabled(boolean enabled) { 143 btnCancel.setEnabled(enabled); 144 } 145 146 public void setInBackgroundPossible(boolean value) { 147 btnInBackground.setVisible(value); 148 } 149 150 /** 151 * Installs a callback for the cancel button. If callback is null, all action listeners 152 * are removed from the cancel button. 153 * 154 * @param callback the cancel callback 155 */ 156 public void setCancelCallback(ActionListener callback) { 157 if (callback == null) { 158 ActionListener[] listeners = btnCancel.getActionListeners(); 159 for (ActionListener l: listeners) { 160 btnCancel.removeActionListener(l); 161 } 162 } else { 163 btnCancel.addActionListener(callback); 164 } 165 } 166 167 /** 168 * Installs a callback for the "In background" button. If callback is null, all action listeners 169 * are removed from the cancel button. 170 * 171 * @param callback the cancel callback 172 */ 173 public void setInBackgroundCallback(ActionListener callback) { 174 if (callback == null) { 175 ActionListener[] listeners = btnInBackground.getActionListeners(); 176 for (ActionListener l: listeners) { 177 btnInBackground.removeActionListener(l); 178 } 179 } else { 180 btnInBackground.addActionListener(callback); 181 } 182 } 183 184 @Override 185 public void updateProgress(int progress) { 186 this.progress.setValue(progress); 187 } 188 189 }