You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

SwingUpdaterDialog.java 8.6KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. /*
  2. * Copyright (c) 2006-2014 DMDirc Developers
  3. *
  4. * Permission is hereby granted, free of charge, to any person obtaining a copy
  5. * of this software and associated documentation files (the "Software"), to deal
  6. * in the Software without restriction, including without limitation the rights
  7. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. * copies of the Software, and to permit persons to whom the Software is
  9. * furnished to do so, subject to the following conditions:
  10. *
  11. * The above copyright notice and this permission notice shall be included in
  12. * all copies or substantial portions of the Software.
  13. *
  14. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  20. * SOFTWARE.
  21. */
  22. package com.dmdirc.addons.ui_swing.dialogs.updater;
  23. import com.dmdirc.DMDircMBassador;
  24. import com.dmdirc.addons.ui_swing.UIUtilities;
  25. import com.dmdirc.addons.ui_swing.components.LoggingSwingWorker;
  26. import com.dmdirc.addons.ui_swing.components.PackingTable;
  27. import com.dmdirc.addons.ui_swing.components.text.TextLabel;
  28. import com.dmdirc.addons.ui_swing.dialogs.StandardDialog;
  29. import com.dmdirc.addons.ui_swing.injection.DialogModule.ForUpdates;
  30. import com.dmdirc.addons.ui_swing.injection.DialogProvider;
  31. import com.dmdirc.addons.ui_swing.injection.MainWindow;
  32. import com.dmdirc.updater.UpdateComponent;
  33. import com.dmdirc.updater.manager.CachingUpdateManager;
  34. import com.dmdirc.updater.manager.UpdateManager;
  35. import com.dmdirc.updater.manager.UpdateManagerListener;
  36. import com.dmdirc.updater.manager.UpdateManagerStatus;
  37. import com.dmdirc.updater.manager.UpdateStatus;
  38. import java.awt.Dimension;
  39. import java.awt.Window;
  40. import java.awt.event.ActionEvent;
  41. import java.awt.event.ActionListener;
  42. import java.util.ArrayList;
  43. import java.util.List;
  44. import javax.inject.Inject;
  45. import javax.swing.JButton;
  46. import javax.swing.JScrollPane;
  47. import javax.swing.JTable;
  48. import javax.swing.ListSelectionModel;
  49. import javax.swing.WindowConstants;
  50. import javax.swing.table.TableCellRenderer;
  51. import net.miginfocom.swing.MigLayout;
  52. /**
  53. * The updater dialog informs the user of the new update that is available, and walks them through
  54. * the process of downloading the update.
  55. */
  56. public class SwingUpdaterDialog extends StandardDialog implements
  57. ActionListener, UpdateManagerListener {
  58. /** Serial version UID. */
  59. private static final long serialVersionUID = 3;
  60. /** The update manager to use. */
  61. private final CachingUpdateManager updateManager;
  62. /** Update table. */
  63. private JTable table;
  64. /** Table scrollpane. */
  65. private JScrollPane scrollPane;
  66. /** The label we use for the dialog header. */
  67. private TextLabel header;
  68. /** UpdateComponent renderer. */
  69. private UpdateComponentTableCellRenderer updateComponentRenderer;
  70. /** Update.Status renderer. */
  71. private UpdateStatusTableCellRenderer updateStatusRenderer;
  72. /** Provider of restart dialogs. */
  73. private final DialogProvider<SwingRestartDialog> restartDialogProvider;
  74. /** The event bus to post errors to. */
  75. private final DMDircMBassador eventBus;
  76. /**
  77. * Creates a new instance of the updater dialog.
  78. *
  79. * @param updateManager The update manager to use for information
  80. * @param parentWindow Parent window
  81. * @param restartDialogProvider Provider of restart dialogs.
  82. * @param eventBus The event bus to post errors to
  83. */
  84. @Inject
  85. public SwingUpdaterDialog(
  86. final CachingUpdateManager updateManager,
  87. @MainWindow final Window parentWindow,
  88. @ForUpdates final DialogProvider<SwingRestartDialog> restartDialogProvider,
  89. final DMDircMBassador eventBus) {
  90. super(parentWindow, ModalityType.MODELESS);
  91. this.updateManager = updateManager;
  92. this.restartDialogProvider = restartDialogProvider;
  93. this.eventBus = eventBus;
  94. initComponents();
  95. layoutComponents();
  96. updateManager.addUpdateManagerListener(this);
  97. getOkButton().addActionListener(this);
  98. getCancelButton().addActionListener(this);
  99. setTitle("Update available");
  100. setSize(new Dimension(450, 400));
  101. }
  102. /**
  103. * Initialises the components.
  104. */
  105. private void initComponents() {
  106. setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
  107. updateStatusRenderer = new UpdateStatusTableCellRenderer();
  108. updateComponentRenderer = new UpdateComponentTableCellRenderer();
  109. header = new TextLabel("An update is available for one or more "
  110. + "components of DMDirc:");
  111. final List<UpdateComponent> updates = new ArrayList<>();
  112. for (UpdateComponent component : updateManager.getComponents()) {
  113. if (updateManager.getStatus(component) != UpdateStatus.IDLE
  114. && updateManager.getStatus(component) != UpdateStatus.CHECKING_NOT_PERMITTED) {
  115. updates.add(component);
  116. }
  117. }
  118. scrollPane = new JScrollPane();
  119. table = new PackingTable(new UpdateTableModel(updateManager, updates), scrollPane) {
  120. /** Serialisation version ID. */
  121. private static final long serialVersionUID = 1;
  122. @Override
  123. public TableCellRenderer getCellRenderer(final int row,
  124. final int column) {
  125. switch (column) {
  126. case 1:
  127. return updateComponentRenderer;
  128. case 3:
  129. return updateStatusRenderer;
  130. default:
  131. return super.getCellRenderer(row, column);
  132. }
  133. }
  134. };
  135. table.setAutoCreateRowSorter(true);
  136. table.setAutoCreateColumnsFromModel(true);
  137. table.setColumnSelectionAllowed(false);
  138. table.setCellSelectionEnabled(false);
  139. table.setFillsViewportHeight(false);
  140. table.setRowSelectionAllowed(true);
  141. table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
  142. table.getRowSorter().toggleSortOrder(0);
  143. scrollPane.setViewportView(table);
  144. orderButtons(new JButton(), new JButton());
  145. }
  146. /**
  147. * Lays out the components.
  148. */
  149. private void layoutComponents() {
  150. setLayout(new MigLayout("fill, wmin 450, hmin 400, wmax 450, hmax 400, "
  151. + "hidemode 3"));
  152. add(header, "wrap 1.5*unrel, growx, pushx");
  153. add(scrollPane, "grow, push, wrap");
  154. add(getLeftButton(), "split 2, right");
  155. add(getRightButton(), "right");
  156. }
  157. @Override
  158. public void actionPerformed(final ActionEvent e) {
  159. if (e.getSource().equals(getOkButton())) {
  160. getOkButton().setEnabled(false);
  161. getCancelButton().setVisible(false);
  162. header.setText("DMDirc is updating the following components:");
  163. new LoggingSwingWorker<Void, Void>(eventBus) {
  164. @Override
  165. protected Void doInBackground() {
  166. for (UpdateComponent update : ((UpdateTableModel) table.getModel()).getUpdates()) {
  167. if (((UpdateTableModel) table.getModel()).isEnabled(update)) {
  168. updateManager.install(update);
  169. }
  170. }
  171. return null;
  172. }
  173. }.execute();
  174. if (updateManager.getManagerStatus() == UpdateManagerStatus.IDLE_RESTART_NEEDED) {
  175. restartDialogProvider.displayOrRequestFocus();
  176. dispose();
  177. }
  178. } else if (e.getSource().equals(getCancelButton())) {
  179. dispose();
  180. }
  181. }
  182. @Override
  183. public boolean enterPressed() {
  184. executeAction(getOkButton());
  185. return true;
  186. }
  187. @Override
  188. public void updateManagerStatusChanged(final UpdateManager manager,
  189. final UpdateManagerStatus status) {
  190. UIUtilities.invokeLater(() -> {
  191. getOkButton().setEnabled(status != UpdateManagerStatus.WORKING);
  192. if (status == UpdateManagerStatus.IDLE_RESTART_NEEDED) {
  193. if (isVisible()) {
  194. restartDialogProvider.displayOrRequestFocus();
  195. }
  196. dispose();
  197. } else {
  198. getCancelButton().setVisible(true);
  199. }
  200. });
  201. }
  202. }