1/* 2 * Copyright (C) 2015 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17package com.android.preload.ui; 18 19import com.android.ddmlib.Client; 20import com.android.ddmlib.ClientData; 21 22import java.awt.BorderLayout; 23import java.awt.Component; 24import java.awt.Dimension; 25import java.io.File; 26import java.util.List; 27 28import javax.swing.Action; 29import javax.swing.DefaultListCellRenderer; 30import javax.swing.JDialog; 31import javax.swing.JFileChooser; 32import javax.swing.JFrame; 33import javax.swing.JLabel; 34import javax.swing.JList; 35import javax.swing.JOptionPane; 36import javax.swing.JProgressBar; 37import javax.swing.JScrollPane; 38import javax.swing.JTable; 39import javax.swing.JToolBar; 40import javax.swing.ListModel; 41import javax.swing.SwingUtilities; 42import javax.swing.table.TableModel; 43 44public class UI extends JFrame { 45 46 private JList<Client> clientList; 47 private JTable dataTable; 48 49 // Shared file chooser, means the directory is retained. 50 private JFileChooser jfc; 51 52 public UI(ListModel<Client> clientListModel, 53 TableModel dataTableModel, 54 List<Action> actions) { 55 super("Preloaded-classes computation"); 56 57 getContentPane().add(new JScrollPane(clientList = new JList<Client>(clientListModel)), 58 BorderLayout.WEST); 59 clientList.setCellRenderer(new ClientListCellRenderer()); 60 // clientList.addListSelectionListener(listener); 61 62 dataTable = new JTable(dataTableModel); 63 getContentPane().add(new JScrollPane(dataTable), BorderLayout.CENTER); 64 65 JToolBar toolbar = new JToolBar(JToolBar.HORIZONTAL); 66 for (Action a : actions) { 67 if (a == null) { 68 toolbar.addSeparator(); 69 } else { 70 toolbar.add(a); 71 } 72 } 73 getContentPane().add(toolbar, BorderLayout.PAGE_START); 74 75 setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 76 setBounds(100, 100, 800, 600); 77 } 78 79 public Client getSelectedClient() { 80 return clientList.getSelectedValue(); 81 } 82 83 public int getSelectedDataTableRow() { 84 return dataTable.getSelectedRow(); 85 } 86 87 private JDialog currentWaitDialog = null; 88 89 public void showWaitDialog() { 90 if (currentWaitDialog == null) { 91 currentWaitDialog = new JDialog(this, "Please wait...", true); 92 currentWaitDialog.getContentPane().add(new JLabel("Please be patient."), 93 BorderLayout.CENTER); 94 JProgressBar progress = new JProgressBar(JProgressBar.HORIZONTAL); 95 progress.setIndeterminate(true); 96 currentWaitDialog.getContentPane().add(progress, BorderLayout.SOUTH); 97 currentWaitDialog.setSize(200, 100); 98 currentWaitDialog.setLocationRelativeTo(null); 99 showWaitDialogLater(); 100 } 101 } 102 103 private void showWaitDialogLater() { 104 SwingUtilities.invokeLater(new Runnable() { 105 @Override 106 public void run() { 107 if (currentWaitDialog != null) { 108 currentWaitDialog.setVisible(true); // This is blocking. 109 } 110 } 111 }); 112 } 113 114 public void updateWaitDialog(String s) { 115 if (currentWaitDialog != null) { 116 ((JLabel) currentWaitDialog.getContentPane().getComponent(0)).setText(s); 117 Dimension prefSize = currentWaitDialog.getPreferredSize(); 118 Dimension curSize = currentWaitDialog.getSize(); 119 if (prefSize.width > curSize.width || prefSize.height > curSize.height) { 120 currentWaitDialog.setSize(Math.max(prefSize.width, curSize.width), 121 Math.max(prefSize.height, curSize.height)); 122 currentWaitDialog.invalidate(); 123 } 124 } 125 } 126 127 public void hideWaitDialog() { 128 if (currentWaitDialog != null) { 129 currentWaitDialog.setVisible(false); 130 currentWaitDialog = null; 131 } 132 } 133 134 public void showMessageDialog(String s) { 135 // Hide the wait dialog... 136 if (currentWaitDialog != null) { 137 currentWaitDialog.setVisible(false); 138 } 139 140 try { 141 JOptionPane.showMessageDialog(this, s); 142 } finally { 143 // And reshow it afterwards... 144 if (currentWaitDialog != null) { 145 showWaitDialogLater(); 146 } 147 } 148 } 149 150 public boolean showConfirmDialog(String title, String message) { 151 // Hide the wait dialog... 152 if (currentWaitDialog != null) { 153 currentWaitDialog.setVisible(false); 154 } 155 156 try { 157 return JOptionPane.showConfirmDialog(this, title, message, JOptionPane.YES_NO_OPTION) 158 == JOptionPane.YES_OPTION; 159 } finally { 160 // And reshow it afterwards... 161 if (currentWaitDialog != null) { 162 showWaitDialogLater(); 163 } 164 } 165 } 166 167 public String showInputDialog(String message) { 168 // Hide the wait dialog... 169 if (currentWaitDialog != null) { 170 currentWaitDialog.setVisible(false); 171 } 172 173 try { 174 return JOptionPane.showInputDialog(message); 175 } finally { 176 // And reshow it afterwards... 177 if (currentWaitDialog != null) { 178 showWaitDialogLater(); 179 } 180 } 181 } 182 183 @SuppressWarnings("unchecked") 184 public <T> T showChoiceDialog(String title, String message, T[] choices) { 185 // Hide the wait dialog... 186 if (currentWaitDialog != null) { 187 currentWaitDialog.setVisible(false); 188 } 189 190 try{ 191 return (T)JOptionPane.showInputDialog(this, 192 title, 193 message, 194 JOptionPane.QUESTION_MESSAGE, 195 null, 196 choices, 197 choices[0]); 198 } finally { 199 // And reshow it afterwards... 200 if (currentWaitDialog != null) { 201 showWaitDialogLater(); 202 } 203 } 204 } 205 206 public File showSaveDialog() { 207 // Hide the wait dialog... 208 if (currentWaitDialog != null) { 209 currentWaitDialog.setVisible(false); 210 } 211 212 try{ 213 if (jfc == null) { 214 jfc = new JFileChooser(); 215 } 216 217 int ret = jfc.showSaveDialog(this); 218 if (ret == JFileChooser.APPROVE_OPTION) { 219 return jfc.getSelectedFile(); 220 } else { 221 return null; 222 } 223 } finally { 224 // And reshow it afterwards... 225 if (currentWaitDialog != null) { 226 showWaitDialogLater(); 227 } 228 } 229 } 230 231 public File[] showOpenDialog(boolean multi) { 232 // Hide the wait dialog... 233 if (currentWaitDialog != null) { 234 currentWaitDialog.setVisible(false); 235 } 236 237 try{ 238 if (jfc == null) { 239 jfc = new JFileChooser(); 240 } 241 242 jfc.setMultiSelectionEnabled(multi); 243 int ret = jfc.showOpenDialog(this); 244 if (ret == JFileChooser.APPROVE_OPTION) { 245 return jfc.getSelectedFiles(); 246 } else { 247 return null; 248 } 249 } finally { 250 // And reshow it afterwards... 251 if (currentWaitDialog != null) { 252 showWaitDialogLater(); 253 } 254 } 255 } 256 257 private class ClientListCellRenderer extends DefaultListCellRenderer { 258 259 @Override 260 public Component getListCellRendererComponent(JList<?> list, Object value, int index, 261 boolean isSelected, boolean cellHasFocus) { 262 ClientData cd = ((Client) value).getClientData(); 263 String s = cd.getClientDescription() + " (pid " + cd.getPid() + ")"; 264 return super.getListCellRendererComponent(list, s, index, isSelected, cellHasFocus); 265 } 266 } 267} 268