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 
17 package com.android.preload.ui;
18 
19 import com.android.ddmlib.Client;
20 import com.android.ddmlib.ClientData;
21 
22 import java.awt.BorderLayout;
23 import java.awt.Component;
24 import java.awt.Dimension;
25 import java.io.File;
26 import java.util.List;
27 
28 import javax.swing.Action;
29 import javax.swing.DefaultListCellRenderer;
30 import javax.swing.JDialog;
31 import javax.swing.JFileChooser;
32 import javax.swing.JFrame;
33 import javax.swing.JLabel;
34 import javax.swing.JList;
35 import javax.swing.JOptionPane;
36 import javax.swing.JProgressBar;
37 import javax.swing.JScrollPane;
38 import javax.swing.JTable;
39 import javax.swing.JToolBar;
40 import javax.swing.ListModel;
41 import javax.swing.SwingUtilities;
42 import javax.swing.table.TableModel;
43 
44 public 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 
UI(ListModel<Client> clientListModel, TableModel dataTableModel, List<Action> actions)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 
getSelectedClient()79     public Client getSelectedClient() {
80         return clientList.getSelectedValue();
81     }
82 
getSelectedDataTableRow()83     public int getSelectedDataTableRow() {
84         return dataTable.getSelectedRow();
85     }
86 
87     private JDialog currentWaitDialog = null;
88 
showWaitDialog()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 
showWaitDialogLater()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 
updateWaitDialog(String s)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 
hideWaitDialog()127     public void hideWaitDialog() {
128         if (currentWaitDialog != null) {
129             currentWaitDialog.setVisible(false);
130             currentWaitDialog = null;
131         }
132     }
133 
showMessageDialog(String s)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 
showConfirmDialog(String title, String message)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 
showInputDialog(String message)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")
showChoiceDialog(String title, String message, T[] choices)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 
showSaveDialog()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 
showOpenDialog(boolean multi)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
getListCellRendererComponent(JList<?> list, Object value, int index, boolean isSelected, boolean cellHasFocus)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