21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jconsole; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.beans.*; 31 import java.io.*; 32 import java.lang.reflect.Array; 33 import java.util.*; 34 35 import javax.accessibility.*; 36 import javax.swing.*; 37 import javax.swing.border.*; 38 import javax.swing.filechooser.*; 39 import javax.swing.filechooser.FileFilter; 40 41 import com.sun.tools.jconsole.JConsoleContext; 42 43 import static com.sun.tools.jconsole.JConsoleContext.ConnectionState.*; 44 45 import static sun.tools.jconsole.Formatter.*; 46 import static sun.tools.jconsole.ProxyClient.*; 47 import static sun.tools.jconsole.Resources.*; 48 import static sun.tools.jconsole.Utilities.*; 49 50 @SuppressWarnings("serial") 51 public class Plotter extends JComponent 52 implements Accessible, ActionListener, PropertyChangeListener { 53 54 public static enum Unit { 55 NONE, BYTES, PERCENT 56 } 57 58 static final String[] rangeNames = { 59 Resources.getText(" 1 min"), 60 Resources.getText(" 5 min"), 61 Resources.getText("10 min"), 62 Resources.getText("30 min"), 63 Resources.getText(" 1 hour"), 64 Resources.getText(" 2 hours"), 65 Resources.getText(" 3 hours"), 66 Resources.getText(" 6 hours"), 67 Resources.getText("12 hours"), 68 Resources.getText(" 1 day"), 69 Resources.getText(" 7 days"), 70 Resources.getText(" 1 month"), 71 Resources.getText(" 3 months"), 72 Resources.getText(" 6 months"), 73 Resources.getText(" 1 year"), 74 Resources.getText("All") 75 }; 76 77 static final int[] rangeValues = { 78 1, 79 5, 80 10, 81 30, 82 1 * 60, 83 2 * 60, 84 3 * 60, 85 6 * 60, 86 12 * 60, 87 1 * 24 * 60, 88 7 * 24 * 60, 89 1 * 31 * 24 * 60, 90 3 * 31 * 24 * 60, 91 6 * 31 * 24 * 60, 92 366 * 24 * 60, 93 -1 94 }; 230 if (minutes != viewRange) { 231 int oldValue = viewRange; 232 viewRange = minutes; 233 /* Do not i18n this string */ 234 firePropertyChange("viewRange", oldValue, viewRange); 235 if (popupMenu != null) { 236 for (int i = 0; i < menuRBs.length; i++) { 237 if (rangeValues[i] == viewRange) { 238 menuRBs[i].setSelected(true); 239 break; 240 } 241 } 242 } 243 repaint(); 244 } 245 } 246 247 @Override 248 public JPopupMenu getComponentPopupMenu() { 249 if (popupMenu == null) { 250 popupMenu = new JPopupMenu(Resources.getText("Chart:")); 251 timeRangeMenu = new JMenu(Resources.getText("Plotter.timeRangeMenu")); 252 timeRangeMenu.setMnemonic(getMnemonicInt("Plotter.timeRangeMenu")); 253 popupMenu.add(timeRangeMenu); 254 menuRBs = new JRadioButtonMenuItem[rangeNames.length]; 255 ButtonGroup rbGroup = new ButtonGroup(); 256 for (int i = 0; i < rangeNames.length; i++) { 257 menuRBs[i] = new JRadioButtonMenuItem(rangeNames[i]); 258 rbGroup.add(menuRBs[i]); 259 menuRBs[i].addActionListener(this); 260 if (viewRange == rangeValues[i]) { 261 menuRBs[i].setSelected(true); 262 } 263 timeRangeMenu.add(menuRBs[i]); 264 } 265 266 popupMenu.addSeparator(); 267 268 saveAsMI = new JMenuItem(getText("Plotter.saveAsMenuItem")); 269 saveAsMI.setMnemonic(getMnemonicInt("Plotter.saveAsMenuItem")); 270 saveAsMI.addActionListener(this); 271 popupMenu.add(saveAsMI); 272 } 273 return popupMenu; 274 } 275 276 public void actionPerformed(ActionEvent ev) { 277 JComponent src = (JComponent)ev.getSource(); 278 if (src == saveAsMI) { 279 saveAs(); 280 } else { 281 int index = timeRangeMenu.getPopupMenu().getComponentIndex(src); 282 setViewRange(rangeValues[index]); 283 } 284 } 285 286 private void saveAs() { 287 if (saveFC == null) { 288 saveFC = new SaveDataFileChooser(); 289 } 301 out.print("Time"); 302 for (Sequence seq : seqs) { 303 out.print(","+seq.name); 304 } 305 out.println(); 306 307 // Print data lines 308 if (seqs.size() > 0 && seqs.get(0).size > 0) { 309 for (int i = 0; i < seqs.get(0).size; i++) { 310 double excelTime = toExcelTime(times.time(i)); 311 out.print(String.format(Locale.ENGLISH, "%.6f", excelTime)); 312 for (Sequence seq : seqs) { 313 out.print("," + getFormattedValue(seq.value(i), false)); 314 } 315 out.println(); 316 } 317 } 318 319 out.close(); 320 JOptionPane.showMessageDialog(this, 321 getText("FileChooser.savedFile", 322 file.getAbsolutePath(), 323 file.length())); 324 } catch (IOException ex) { 325 String msg = ex.getLocalizedMessage(); 326 String path = file.getAbsolutePath(); 327 if (msg.startsWith(path)) { 328 msg = msg.substring(path.length()).trim(); 329 } 330 JOptionPane.showMessageDialog(this, 331 getText("FileChooser.saveFailed.message", 332 path, msg), 333 getText("FileChooser.saveFailed.title"), 334 JOptionPane.ERROR_MESSAGE); 335 } 336 } 337 338 @Override 339 public void paintComponent(Graphics g) { 340 super.paintComponent(g); 341 342 Color oldColor = g.getColor(); 343 Font oldFont = g.getFont(); 344 Color fg = getForeground(); 345 Color bg = getBackground(); 346 boolean bgIsLight = (bg.getRed() > 200 && 347 bg.getGreen() > 200 && 348 bg.getBlue() > 200); 349 350 351 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, 352 RenderingHints.VALUE_ANTIALIAS_ON); 353 1003 if (file != null) { 1004 FileFilter filter = getFileFilter(); 1005 if (filter != null && filter instanceof FileNameExtensionFilter) { 1006 String[] extensions = 1007 ((FileNameExtensionFilter)filter).getExtensions(); 1008 1009 boolean goodExt = false; 1010 for (String ext : extensions) { 1011 if (file.getName().toLowerCase().endsWith("." + ext.toLowerCase())) { 1012 goodExt = true; 1013 break; 1014 } 1015 } 1016 if (!goodExt) { 1017 file = new File(file.getParent(), 1018 file.getName() + "." + extensions[0]); 1019 } 1020 } 1021 1022 if (file.exists()) { 1023 String okStr = getText("FileChooser.fileExists.okOption"); 1024 String cancelStr = getText("FileChooser.fileExists.cancelOption"); 1025 int ret = 1026 JOptionPane.showOptionDialog(this, 1027 getText("FileChooser.fileExists.message", 1028 file.getName()), 1029 getText("FileChooser.fileExists.title"), 1030 JOptionPane.OK_CANCEL_OPTION, 1031 JOptionPane.WARNING_MESSAGE, 1032 null, 1033 new Object[] { okStr, cancelStr }, 1034 okStr); 1035 if (ret != JOptionPane.OK_OPTION) { 1036 return; 1037 } 1038 } 1039 setSelectedFile(file); 1040 } 1041 super.approveSelection(); 1042 } 1043 } 1044 1045 @Override 1046 public AccessibleContext getAccessibleContext() { 1047 if (accessibleContext == null) { 1048 accessibleContext = new AccessiblePlotter(); 1049 } 1050 return accessibleContext; 1051 } 1052 1053 protected class AccessiblePlotter extends AccessibleJComponent { 1054 private static final long serialVersionUID = -3847205410473510922L; 1055 protected AccessiblePlotter() { 1056 setAccessibleName(getText("Plotter.accessibleName")); 1057 } 1058 1059 @Override 1060 public String getAccessibleName() { 1061 String name = super.getAccessibleName(); 1062 1063 if (seqs.size() > 0 && seqs.get(0).size > 0) { 1064 String keyValueList = ""; 1065 for (Sequence seq : seqs) { 1066 if (seq.isPlotted) { 1067 String value = "null"; 1068 if (seq.size > 0) { 1069 if (unit == Unit.BYTES) { 1070 value = getText("Size Bytes", seq.value(seq.size - 1)); 1071 } else { 1072 value = 1073 getFormattedValue(seq.value(seq.size - 1), false) + 1074 ((unit == Unit.PERCENT) ? "%" : ""); 1075 } 1076 } 1077 // Assume format string ends with newline 1078 keyValueList += 1079 getText("Plotter.accessibleName.keyAndValue", 1080 seq.key, value); 1081 } 1082 } 1083 name += "\n" + keyValueList + "."; 1084 } else { 1085 name += "\n" + getText("Plotter.accessibleName.noData"); 1086 } 1087 return name; 1088 } 1089 1090 @Override 1091 public AccessibleRole getAccessibleRole() { 1092 return AccessibleRole.CANVAS; 1093 } 1094 } 1095 } | 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package sun.tools.jconsole; 27 28 import java.awt.*; 29 import java.awt.event.*; 30 import java.beans.*; 31 import java.io.*; 32 import java.lang.reflect.Array; 33 import java.util.*; 34 35 import javax.accessibility.*; 36 import javax.swing.*; 37 import javax.swing.border.*; 38 import javax.swing.filechooser.*; 39 import javax.swing.filechooser.FileFilter; 40 41 import sun.tools.jconsole.resources.Messages; 42 43 import com.sun.tools.jconsole.JConsoleContext; 44 45 import static sun.tools.jconsole.Formatter.*; 46 import static sun.tools.jconsole.ProxyClient.*; 47 48 @SuppressWarnings("serial") 49 public class Plotter extends JComponent 50 implements Accessible, ActionListener, PropertyChangeListener { 51 52 public static enum Unit { 53 NONE, BYTES, PERCENT 54 } 55 56 static final String[] rangeNames = { 57 Messages.ONE_MIN, 58 Messages.FIVE_MIN, 59 Messages.TEN_MIN, 60 Messages.THIRTY_MIN, 61 Messages.ONE_HOUR, 62 Messages.TWO_HOURS, 63 Messages.THREE_HOURS, 64 Messages.SIX_HOURS, 65 Messages.TWELVE_HOURS, 66 Messages.ONE_DAY, 67 Messages.SEVEN_DAYS, 68 Messages.ONE_MONTH, 69 Messages.THREE_MONTHS, 70 Messages.SIX_MONTHS, 71 Messages.ONE_YEAR, 72 Messages.ALL 73 }; 74 75 static final int[] rangeValues = { 76 1, 77 5, 78 10, 79 30, 80 1 * 60, 81 2 * 60, 82 3 * 60, 83 6 * 60, 84 12 * 60, 85 1 * 24 * 60, 86 7 * 24 * 60, 87 1 * 31 * 24 * 60, 88 3 * 31 * 24 * 60, 89 6 * 31 * 24 * 60, 90 366 * 24 * 60, 91 -1 92 }; 228 if (minutes != viewRange) { 229 int oldValue = viewRange; 230 viewRange = minutes; 231 /* Do not i18n this string */ 232 firePropertyChange("viewRange", oldValue, viewRange); 233 if (popupMenu != null) { 234 for (int i = 0; i < menuRBs.length; i++) { 235 if (rangeValues[i] == viewRange) { 236 menuRBs[i].setSelected(true); 237 break; 238 } 239 } 240 } 241 repaint(); 242 } 243 } 244 245 @Override 246 public JPopupMenu getComponentPopupMenu() { 247 if (popupMenu == null) { 248 popupMenu = new JPopupMenu(Messages.CHART_COLON); 249 timeRangeMenu = new JMenu(Messages.PLOTTER_TIME_RANGE_MENU); 250 timeRangeMenu.setMnemonic(Resources.getMnemonicInt(Messages.PLOTTER_TIME_RANGE_MENU)); 251 popupMenu.add(timeRangeMenu); 252 menuRBs = new JRadioButtonMenuItem[rangeNames.length]; 253 ButtonGroup rbGroup = new ButtonGroup(); 254 for (int i = 0; i < rangeNames.length; i++) { 255 menuRBs[i] = new JRadioButtonMenuItem(rangeNames[i]); 256 rbGroup.add(menuRBs[i]); 257 menuRBs[i].addActionListener(this); 258 if (viewRange == rangeValues[i]) { 259 menuRBs[i].setSelected(true); 260 } 261 timeRangeMenu.add(menuRBs[i]); 262 } 263 264 popupMenu.addSeparator(); 265 266 saveAsMI = new JMenuItem(Messages.PLOTTER_SAVE_AS_MENU_ITEM); 267 saveAsMI.setMnemonic(Resources.getMnemonicInt(Messages.PLOTTER_SAVE_AS_MENU_ITEM)); 268 saveAsMI.addActionListener(this); 269 popupMenu.add(saveAsMI); 270 } 271 return popupMenu; 272 } 273 274 public void actionPerformed(ActionEvent ev) { 275 JComponent src = (JComponent)ev.getSource(); 276 if (src == saveAsMI) { 277 saveAs(); 278 } else { 279 int index = timeRangeMenu.getPopupMenu().getComponentIndex(src); 280 setViewRange(rangeValues[index]); 281 } 282 } 283 284 private void saveAs() { 285 if (saveFC == null) { 286 saveFC = new SaveDataFileChooser(); 287 } 299 out.print("Time"); 300 for (Sequence seq : seqs) { 301 out.print(","+seq.name); 302 } 303 out.println(); 304 305 // Print data lines 306 if (seqs.size() > 0 && seqs.get(0).size > 0) { 307 for (int i = 0; i < seqs.get(0).size; i++) { 308 double excelTime = toExcelTime(times.time(i)); 309 out.print(String.format(Locale.ENGLISH, "%.6f", excelTime)); 310 for (Sequence seq : seqs) { 311 out.print("," + getFormattedValue(seq.value(i), false)); 312 } 313 out.println(); 314 } 315 } 316 317 out.close(); 318 JOptionPane.showMessageDialog(this, 319 Resources.format(Messages.FILE_CHOOSER_SAVED_FILE, 320 file.getAbsolutePath(), 321 file.length())); 322 } catch (IOException ex) { 323 String msg = ex.getLocalizedMessage(); 324 String path = file.getAbsolutePath(); 325 if (msg.startsWith(path)) { 326 msg = msg.substring(path.length()).trim(); 327 } 328 JOptionPane.showMessageDialog(this, 329 Resources.format(Messages.FILE_CHOOSER_SAVE_FAILED_MESSAGE, 330 path, msg), 331 Messages.FILE_CHOOSER_SAVE_FAILED_TITLE, 332 JOptionPane.ERROR_MESSAGE); 333 } 334 } 335 336 @Override 337 public void paintComponent(Graphics g) { 338 super.paintComponent(g); 339 340 Color oldColor = g.getColor(); 341 Font oldFont = g.getFont(); 342 Color fg = getForeground(); 343 Color bg = getBackground(); 344 boolean bgIsLight = (bg.getRed() > 200 && 345 bg.getGreen() > 200 && 346 bg.getBlue() > 200); 347 348 349 ((Graphics2D)g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, 350 RenderingHints.VALUE_ANTIALIAS_ON); 351 1001 if (file != null) { 1002 FileFilter filter = getFileFilter(); 1003 if (filter != null && filter instanceof FileNameExtensionFilter) { 1004 String[] extensions = 1005 ((FileNameExtensionFilter)filter).getExtensions(); 1006 1007 boolean goodExt = false; 1008 for (String ext : extensions) { 1009 if (file.getName().toLowerCase().endsWith("." + ext.toLowerCase())) { 1010 goodExt = true; 1011 break; 1012 } 1013 } 1014 if (!goodExt) { 1015 file = new File(file.getParent(), 1016 file.getName() + "." + extensions[0]); 1017 } 1018 } 1019 1020 if (file.exists()) { 1021 String okStr = Messages.FILE_CHOOSER_FILE_EXISTS_OK_OPTION; 1022 String cancelStr = Messages.FILE_CHOOSER_FILE_EXISTS_CANCEL_OPTION; 1023 int ret = 1024 JOptionPane.showOptionDialog(this, 1025 Resources.format(Messages.FILE_CHOOSER_FILE_EXISTS_MESSAGE, 1026 file.getName()), 1027 Messages.FILE_CHOOSER_FILE_EXISTS_TITLE, 1028 JOptionPane.OK_CANCEL_OPTION, 1029 JOptionPane.WARNING_MESSAGE, 1030 null, 1031 new Object[] { okStr, cancelStr }, 1032 okStr); 1033 if (ret != JOptionPane.OK_OPTION) { 1034 return; 1035 } 1036 } 1037 setSelectedFile(file); 1038 } 1039 super.approveSelection(); 1040 } 1041 } 1042 1043 @Override 1044 public AccessibleContext getAccessibleContext() { 1045 if (accessibleContext == null) { 1046 accessibleContext = new AccessiblePlotter(); 1047 } 1048 return accessibleContext; 1049 } 1050 1051 protected class AccessiblePlotter extends AccessibleJComponent { 1052 private static final long serialVersionUID = -3847205410473510922L; 1053 protected AccessiblePlotter() { 1054 setAccessibleName(Messages.PLOTTER_ACCESSIBLE_NAME); 1055 } 1056 1057 @Override 1058 public String getAccessibleName() { 1059 String name = super.getAccessibleName(); 1060 1061 if (seqs.size() > 0 && seqs.get(0).size > 0) { 1062 String keyValueList = ""; 1063 for (Sequence seq : seqs) { 1064 if (seq.isPlotted) { 1065 String value = "null"; 1066 if (seq.size > 0) { 1067 if (unit == Unit.BYTES) { 1068 value = Resources.format(Messages.SIZE_BYTES, seq.value(seq.size - 1)); 1069 } else { 1070 value = 1071 getFormattedValue(seq.value(seq.size - 1), false) + 1072 ((unit == Unit.PERCENT) ? "%" : ""); 1073 } 1074 } 1075 // Assume format string ends with newline 1076 keyValueList += 1077 Resources.format(Messages.PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE, 1078 seq.key, value); 1079 } 1080 } 1081 name += "\n" + keyValueList + "."; 1082 } else { 1083 name += "\n" + Messages.PLOTTER_ACCESSIBLE_NAME_NO_DATA; 1084 } 1085 return name; 1086 } 1087 1088 @Override 1089 public AccessibleRole getAccessibleRole() { 1090 return AccessibleRole.CANVAS; 1091 } 1092 } 1093 } |