001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2018 005 * Space Science and Engineering Center (SSEC) 006 * University of Wisconsin - Madison 007 * 1225 W. Dayton Street, Madison, WI 53706, USA 008 * https://www.ssec.wisc.edu/mcidas 009 * 010 * All Rights Reserved 011 * 012 * McIDAS-V is built on Unidata's IDV and SSEC's VisAD libraries, and 013 * some McIDAS-V source code is based on IDV and VisAD source code. 014 * 015 * McIDAS-V is free software; you can redistribute it and/or modify 016 * it under the terms of the GNU Lesser Public License as published by 017 * the Free Software Foundation; either version 3 of the License, or 018 * (at your option) any later version. 019 * 020 * McIDAS-V is distributed in the hope that it will be useful, 021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 023 * GNU Lesser Public License for more details. 024 * 025 * You should have received a copy of the GNU Lesser Public License 026 * along with this program. If not, see http://www.gnu.org/licenses. 027 */ 028 029package edu.wisc.ssec.mcidasv; 030 031import static javax.swing.GroupLayout.Alignment.BASELINE; 032import static javax.swing.GroupLayout.Alignment.LEADING; 033import static javax.swing.GroupLayout.Alignment.TRAILING; 034import static javax.swing.GroupLayout.DEFAULT_SIZE; 035import static javax.swing.GroupLayout.PREFERRED_SIZE; 036import static javax.swing.LayoutStyle.ComponentPlacement.RELATED; 037 038import java.awt.BorderLayout; 039import java.awt.CardLayout; 040import java.awt.Color; 041import java.awt.Component; 042import java.awt.Container; 043import java.awt.Dimension; 044import java.awt.FlowLayout; 045import java.awt.Font; 046import java.awt.Graphics; 047import java.awt.Graphics2D; 048import java.awt.Insets; 049import java.awt.RenderingHints; 050import java.awt.event.ActionEvent; 051import java.awt.event.ActionListener; 052import java.beans.PropertyChangeEvent; 053import java.beans.PropertyChangeListener; 054import java.net.URL; 055import java.text.Collator; 056import java.text.DecimalFormat; 057import java.util.ArrayList; 058import java.util.Arrays; 059import java.util.Collection; 060import java.util.Collections; 061import java.util.Enumeration; 062import java.util.HashMap; 063import java.util.Hashtable; 064import java.util.LinkedHashSet; 065import java.util.List; 066import java.util.Map; 067import java.util.Set; 068import java.util.TimeZone; 069import java.util.TreeSet; 070 071import javax.swing.BorderFactory; 072import javax.swing.BoxLayout; 073import javax.swing.DefaultListCellRenderer; 074import javax.swing.DefaultListModel; 075import javax.swing.GroupLayout; 076import javax.swing.ImageIcon; 077import javax.swing.JButton; 078import javax.swing.JCheckBox; 079import javax.swing.JComboBox; 080import javax.swing.JComponent; 081import javax.swing.JLabel; 082import javax.swing.JList; 083import javax.swing.JOptionPane; 084import javax.swing.JPanel; 085import javax.swing.JRadioButton; 086import javax.swing.JScrollPane; 087import javax.swing.JSlider; 088import javax.swing.JTextField; 089import javax.swing.ListSelectionModel; 090import javax.swing.SwingConstants; 091import javax.swing.SwingUtilities; 092import javax.swing.border.BevelBorder; 093import javax.swing.event.ChangeEvent; 094import javax.swing.event.ChangeListener; 095import javax.swing.event.ListSelectionEvent; 096import javax.swing.event.ListSelectionListener; 097 098import edu.wisc.ssec.mcidasv.ui.ColorSwatchComponent; 099import edu.wisc.ssec.mcidasv.util.GetMem; 100 101import org.bushe.swing.event.EventBus; 102import org.bushe.swing.event.annotation.AnnotationProcessor; 103import org.bushe.swing.event.annotation.EventSubscriber; 104import org.slf4j.Logger; 105import org.slf4j.LoggerFactory; 106import org.w3c.dom.Element; 107import org.w3c.dom.NodeList; 108 109import ucar.unidata.data.DataUtil; 110import ucar.unidata.geoloc.ProjectionImpl; 111import ucar.unidata.idv.ControlDescriptor; 112import ucar.unidata.idv.DisplayControl; 113import ucar.unidata.idv.IdvConstants; 114import ucar.unidata.idv.IdvObjectStore; 115import ucar.unidata.idv.IdvPreferenceManager; 116import ucar.unidata.idv.IntegratedDataViewer; 117import ucar.unidata.idv.MapViewManager; 118import ucar.unidata.idv.ViewManager; 119import ucar.unidata.idv.control.DisplayControlImpl; 120import ucar.unidata.ui.CheckboxCategoryPanel; 121import ucar.unidata.ui.FontSelector; 122import ucar.unidata.ui.HelpTipDialog; 123import ucar.unidata.ui.XmlUi; 124import ucar.unidata.util.FileManager; 125import ucar.unidata.util.GuiUtils; 126import ucar.unidata.util.IOUtil; 127import ucar.unidata.util.LogUtil; 128import ucar.unidata.util.Misc; 129import ucar.unidata.util.Msg; 130import ucar.unidata.util.ObjectListener; 131import ucar.unidata.util.StringUtil; 132import ucar.unidata.util.TwoFacedObject; 133import ucar.unidata.xml.PreferenceManager; 134import ucar.unidata.xml.XmlObjectStore; 135import ucar.unidata.xml.XmlUtil; 136import ucar.visad.UtcDate; 137import visad.DateTime; 138import visad.Unit; 139import edu.wisc.ssec.mcidasv.servermanager.EntryStore; 140import edu.wisc.ssec.mcidasv.servermanager.AddePreferences; 141import edu.wisc.ssec.mcidasv.servermanager.AddePreferences.AddePrefConglomeration; 142import edu.wisc.ssec.mcidasv.startupmanager.Platform; 143import edu.wisc.ssec.mcidasv.startupmanager.StartupManager; 144import edu.wisc.ssec.mcidasv.ui.McvToolbarEditor; 145import edu.wisc.ssec.mcidasv.ui.UIManager; 146import edu.wisc.ssec.mcidasv.util.CollectionHelpers; 147import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 148import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width; 149 150/** 151 * <p>An extension of {@link ucar.unidata.idv.IdvPreferenceManager} that uses 152 * a JList instead of tabs to lay out the various PreferenceManagers.</p> 153 * 154 * @author McIDAS-V Dev Team 155 */ 156public class McIdasPreferenceManager extends IdvPreferenceManager implements ListSelectionListener, Constants { 157 158 /** Logger object. */ 159 private static final Logger logger = LoggerFactory.getLogger(McIdasPreferenceManager.class); 160 161 public static final float LOGO_SCALE_MIN = 0.1f; 162 public static final float LOGO_SCALE_MAX = 2.0f; 163 164 /** 165 * <p>Controls how the preference panel list is displayed. Want to modify 166 * the preferences UI in some way? PREF_PANELS is your friend. Think of 167 * it like a really brain-dead SQLite.</p> 168 * 169 * <p>Each row is a panel, and <b>must</b> consist of three columns.</p> 170 * 171 * <ol start="0"> 172 * <li>Name of the panel.</li> 173 * <li>Path to the icon associated with the panel.</li> 174 * <li>The panel's {@literal "help ID."}</li> 175 * </ol> 176 * 177 * <p>The {@link JList} in the preferences window will order the panels 178 * based upon {@code PREF_PANELS}.</p> 179 */ 180 public static final String[][] PREF_PANELS = { 181 { Constants.PREF_LIST_GENERAL, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/mcidasv-round32.png", "idv.tools.preferences.generalpreferences" }, 182 { Constants.PREF_LIST_VIEW, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/tab-new32.png", "idv.tools.preferences.displaywindowpreferences" }, 183 { Constants.PREF_LIST_TOOLBAR, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/application-x-executable32.png", "idv.tools.preferences.toolbarpreferences" }, 184 { Constants.PREF_LIST_DATA_CHOOSERS, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/preferences-desktop-remote-desktop32.png", "idv.tools.preferences.datapreferences" }, 185 { Constants.PREF_LIST_ADDE_SERVERS, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/applications-internet32.png", "idv.tools.preferences.serverpreferences" }, 186 { Constants.PREF_LIST_AVAILABLE_DISPLAYS, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/video-display32.png", "idv.tools.preferences.availabledisplayspreferences" }, 187 { Constants.PREF_LIST_NAV_CONTROLS, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/input-mouse32.png", "idv.tools.preferences.navigationpreferences" }, 188 { Constants.PREF_LIST_FORMATS_DATA,"/edu/wisc/ssec/mcidasv/resources/icons/prefs/preferences-desktop-theme32.png", "idv.tools.preferences.formatpreferences" }, 189 { Constants.PREF_LIST_ADVANCED, "/edu/wisc/ssec/mcidasv/resources/icons/prefs/applications-internet32.png", "idv.tools.preferences.advancedpreferences" } 190 }; 191 192 /** Desired rendering hints with their desired values. */ 193 public static final Object[][] RENDER_HINTS = { 194 { RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON }, 195 { RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY }, 196 { RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON } 197 }; 198 199 /** Options for bundle loading */ 200 public static final String[] loadComboOptions = { 201 "Create new window(s)", 202 "Merge with active tab(s)", 203 "Add new tab(s) to current window", 204 "Replace session" 205 }; 206 207 /** 208 * @return The rendering hints to use, as determined by RENDER_HINTS. 209 */ 210 public static RenderingHints getRenderingHints() { 211 RenderingHints hints = new RenderingHints(null); 212 for (int i = 0; i < RENDER_HINTS.length; i++) { 213 hints.put(RENDER_HINTS[i][0], RENDER_HINTS[i][1]); 214 } 215 return hints; 216 } 217 218 /** Help McV remember the last preference panel the user selected. */ 219 private static final String LAST_PREF_PANEL = "mcv.prefs.lastpanel"; 220 221 private static final String LEGEND_TEMPLATE_DATA = "%datasourcename% - %displayname%"; 222 private static final String DISPLAY_LIST_TEMPLATE_DATA = "%datasourcename% - %displayname% " + UtcDate.MACRO_TIMESTAMP; 223 private static final String TEMPLATE_IMAGEDISPLAY = "%longname% " + UtcDate.MACRO_TIMESTAMP; 224 225 private static final String TEMPLATE_NO_DATA = "%displayname%"; 226 227 /** test value for formatting */ 228 private static double latlonValue = -104.56284; 229 230 /** Decimal format */ 231 private static DecimalFormat latlonFormat = new DecimalFormat(); 232 233 /** Provide some default values for the lat-lon preference drop down. */ 234 private static final Set<String> defaultLatLonFormats = 235 CollectionHelpers.set("##0", 236 "##0.0", 237 "##0.0#", 238 "##0.0##", 239 "0.0", 240 "0.00", 241 "0.000"); 242 243 private static final Set<String> probeFormatsList = 244 CollectionHelpers.set(DisplayControl.DEFAULT_PROBEFORMAT, 245 "%rawvalue% [%rawunit%]", 246 "%value%", 247 "%rawvalue%", 248 "%value% <i>%unit%</i>"); 249 250 /** 251 * Replacing the "incoming" IDV preference tab names with whatever's in 252 * this map. 253 */ 254 private static final Map<String, String> replaceMap = 255 CollectionHelpers.zipMap( 256 CollectionHelpers.arr("Toolbar", "View"), 257 CollectionHelpers.arr(Constants.PREF_LIST_TOOLBAR, Constants.PREF_LIST_VIEW)); 258 259 /** Path to the McV choosers.xml */ 260 private static final String MCV_CHOOSERS = "/edu/wisc/ssec/mcidasv/resources/choosers.xml"; 261 262 /** 263 * Maps the {@literal "name"} of a panel to the actual thing holding the 264 * PreferenceManager. 265 */ 266 private final Map<String, Container> prefMap = CollectionHelpers.concurrentMap(); 267 268 /** Maps the name of a panel to an icon. */ 269 private final Map<String, ImageIcon> iconCache = CollectionHelpers.concurrentMap(); 270 271 /** 272 * A table of the different preference managers that'll wind up in the 273 * list. 274 */ 275 private final Map<String, PreferenceManager> managerMap = CollectionHelpers.concurrentMap(); 276 277 /** 278 * Each PreferenceManager has associated data contained in this table. 279 * TODO: bug Unidata about getting IdvPreferenceManager's dataList protected 280 */ 281 private final Map<String, Object> dataMap = CollectionHelpers.concurrentMap(); 282 283 private final Set<String> labelSet = new LinkedHashSet<String>(); 284 285 /** 286 * The list that'll contain all the names of the different 287 * PreferenceManagers 288 */ 289 private JList labelList; 290 291 /** The "M" in the MVC for JLists. Contains all the list data. */ 292 private DefaultListModel listModel; 293 294 /** Handle scrolling like a pro. */ 295 private JScrollPane listScrollPane; 296 297 /** Holds the main preference pane */ 298 private JPanel mainPane; 299 300 /** Holds the buttons at the bottom */ 301 private JPanel buttonPane; 302 303 /** Date formats */ 304 private final Set<String> dateFormats = CollectionHelpers.set( 305 DEFAULT_DATE_FORMAT, "MM/dd/yy HH:mm z", "dd.MM.yy HH:mm z", 306 "yyyy-MM-dd", "EEE, MMM dd yyyy HH:mm z", "HH:mm:ss", "HH:mm", 307 "yyyy-MM-dd'T'HH:mm:ss'Z'", "yyyy-MM-dd'T'HH:mm:ssZ"); 308 309 /** The toolbar editor */ 310 private McvToolbarEditor toolbarEditor; 311 312 /** 313 * Prep as much as possible for displaying the preference window: load up 314 * icons and create some of the window features. 315 * 316 * @param idv Reference to the supreme IDV object. 317 */ 318 public McIdasPreferenceManager(IntegratedDataViewer idv) { 319 super(idv); 320 AnnotationProcessor.process(this); 321 init(); 322 323 for (int i = 0; i < PREF_PANELS.length; i++) { 324 URL url = getClass().getResource(PREF_PANELS[i][1]); 325 iconCache.put(PREF_PANELS[i][0], new ImageIcon(url)); 326 } 327 328 setEmptyPref("idv.displaylist.template.data", DISPLAY_LIST_TEMPLATE_DATA); 329 setEmptyPref("idv.displaylist.template.nodata", TEMPLATE_NO_DATA); 330 setEmptyPref("idv.displaylist.template.imagedisplay", TEMPLATE_IMAGEDISPLAY); 331 setEmptyPref("idv.legendlabel.template.data", LEGEND_TEMPLATE_DATA); 332 setEmptyPref("idv.legendlabel.template.nodata", TEMPLATE_NO_DATA); 333 } 334 335 private boolean setEmptyPref(final String id, final String val) { 336 IdvObjectStore store = getIdv().getStore(); 337 if (store.get(id, (String)null) == null) { 338 store.put(id, val); 339 return true; 340 } 341 return false; 342 } 343 344 /** 345 * Overridden so McIDAS-V can direct users to specific help sections for 346 * each preference panel. 347 */ 348 @Override public void actionPerformed(ActionEvent event) { 349 String cmd = event.getActionCommand(); 350 if (!GuiUtils.CMD_HELP.equals(cmd) || labelList == null) { 351 super.actionPerformed(event); 352 return; 353 } 354 355 int selectedIndex = labelList.getSelectedIndex(); 356 getIdvUIManager().showHelp(PREF_PANELS[selectedIndex][2]); 357 } 358 359 public void replaceServerPrefPanel(final JPanel panel) { 360 String name = "SERVER MANAGER"; 361 mainPane.add(name, panel); 362 ((CardLayout)mainPane.getLayout()).show(mainPane, name); 363 } 364 365 @EventSubscriber(eventClass=EntryStore.Event.class) 366 public void replaceServerPreferences(EntryStore.Event evt) { 367 EntryStore remoteAddeStore = ((McIDASV)getIdv()).getServerManager(); 368 AddePreferences prefs = new AddePreferences(remoteAddeStore); 369 AddePrefConglomeration eww = prefs.buildPanel((McIDASV)getIdv()); 370 } 371 372 /** 373 * Add a PreferenceManager to the list of things that should be shown in 374 * the preference dialog. 375 * 376 * @param tabLabel The label (or name) of the PreferenceManager. 377 * @param description Not used. 378 * @param listener The actual PreferenceManager. 379 * @param panel The container holding all of the PreferenceManager stuff. 380 * @param data Data passed to the preference manager. 381 */ 382 @Override public void add(String tabLabel, String description, 383 PreferenceManager listener, Container panel, Object data) { 384 385 // if there is an alternate name for tabLabel, find and use it. 386 if (replaceMap.containsKey(tabLabel) == true) { 387 tabLabel = replaceMap.get(tabLabel); 388 } 389 390 if (prefMap.containsKey(tabLabel) == true) { 391 return; 392 } 393 394 // figure out the last panel that was selected. 395 int selected = getIdv().getObjectStore().get(LAST_PREF_PANEL, 0); 396 if (selected < 0 || selected >= PREF_PANELS.length) { 397 logger.warn("attempted to select an invalid preference panel: {}", selected); 398 selected = 0; 399 } 400 String selectedPanel = PREF_PANELS[selected][0]; 401 402 panel.setPreferredSize(null); 403 404 Msg.translateTree(panel); 405 406 managerMap.put(tabLabel, listener); 407 if (data == null) { 408 dataMap.put(tabLabel, new Hashtable()); 409 } else { 410 dataMap.put(tabLabel, data); 411 } 412 prefMap.put(tabLabel, panel); 413 414 if (labelSet.add(tabLabel)) { 415 JLabel label = new JLabel(); 416 label.setText(tabLabel); 417 label.setIcon(iconCache.get(tabLabel)); 418 listModel.addElement(label); 419 420 labelList.setSelectedIndex(selected); 421 mainPane.add(tabLabel, panel); 422 if (selectedPanel.equals(tabLabel)) { 423 ((CardLayout)mainPane.getLayout()).show(mainPane, tabLabel); 424 } 425 } 426 427 mainPane.repaint(); 428 } 429 430 /** 431 * Apply the preferences (taken straight from IDV). 432 * 433 * @return Whether or not each of the preference managers applied properly. 434 */ 435 // TODO(jon?): bug Unidata about making managers and dataList protected instead of private 436 @Override public boolean apply() { 437 try { 438 for (String id : labelSet) { 439 PreferenceManager manager = managerMap.get(id); 440 manager.applyPreference(getStore(), dataMap.get(id)); 441 } 442 fixDisplayListFont(); 443 getStore().save(); 444 return true; 445 } catch (Exception exc) { 446 LogUtil.logException("Error applying preferences", exc); 447 return false; 448 } 449 } 450 451 // For some reason the display list font can have a size of zero if your 452 // new font size didn't change after starting the prefs panel. 453 private void fixDisplayListFont() { 454 IdvObjectStore s = getStore(); 455 Font f = s.get(ViewManager.PREF_DISPLAYLISTFONT, FontSelector.DEFAULT_FONT); 456 if (f.getSize() == 0) { 457 f = f.deriveFont(8f); 458 s.put(ViewManager.PREF_DISPLAYLISTFONT, f); 459 } 460 } 461 462 /** 463 * Select a list item and its corresponding panel that both live within the 464 * preference window JList. 465 * 466 * @param labelName The "name" of the JLabel within the JList. 467 */ 468 public void selectListItem(String labelName) { 469 show(); 470 toFront(); 471 472 for (int i = 0; i < listModel.getSize(); i++) { 473 String labelText = ((JLabel)listModel.get(i)).getText(); 474 if (StringUtil.stringMatch(labelText, labelName)) { 475 // persist across restarts 476 getIdv().getObjectStore().put(LAST_PREF_PANEL, i); 477 labelList.setSelectedIndex(i); 478 return; 479 } 480 } 481 } 482 483 /** 484 * Wrapper so that IDV code can still select which preference pane to show. 485 * 486 * @param tabNameToShow The name of the pane to be shown. Regular 487 * expressions are supported. 488 */ 489 public void showTab(String tabNameToShow) { 490 selectListItem(tabNameToShow); 491 } 492 493 /** 494 * Handle the user clicking around. 495 * 496 * @param e The event to be handled! Use your imagination! 497 */ 498 public void valueChanged(ListSelectionEvent e) { 499 if (e.getValueIsAdjusting() == false) { 500 String name = getSelectedName(); 501 ((CardLayout)mainPane.getLayout()).show(mainPane, name); 502 } 503 } 504 505 /** 506 * Returns the container the corresponds to the currently selected label in 507 * the JList. Also stores the selected panel so that the next time a user 508 * tries to open the preferences they will start off in the panel they last 509 * selected. 510 * 511 * @return The current container. 512 */ 513 private String getSelectedName() { 514 // make sure the selected panel persists across restarts 515 getIdv().getObjectStore().put(LAST_PREF_PANEL, labelList.getSelectedIndex()); 516 String key = ((JLabel)listModel.getElementAt(labelList.getSelectedIndex())).getText(); 517 return key; 518 } 519 520 /** 521 * Perform the GUI initialization for the preference dialog. 522 */ 523 public void init() { 524 listModel = new DefaultListModel(); 525 labelList = new JList(listModel); 526 527 labelList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); 528 labelList.setCellRenderer(new IconCellRenderer()); 529 labelList.addListSelectionListener(new ListSelectionListener() { 530 public void valueChanged(ListSelectionEvent e) { 531 if (e.getValueIsAdjusting() == false) { 532 String name = getSelectedName(); 533 if (Constants.PREF_LIST_NAV_CONTROLS.equals(name)) { 534 mainPane.add(name, makeEventPanel()); 535 mainPane.validate(); 536 } 537 ((CardLayout)mainPane.getLayout()).show(mainPane, name); 538 } 539 } 540 }); 541 542 listScrollPane = new JScrollPane(labelList); 543 listScrollPane.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); 544 545 mainPane = new JPanel(new CardLayout()); 546 mainPane.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED)); 547 mainPane.addPropertyChangeListener(new PropertyChangeListener() { 548 public void propertyChange(PropertyChangeEvent e) { 549// System.err.println("prop change: prop="+e.getPropertyName()+" old="+e.getOldValue()+" new="+e.getNewValue()); 550 String p = e.getPropertyName(); 551 if (!"Frame.active".equals(p) && !"ancestor".equals(p)) { 552 return; 553 } 554 555 Object v = e.getNewValue(); 556 boolean okay = false; 557 if (v instanceof Boolean) { 558 okay = ((Boolean)v).booleanValue(); 559 } else if (v instanceof JPanel) { 560 okay = true; 561 } else { 562 okay = false; 563 } 564 565 if (okay) { 566 if (getSelectedName().equals(Constants.PREF_LIST_NAV_CONTROLS)) { 567 mainPane.add(Constants.PREF_LIST_NAV_CONTROLS, makeEventPanel()); 568 mainPane.validate(); 569 ((CardLayout)mainPane.getLayout()).show(mainPane, Constants.PREF_LIST_NAV_CONTROLS); 570 } 571 } 572 } 573 }); 574 575 JPanel buttons = GuiUtils.makeApplyOkHelpCancelButtons(this); 576 buttonPane = McVGuiUtils.makePrettyButtons(buttons); 577 578 contents = new JPanel(); 579 GroupLayout layout = new GroupLayout(contents); 580 contents.setLayout(layout); 581 layout.setHorizontalGroup( 582 layout.createParallelGroup(LEADING) 583 .addGroup(layout.createSequentialGroup() 584 .addComponent(listScrollPane, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 585 .addPreferredGap(RELATED) 586 .addComponent(mainPane, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 587 .addComponent(buttonPane, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 588 ); 589 layout.setVerticalGroup( 590 layout.createParallelGroup(LEADING) 591 .addGroup(layout.createSequentialGroup() 592 .addGroup(layout.createParallelGroup(TRAILING) 593 .addComponent(mainPane, LEADING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 594 .addComponent(listScrollPane, LEADING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 595 .addPreferredGap(RELATED) 596 .addComponent(buttonPane, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE)) 597 ); 598 } 599 600 /** 601 * Initialize the preference dialog. Leave most of the heavy lifting to 602 * the IDV, except for creating the server manager. 603 */ 604 protected void initPreferences() { 605 // General/McIDAS-V 606 addMcVPreferences(); 607 608 // View/Display Window 609 addDisplayWindowPreferences(); 610 611 // Toolbar/Toolbar Options 612 addToolbarPreferences(); 613 614 // Available Choosers/Data Sources 615 addChooserPreferences(); 616 617 // ADDE Servers 618 addServerPreferences(); 619 620 // Available Displays/Display Types 621 addDisplayPreferences(); 622 623 // Navigation/Navigation Controls 624 addNavigationPreferences(); 625 626 // Formats & Data 627 addFormatDataPreferences(); 628 629 // Advanced 630 if (!labelSet.contains(Constants.PREF_LIST_ADVANCED)) { 631 // due to issue with MemoryOption.getTextComponent, we don't 632 // want to do this again if Advanced tab is already built. 633 // (the heap size text field will disappear on second opening 634 // of McV preferences window!) 635 addAdvancedPreferences(); 636 } 637 } 638 639 /** 640 * Build a {@link AddePreferences} panel {@literal "around"} the 641 * server manager {@link EntryStore}. 642 * 643 * @see McIDASV#getServerManager() 644 */ 645 public void addServerPreferences() { 646 EntryStore remoteAddeStore = ((McIDASV)getIdv()).getServerManager(); 647 AddePreferences prefs = new AddePreferences(remoteAddeStore); 648 prefs.addPanel(this); 649 } 650 651 /** 652 * Create the navigation preference panel 653 */ 654 public void addNavigationPreferences() { 655 PreferenceManager navigationManager = new PreferenceManager() { 656 public void applyPreference(XmlObjectStore theStore, Object data) { 657// System.err.println("applying nav prefs"); 658 } 659 }; 660 this.add(Constants.PREF_LIST_NAV_CONTROLS, "", navigationManager, makeEventPanel(), new Hashtable()); 661 } 662 663 /** 664 * Create the toolbar preference panel 665 */ 666 public void addToolbarPreferences() { 667 if (toolbarEditor == null) { 668 toolbarEditor = 669 new McvToolbarEditor((UIManager)getIdv().getIdvUIManager()); 670 } 671 672 PreferenceManager toolbarManager = new PreferenceManager() { 673 public void applyPreference(XmlObjectStore s, Object d) { 674 if (toolbarEditor.anyChanges() == true) { 675 toolbarEditor.doApply(); 676 UIManager mngr = (UIManager)getIdv().getIdvUIManager(); 677 mngr.setCurrentToolbars(toolbarEditor); 678 } 679 } 680 }; 681 this.add("Toolbar", "Toolbar icons", toolbarManager, 682 toolbarEditor.getContents(), toolbarEditor); 683 } 684 685 /** 686 * Make a checkbox preference panel 687 * 688 * @param objects Holds (Label, preference id, Boolean default value). 689 * If preference id is null then just show the label. If the entry is only length 690 * 2 (i.e., no value) then default to true. 691 * @param widgets The map to store the id to widget 692 * @param store Where to look up the preference value 693 * 694 * @return The created panel 695 */ 696 @SuppressWarnings("unchecked") // idv-style. 697 public static JPanel makePrefPanel(final Object[][] objects, final Hashtable widgets, final XmlObjectStore store) { 698 List<JComponent> comps = CollectionHelpers.arrList(); 699 for (int i = 0; i < objects.length; i++) { 700 final String name = (String)objects[i][0]; 701 final String id = (String)objects[i][1]; 702 final boolean value = ((objects[i].length > 2) ? ((Boolean) objects[i][2]).booleanValue() : true); 703 704 if (id == null) { 705 if (i > 0) { 706 comps.add(new JLabel(" ")); 707 } 708 comps.add(new JLabel(name)); 709 continue; 710 } 711 712 final JCheckBox cb = new JCheckBox(name, store.get(id, value)); 713 cb.addPropertyChangeListener(new PropertyChangeListener() { 714 public void propertyChange(final PropertyChangeEvent e) { 715 SwingUtilities.invokeLater(new Runnable() { 716 public void run() { 717 cb.setSelected(store.get(id, value)); 718 } 719 }); 720 } 721 }); 722 if (objects[i].length > 3) { 723 cb.setToolTipText(objects[i][3].toString()); 724 } 725 widgets.put(id, cb); 726 comps.add(cb); 727 } 728 return GuiUtils.top(GuiUtils.vbox(comps)); 729 } 730 731 public void addAdvancedPreferences() { 732 Hashtable<String, Component> widgets = new Hashtable<String, Component>(); 733 734 McIDASV mcv = (McIDASV)getIdv(); 735 736 // Build the startup options panel 737 final StartupManager startup = StartupManager.getInstance(); 738 Platform platform = startup.getPlatform(); 739 platform.setUserDirectory( 740 mcv.getObjectStore().getUserDirectory().toString()); 741 platform.setAvailableMemory(GetMem.getMemory()); 742 JPanel smPanel = startup.getAdvancedPanel(true); 743 List<JPanel> stuff = Collections.singletonList(smPanel); 744 745 PreferenceManager advancedManager = new PreferenceManager() { 746 public void applyPreference(XmlObjectStore theStore, Object data) { 747 IdvPreferenceManager.applyWidgets((Hashtable)data, theStore); 748 startup.handleApply(); 749 } 750 }; 751 752 JPanel outerPanel = new JPanel(); 753 754 // Outer panel layout 755 GroupLayout layout = new GroupLayout(outerPanel); 756 outerPanel.setLayout(layout); 757 layout.setHorizontalGroup( 758 layout.createParallelGroup(LEADING) 759 .addGroup(layout.createSequentialGroup() 760 .addContainerGap() 761 .addGroup(layout.createParallelGroup(LEADING) 762 .addComponent(smPanel, TRAILING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 763 .addContainerGap()) 764 ); 765 layout.setVerticalGroup( 766 layout.createParallelGroup(LEADING) 767 .addGroup(layout.createSequentialGroup() 768 .addContainerGap() 769 .addComponent(smPanel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 770 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 771 ); 772 773 this.add(Constants.PREF_LIST_ADVANCED, "complicated stuff dude", 774 advancedManager, outerPanel, widgets); 775 } 776 777 /** 778 * Add in the user preference tab for the controls to show 779 */ 780 protected void addDisplayPreferences() { 781 McIDASV mcv = (McIDASV)getIdv(); 782 cbxToCdMap = new Hashtable<JCheckBox, ControlDescriptor>(); 783 List<JPanel> compList = new ArrayList<JPanel>(); 784 List<ControlDescriptor> controlDescriptors = 785 getIdv().getAllControlDescriptors(); 786 787 final List<CheckboxCategoryPanel> catPanels = 788 new ArrayList<CheckboxCategoryPanel>(); 789 790 final Hashtable<String, CheckboxCategoryPanel> catMap = 791 new Hashtable<String, CheckboxCategoryPanel>(); 792 793 for (ControlDescriptor cd : controlDescriptors) { 794 795 final String displayCategory = cd.getDisplayCategory(); 796 797 CheckboxCategoryPanel catPanel = 798 (CheckboxCategoryPanel) catMap.get(displayCategory); 799 800 if (catPanel == null) { 801 catPanel = new CheckboxCategoryPanel(displayCategory, false); 802 catPanels.add(catPanel); 803 catMap.put(displayCategory, catPanel); 804 compList.add(catPanel.getTopPanel()); 805 compList.add(catPanel); 806 } 807 808 JCheckBox cbx = 809 new JCheckBox(cd.getLabel(), shouldShowControl(cd, true)); 810 cbx.setToolTipText(cd.getDescription()); 811 cbxToCdMap.put(cbx, cd); 812 catPanel.addItem(cbx); 813 catPanel.add(GuiUtils.inset(cbx, new Insets(0, 20, 0, 0))); 814 } 815 816 for (CheckboxCategoryPanel cbcp : catPanels) { 817 cbcp.checkVisCbx(); 818 } 819 820 final JButton allOn = new JButton("All on"); 821 allOn.addActionListener(new ActionListener() { 822 public void actionPerformed(ActionEvent ae) { 823 for (CheckboxCategoryPanel cbcp : catPanels) { 824 cbcp.toggleAll(true); 825 } 826 } 827 }); 828 final JButton allOff = new JButton("All off"); 829 allOff.addActionListener(new ActionListener() { 830 public void actionPerformed(ActionEvent ae) { 831 for (CheckboxCategoryPanel cbcp : catPanels) { 832 cbcp.toggleAll(false); 833 } 834 } 835 }); 836 837 Boolean controlsAll = 838 (Boolean)mcv.getPreference(PROP_CONTROLDESCRIPTORS_ALL, Boolean.TRUE); 839 final JRadioButton useAllBtn = new JRadioButton("Use all displays", 840 controlsAll.booleanValue()); 841 final JRadioButton useTheseBtn = 842 new JRadioButton("Use selected displays:", 843 !controlsAll.booleanValue()); 844 GuiUtils.buttonGroup(useAllBtn, useTheseBtn); 845 846 final JPanel cbPanel = GuiUtils.top(GuiUtils.vbox(compList)); 847 848 JScrollPane cbScroller = new JScrollPane(cbPanel); 849 cbScroller.getVerticalScrollBar().setUnitIncrement(10); 850 cbScroller.setPreferredSize(new Dimension(300, 300)); 851 852 JComponent exportComp = 853 GuiUtils.right(GuiUtils.makeButton("Export to Plugin", this, 854 "exportControlsToPlugin")); 855 856 JComponent cbComp = GuiUtils.centerBottom(cbScroller, exportComp); 857 858 JPanel bottomPanel = 859 GuiUtils.leftCenter( 860 GuiUtils.inset( 861 GuiUtils.top(GuiUtils.vbox(allOn, allOff)), 862 4), new Msg.SkipPanel( 863 GuiUtils.hgrid( 864 Misc.newList(cbComp, GuiUtils.filler()), 0))); 865 866 JPanel controlsPanel = 867 GuiUtils.inset(GuiUtils.topCenter(GuiUtils.hbox(useAllBtn, 868 useTheseBtn), bottomPanel), 6); 869 870 GuiUtils.enableTree(cbPanel, !useAllBtn.isSelected()); 871 useAllBtn.addActionListener(new ActionListener() { 872 public void actionPerformed(ActionEvent ae) { 873 GuiUtils.enableTree(cbPanel, !useAllBtn.isSelected()); 874 allOn.setEnabled(!useAllBtn.isSelected()); 875 allOff.setEnabled(!useAllBtn.isSelected()); 876 } 877 }); 878 879 useTheseBtn.addActionListener(new ActionListener() { 880 public void actionPerformed(ActionEvent ae) { 881 GuiUtils.enableTree(cbPanel, !useAllBtn.isSelected()); 882 allOn.setEnabled(!useAllBtn.isSelected()); 883 allOff.setEnabled(!useAllBtn.isSelected()); 884 } 885 }); 886 887 GuiUtils.enableTree(cbPanel, !useAllBtn.isSelected()); 888 889 allOn.setEnabled(!useAllBtn.isSelected()); 890 891 allOff.setEnabled(!useAllBtn.isSelected()); 892 893 PreferenceManager controlsManager = new PreferenceManager() { 894 public void applyPreference(XmlObjectStore theStore, Object data) { 895 controlDescriptorsToShow = new Hashtable(); 896 897 Hashtable<JCheckBox, ControlDescriptor> table = (Hashtable)data; 898 899 List<ControlDescriptor> controlDescriptors = getIdv().getAllControlDescriptors(); 900 901 for (Enumeration keys = table.keys(); keys.hasMoreElements(); ) { 902 JCheckBox cbx = (JCheckBox) keys.nextElement(); 903 ControlDescriptor cd = (ControlDescriptor)table.get(cbx); 904 controlDescriptorsToShow.put(cd.getControlId(), Boolean.valueOf(cbx.isSelected())); 905 } 906 907 showAllControls = useAllBtn.isSelected(); 908 909 theStore.put(PROP_CONTROLDESCRIPTORS, controlDescriptorsToShow); 910 theStore.put(PROP_CONTROLDESCRIPTORS_ALL, Boolean.valueOf(showAllControls)); 911 } 912 }; 913 914 this.add(Constants.PREF_LIST_AVAILABLE_DISPLAYS, 915 "What displays should be available in the user interface?", 916 controlsManager, controlsPanel, cbxToCdMap); 917 } 918 919 protected void addDisplayWindowPreferences() { 920 921 Hashtable<String, JCheckBox> widgets = new Hashtable<>(); 922 MapViewManager mappy = new MapViewManager(getIdv()); 923 924 Object[][] legendObjects = { 925 { "Show Side Legend", MapViewManager.PREF_SHOWSIDELEGEND, Boolean.valueOf(mappy.getShowSideLegend()) }, 926 { "Show Bottom Legend", MapViewManager.PREF_SHOWBOTTOMLEGEND, Boolean.valueOf(mappy.getShowBottomLegend()) } 927 }; 928 JPanel legendPanel = makePrefPanel(legendObjects, widgets, getStore()); 929 legendPanel.setBorder(BorderFactory.createTitledBorder("Legends")); 930 931 Object[][] navigationObjects = { 932 { "Show Earth Navigation Panel", MapViewManager.PREF_SHOWEARTHNAVPANEL, Boolean.valueOf(mappy.getShowEarthNavPanel()) }, 933 { "Show Viewpoint Toolbar", MapViewManager.PREF_SHOWTOOLBAR + "perspective" }, 934 { "Show Zoom/Pan Toolbar", MapViewManager.PREF_SHOWTOOLBAR + "zoompan" }, 935 { "Show Undo/Redo Toolbar", MapViewManager.PREF_SHOWTOOLBAR + "undoredo" } 936 }; 937 JPanel navigationPanel = makePrefPanel(navigationObjects, widgets, getStore()); 938 navigationPanel.setBorder(BorderFactory.createTitledBorder("Navigation Toolbars")); 939 940 String arLabel = "<html>"+MapViewManager.PR_LABEL+"<p>Changes do not affect current displays/layers.</html>"; 941 942 Object[][] panelObjects = { 943 { "Show Globe Background", MapViewManager.PREF_SHOWGLOBEBACKGROUND, Boolean.valueOf(getStore().get(MapViewManager.PREF_SHOWGLOBEBACKGROUND, false)) }, 944 { "Show Top Bar", MapViewManager.PREF_TOPBAR_VISIBLE, Boolean.valueOf(mappy.getTopBarVisible()) }, 945 { "Show Wireframe Box", MapViewManager.PREF_WIREFRAME, Boolean.valueOf(mappy.getWireframe()) }, 946 { "Show Cursor Readout", MapViewManager.PREF_SHOWCURSOR, Boolean.valueOf(mappy.getShowCursor()) }, 947 { "Clip View At Box", MapViewManager.PREF_3DCLIP, Boolean.valueOf(mappy.getClipping()) }, 948 { "Show Layer List in Panel", MapViewManager.PREF_SHOWDISPLAYLIST, Boolean.valueOf(mappy.getShowDisplayList()) }, 949 { "Show Times In Panel", MapViewManager.PREF_ANIREADOUT, Boolean.valueOf(mappy.getAniReadout()) }, 950 { "Show Map Display Scales", MapViewManager.PREF_SHOWSCALES, Boolean.valueOf(mappy.getLabelsVisible()) }, 951 { "Show Transect Display Scales", MapViewManager.PREF_SHOWTRANSECTSCALES, Boolean.valueOf(mappy.getTransectLabelsVisible()) }, 952 { "Show \"Please Wait\" Message", MapViewManager.PREF_WAITMSG, Boolean.valueOf(mappy.getWaitMessageVisible()) }, 953 { "Reset Projection With New Data", MapViewManager.PREF_PROJ_USEFROMDATA }, 954 { ViewManager.LABEL_AUTO_DEPTH, ViewManager.PREF_AUTO_DEPTH, mappy.getAutoDepth() }, 955 { arLabel, MapViewManager.PREF_USE_PROGRESSIVE_RESOLUTION, Boolean.valueOf(getStore().get(MapViewManager.PREF_USE_PROGRESSIVE_RESOLUTION, false)) } 956 }; 957 JPanel panelPanel = makePrefPanel(panelObjects, widgets, getStore()); 958 JCheckBox adaptiveRezCheckBox = widgets.get(MapViewManager.PREF_USE_PROGRESSIVE_RESOLUTION); 959 adaptiveRezCheckBox.setVerticalTextPosition(SwingConstants.TOP); 960 961 panelPanel.setBorder(BorderFactory.createTitledBorder("Panel Configuration")); 962 963 XmlObjectStore store = getStore(); 964 Color globeColor = mappy.getGlobeBackgroundColor(); 965 Color bgColor = store.get(ViewManager.PREF_BGCOLOR, mappy.getBackground()); 966 Color fgColor = store.get(ViewManager.PREF_FGCOLOR, mappy.getForeground()); 967 Color borderColor = store.get(ViewManager.PREF_BORDERCOLOR, Constants.MCV_BLUE_DARK); 968 ColorSwatchComponent globeSwatch = new ColorSwatchComponent(store, globeColor, "Set Globe Background Color"); 969 ColorSwatchComponent bgSwatch = new ColorSwatchComponent(store, bgColor, "Set Background Color"); 970 ColorSwatchComponent fgSwatch = new ColorSwatchComponent(store, fgColor, "Set Foreground Color"); 971 ColorSwatchComponent borderSwatch = new ColorSwatchComponent(store, borderColor, "Set Selected Panel Border Color"); 972 final JComponent[] globeBg = { globeSwatch, globeSwatch.getSetButton(), globeSwatch.getClearButton() }; 973 final JComponent[] bgComps = { bgSwatch, bgSwatch.getSetButton(), bgSwatch.getClearButton() }; 974 final JComponent[] fgComps = { fgSwatch, fgSwatch.getSetButton(), fgSwatch.getClearButton() }; 975 final JComponent[] border = { borderSwatch, borderSwatch.getSetButton(), borderSwatch.getClearButton() }; 976 977 JPanel colorPanel = GuiUtils.vbox( 978 GuiUtils.hbox( 979 McVGuiUtils.makeLabelRight("Globe Background:", Width.ONEHALF), 980 GuiUtils.left(globeBg[0]), 981 GAP_RELATED 982 ), 983 GuiUtils.hbox( 984 McVGuiUtils.makeLabelRight("Background:", Width.ONEHALF), 985 GuiUtils.left(bgComps[0]), 986 GAP_RELATED 987 ), 988 GuiUtils.hbox( 989 McVGuiUtils.makeLabelRight("Foreground:", Width.ONEHALF), 990 GuiUtils.left(fgComps[0]), 991 GAP_RELATED 992 ), 993 GuiUtils.hbox( 994 McVGuiUtils.makeLabelRight("Selected Panel:", Width.ONEHALF), 995 GuiUtils.left(border[0]), 996 GAP_RELATED 997 ) 998 ); 999 1000 colorPanel.setBorder(BorderFactory.createTitledBorder("Color Scheme")); 1001 1002 final FontSelector fontSelector = new FontSelector(FontSelector.COMBOBOX_UI, false, false); 1003 Font f = getStore().get(MapViewManager.PREF_DISPLAYLISTFONT, mappy.getDisplayListFont()); 1004 fontSelector.setFont(f); 1005 Color dlColor = store.get(MapViewManager.PREF_DISPLAYLISTCOLOR, mappy.getDisplayListColor()); 1006 final ColorSwatchComponent dlColorWidget = new ColorSwatchComponent(store, dlColor, "Set Display List Color"); 1007 1008 JPanel fontPanel = GuiUtils.vbox( 1009 GuiUtils.hbox( 1010 McVGuiUtils.makeLabelRight("Font:", Width.ONEHALF), 1011 GuiUtils.left(fontSelector.getComponent()), 1012 GAP_RELATED 1013 ), 1014 GuiUtils.hbox( 1015 McVGuiUtils.makeLabelRight("Color:", Width.ONEHALF), 1016 GuiUtils.left(GuiUtils.hbox(dlColorWidget, dlColorWidget.getClearButton(), GAP_RELATED)), 1017 GAP_RELATED 1018 ) 1019 ); 1020 fontPanel.setBorder(BorderFactory.createTitledBorder("Layer List Properties")); 1021 1022 List<ProjectionImpl> projections = (List<ProjectionImpl>)mappy.getProjectionList(); 1023 final JComboBox projBox = new JComboBox(); 1024 final Map<String, ProjectionImpl> projectionNamesToObjects = new HashMap<>(projections.size()); 1025 1026 Collection<String> projectionNames = new TreeSet<>(Collator.getInstance()); 1027 1028 for (ProjectionImpl projection : projections) { 1029 String name = projection.getName(); 1030 projectionNamesToObjects.put(name, projection); 1031 projectionNames.add(name); 1032 } 1033 1034 GuiUtils.setListData(projBox, projectionNames.toArray()); 1035 Object defaultProj = mappy.getDefaultProjection(); 1036 if (defaultProj != null) { 1037 if (defaultProj instanceof ProjectionImpl) { 1038 projBox.setSelectedItem(((ProjectionImpl)defaultProj).getName()); 1039 } else { 1040 projBox.setSelectedItem(defaultProj); 1041 } 1042 } 1043 1044 JPanel projPanel = GuiUtils.left(projBox); 1045 projPanel.setBorder(BorderFactory.createTitledBorder("Default Projection")); 1046 1047 McIDASV mcv = (McIDASV)getIdv(); 1048 1049 // START MCV INQUIRY 2718 changes 1050 // see the comments for the ViewManager.PREF_LOGO_CHANGED field 1051 // as well as Inquiry 2718 for more 1052 boolean logoViz = true; 1053 String logoPath = mcv.getStateManager().getPreferenceOrProperty(ViewManager.PREF_LOGO, Constants.ICON_MCIDASV_DEFAULT); 1054 if (getStore().getKeys().contains(ViewManager.PREF_LOGO_CHANGED)) { 1055 logoViz = mcv.getStateManager().getPreferenceOrProperty( 1056 ViewManager.PREF_LOGO_VISIBILITY, true); 1057// logoPath = mcv.getStateManager().getPreferenceOrProperty(ViewManager.PREF_LOGO, Constants.ICON_MCIDASV_DEFAULT); 1058 } 1059 // END MCV INQUIRY 2718 changes 1060 1061 final JCheckBox logoVizBox = new JCheckBox("Show Logo in View", logoViz); 1062 final JTextField logoField = new JTextField(logoPath); 1063 logoField.setToolTipText("Enter a file or URL"); 1064 1065 JButton browseButton = new JButton("Browse.."); 1066 browseButton.setToolTipText("Choose a logo from disk"); 1067 browseButton.addActionListener(new ActionListener() { 1068 public void actionPerformed(ActionEvent ae) { 1069 String filename = FileManager.getReadFile(FileManager.FILTER_IMAGE); 1070 if (filename == null) { 1071 return; 1072 } 1073 logoField.setText(filename); 1074 } 1075 }); 1076 1077 // TJJ Jan 2018 - reworking Logo panel layout 1078 // http://mcidas.ssec.wisc.edu/inquiry-v/?inquiry=1933 1079 1080 JPanel logoPanel = new JPanel(); 1081 logoPanel.setLayout(new BoxLayout(logoPanel, BoxLayout.PAGE_AXIS)); 1082 String[] logos = ViewManager.parseLogoPosition( 1083 mcv.getStateManager().getPreferenceOrProperty( 1084 ViewManager.PREF_LOGO_POSITION_OFFSET, "")); 1085 final JComboBox logoPosBox = new JComboBox(ViewManager.logoPoses); 1086 logoPosBox.setToolTipText("Set the logo position on the screen"); 1087 logoPosBox.setSelectedItem(ViewManager.findLoc(logos[0])); 1088 1089 final JTextField logoOffsetField = new JTextField(logos[1]); 1090 // provide enough space for 8 characters 1091 logoOffsetField.setColumns(8); 1092 logoOffsetField.setToolTipText("Set an offset from the position (x,y)"); 1093 1094 JPanel logoScalePanel = new JPanel(new FlowLayout()); 1095 float scaleMin = LOGO_SCALE_MIN; 1096 float scaleMax = LOGO_SCALE_MAX; 1097 float logoScaleFactor = 1098 (float) mcv.getStateManager().getPreferenceOrProperty(ViewManager.PREF_LOGO_SCALE, 1.0); 1099 final JSlider logoScaleSlider = new JSlider(1, 20, 1); 1100 final JTextField logoSizeTextField = new JTextField("" + logoScaleFactor); 1101 // Legal values will never be more than three characters, e.g. 1.5 1102 logoSizeTextField.setColumns(3); 1103 ActionListener logoListener = new ActionListener() { 1104 1105 @Override 1106 public void actionPerformed(ActionEvent e) { 1107 try { 1108 float val = Float.parseFloat(logoSizeTextField.getText()); 1109 if ((val >= scaleMin) && (val <= scaleMax)) { 1110 logoScaleSlider.setValue((int) (val * 10)); 1111 } else { 1112 JOptionPane.showMessageDialog(null, "Value provided is not a floating point number within valid range (0.1 to 2.0)"); 1113 } 1114 } catch (NumberFormatException nfe) { 1115 JOptionPane.showMessageDialog(null, "Value provided is not a floating point number within valid range (0.1 to 2.0)"); 1116 } 1117 } 1118 1119 }; 1120 logoSizeTextField.addActionListener(logoListener); 1121 1122 logoScaleSlider.setMinorTickSpacing(1); 1123 logoScaleSlider.setPaintTicks(true); 1124 1125 // TJJ Jan 2018 - create custom labels since we want float values for scale multiplier 1126 Hashtable<Integer, JLabel> labelTable = new Hashtable<Integer, JLabel>(); 1127 labelTable.put(1, new JLabel("0.1")); 1128 labelTable.put(5, new JLabel("0.5")); 1129 labelTable.put(10, new JLabel("1.0")); 1130 labelTable.put(15, new JLabel("1.5")); 1131 labelTable.put(20, new JLabel("2.0")); 1132 logoScaleSlider.setLabelTable(labelTable); 1133 logoScaleSlider.setPaintLabels(true); 1134 logoScaleSlider.setValue((int) (logoScaleFactor * 10)); 1135 ChangeListener listener = new ChangeListener() { 1136 public void stateChanged(ChangeEvent e) { 1137 logoSizeTextField.setText("" + logoScaleSlider.getValue() / 10.f); 1138 } 1139 }; 1140 logoScaleSlider.addChangeListener(listener); 1141 logoScaleSlider.setToolTipText("Change Logo Scale Value"); 1142 1143 logoScalePanel.add(logoSizeTextField); 1144 logoScalePanel.add(logoScaleSlider); 1145 1146 JPanel logoTop = new JPanel(new FlowLayout(FlowLayout.LEFT)); 1147 logoTop.add(logoVizBox); 1148 1149 JPanel logoMiddle = new JPanel(new BorderLayout()); 1150 logoMiddle.add(logoField, BorderLayout.CENTER); 1151 logoMiddle.add(browseButton, BorderLayout.LINE_END); 1152 1153 JPanel logoBottomOne = new JPanel(new FlowLayout(FlowLayout.LEFT)); 1154 logoBottomOne.add(new JLabel("Screen Position:")); 1155 logoBottomOne.add(logoPosBox); 1156 logoBottomOne.add(new JLabel("Offset:")); 1157 logoBottomOne.add(logoOffsetField); 1158 JPanel logoBottomTwo = new JPanel(new FlowLayout(FlowLayout.LEFT)); 1159 logoBottomTwo.add(new JLabel("Scale:")); 1160 logoBottomTwo.add(logoScalePanel); 1161 1162 logoPanel.add(logoTop); 1163 logoPanel.add(logoMiddle); 1164 logoPanel.add(logoBottomOne); 1165 logoPanel.add(logoBottomTwo); 1166 1167 logoPanel.setBorder(BorderFactory.createTitledBorder("Logo")); 1168 1169 JPanel outerPanel = new JPanel(); 1170 1171 // Outer panel layout 1172 GroupLayout layout = new GroupLayout(outerPanel); 1173 outerPanel.setLayout(layout); 1174 layout.setHorizontalGroup( 1175 layout.createParallelGroup(LEADING) 1176 .addGroup(layout.createSequentialGroup() 1177 .addContainerGap() 1178 .addGroup(layout.createParallelGroup(LEADING) 1179 .addComponent(navigationPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1180 .addComponent(panelPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1181 .addGap(GAP_RELATED) 1182 .addGroup(layout.createParallelGroup(LEADING) 1183 .addComponent(colorPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1184 .addComponent(legendPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1185 .addComponent(fontPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1186 .addComponent(logoPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1187 .addComponent(projPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1188 .addContainerGap()) 1189 ); 1190 layout.setVerticalGroup( 1191 layout.createParallelGroup(LEADING) 1192 .addGroup(layout.createSequentialGroup() 1193 .addContainerGap() 1194 .addGroup(layout.createParallelGroup(LEADING, false) 1195 .addComponent(navigationPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1196 .addComponent(legendPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1197 .addPreferredGap(RELATED) 1198 .addGroup(layout.createParallelGroup(LEADING, false) 1199 .addGroup(layout.createSequentialGroup() 1200 .addComponent(colorPanel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 1201 .addPreferredGap(RELATED) 1202 .addComponent(fontPanel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 1203 .addPreferredGap(RELATED) 1204 .addComponent(logoPanel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 1205 .addPreferredGap(RELATED) 1206 .addComponent(projPanel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE)) 1207 .addComponent(panelPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1208 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 1209 ); 1210 1211 PreferenceManager miscManager = new PreferenceManager() { 1212 // applyWidgets called the same way the IDV does it. 1213 public void applyPreference(XmlObjectStore theStore, Object data) { 1214 savePrefsFromWidgets((Hashtable)data, theStore); 1215 1216 // START MCV INQUIRY 2718 changes 1217 // see the comments for the ViewManager.PREF_LOGO_CHANGED field 1218 // as well as Inquiry 2718 for more 1219 theStore.put(ViewManager.PREF_LOGO_CHANGED, true); 1220 // END MCV INQUIRY 2718 changes 1221 1222 Object projBoxSelection = projBox.getSelectedItem(); 1223 if (projBoxSelection instanceof String) { 1224 String projName = (String)projBoxSelection; 1225 ProjectionImpl proj = projectionNamesToObjects.get(projName); 1226 theStore.put(MapViewManager.PREF_PROJ_DFLT, proj); 1227 } else { 1228 theStore.put(MapViewManager.PREF_PROJ_DFLT, projBoxSelection); 1229 } 1230 1231 theStore.put(MapViewManager.PREF_BGCOLOR, bgComps[0].getBackground()); 1232 theStore.put(MapViewManager.PREF_FGCOLOR, fgComps[0].getBackground()); 1233 theStore.put(MapViewManager.PREF_BORDERCOLOR, border[0].getBackground()); 1234 theStore.put(MapViewManager.PREF_DISPLAYLISTFONT, fontSelector.getFont()); 1235 theStore.put(MapViewManager.PREF_LOGO, logoField.getText()); 1236 String lpos = 1237 ((TwoFacedObject) logoPosBox.getSelectedItem()).getId() 1238 .toString(); 1239 String loff = logoOffsetField.getText().trim(); 1240 theStore.put(MapViewManager.PREF_LOGO_POSITION_OFFSET, 1241 ViewManager.makeLogoPosition(lpos, loff)); 1242 theStore.put(MapViewManager.PREF_LOGO_VISIBILITY, logoVizBox.isSelected()); 1243 theStore.put(MapViewManager.PREF_LOGO_SCALE, 1244 logoScaleSlider.getValue() / 10f); 1245 theStore.put(MapViewManager.PREF_DISPLAYLISTCOLOR, dlColorWidget.getSwatchColor()); 1246 theStore.put(MapViewManager.PREF_GLOBEBACKGROUND, globeBg[0].getBackground()); 1247// theStore.put(MapViewManager.PREF_USE_PROGRESSIVE_RESOLUTION, ) 1248 ViewManager.setHighlightBorder(border[0].getBackground()); 1249 EventBus.publish("McvPreference.ProgRez", theStore.get(MapViewManager.PREF_USE_PROGRESSIVE_RESOLUTION, false)); 1250 } 1251 }; 1252 1253 this.add(Constants.PREF_LIST_VIEW, "Display Window Preferences", miscManager, outerPanel, widgets); 1254 } 1255 1256 private static void savePrefsFromWidgets(Hashtable widgets, XmlObjectStore store) { 1257 IdvPreferenceManager.applyWidgets(widgets, store); 1258 for (Enumeration keys = widgets.keys(); keys.hasMoreElements(); ) { 1259 String key = (String) keys.nextElement(); 1260 Object widget = widgets.get(key); 1261 if (MapViewManager.PREF_USE_PROGRESSIVE_RESOLUTION.equals(key)) { 1262 store.put(key, ((JCheckBox)widget).isSelected()); 1263 } 1264 } 1265 } 1266 1267 /** 1268 * Creates and adds the basic preference panel. 1269 */ 1270 protected void addMcVPreferences() { 1271 1272 Hashtable<String, Component> widgets = new Hashtable<String, Component>(); 1273 McIDASV mcv = (McIDASV)getIdv(); 1274 StateManager sm = (edu.wisc.ssec.mcidasv.StateManager)mcv.getStateManager(); 1275 1276 PreferenceManager basicManager = new PreferenceManager() { 1277 // IDV-style call to applyWidgets. 1278 public void applyPreference(XmlObjectStore theStore, Object data) { 1279 applyWidgets((Hashtable)data, theStore); 1280 getIdv().getIdvUIManager().setDateFormat(); 1281 getIdv().getIdvUIManager().favoriteBundlesChanged(); 1282 getIdv().initCacheManager(); 1283 applyEventPreferences(theStore); 1284 } 1285 }; 1286 1287 boolean isPrerelease = sm.getIsPrerelease(); 1288 Object[][] generalObjects = { 1289 { "Show McIDAS-V system bundles", PREF_SHOW_SYSTEM_BUNDLES, Boolean.TRUE }, 1290 { "Show Help Tips on start", HelpTipDialog.PREF_HELPTIPSHOW }, 1291 { "Show Data Explorer on start", PREF_SHOWDASHBOARD, Boolean.TRUE }, 1292 { "Check for new version and notice on start", Constants.PREF_VERSION_CHECK, Boolean.TRUE }, 1293 { "Include prereleases in version check", Constants.PREF_PRERELEASE_CHECK, isPrerelease }, 1294 { "Confirm before exiting", PREF_SHOWQUITCONFIRM }, 1295 { "Automatically save default layout at exit", Constants.PREF_AUTO_SAVE_DEFAULT_LAYOUT, Boolean.FALSE }, 1296 { "Save visibility of Data Explorer", Constants.PREF_SAVE_DASHBOARD_VIZ, Boolean.FALSE }, 1297 { "Confirm removal of all data sources", PREF_CONFIRM_REMOVE_DATA, Boolean.TRUE }, 1298 { "Confirm removal of all layers", PREF_CONFIRM_REMOVE_LAYERS, Boolean.TRUE }, 1299 { "Confirm removal of all layers and data sources", PREF_CONFIRM_REMOVE_BOTH, Boolean.TRUE }, 1300 }; 1301 final IdvObjectStore store = getStore(); 1302 JPanel generalPanel = makePrefPanel(generalObjects, widgets, store); 1303 generalPanel.setBorder(BorderFactory.createTitledBorder("General")); 1304 1305 // Turn what used to be a set of checkboxes into a corresponding menu selection 1306 // The options have to be checkboxes in the widget collection 1307 // That way "applyWidgets" will work as expected 1308 boolean shouldRemove = store.get(PREF_OPEN_REMOVE, false); 1309 boolean shouldMerge = store.get(PREF_OPEN_MERGE, false); 1310 final JCheckBox shouldRemoveCbx = new JCheckBox("You shouldn't see this", shouldRemove); 1311 final JCheckBox shouldMergeCbx = new JCheckBox("You shouldn't see this", shouldMerge); 1312 widgets.put(PREF_OPEN_REMOVE, shouldRemoveCbx); 1313 widgets.put(PREF_OPEN_MERGE, shouldMergeCbx); 1314 1315 final JComboBox loadComboBox = new JComboBox(loadComboOptions); 1316 loadComboBox.addActionListener(new ActionListener() { 1317 public void actionPerformed(ActionEvent e) { 1318 switch (((JComboBox)e.getSource()).getSelectedIndex()) { 1319 case 0: 1320 shouldRemoveCbx.setSelected(false); 1321 shouldMergeCbx.setSelected(false); 1322 break; 1323 case 1: 1324 shouldRemoveCbx.setSelected(true); 1325 shouldMergeCbx.setSelected(false); 1326 break; 1327 case 2: 1328 shouldRemoveCbx.setSelected(false); 1329 shouldMergeCbx.setSelected(true); 1330 break; 1331 case 3: 1332 shouldRemoveCbx.setSelected(true); 1333 shouldMergeCbx.setSelected(true); 1334 break; 1335 } 1336 } 1337 }); 1338 1339 // update the bundle loading options upon visibility changes. 1340 loadComboBox.addPropertyChangeListener(new PropertyChangeListener() { 1341 public void propertyChange(final PropertyChangeEvent e) { 1342 String prop = e.getPropertyName(); 1343 if (!"ancestor".equals(prop) && !"Frame.active".equals(prop)) { 1344 return; 1345 } 1346 1347 boolean remove = store.get(PREF_OPEN_REMOVE, false); 1348 boolean merge = store.get(PREF_OPEN_MERGE, false); 1349 1350 if (!remove) { 1351 if (!merge) { 1352 loadComboBox.setSelectedIndex(0); 1353 } else { 1354 loadComboBox.setSelectedIndex(2); 1355 } 1356 } 1357 else { 1358 if (!merge) { 1359 loadComboBox.setSelectedIndex(1); 1360 } else { 1361 loadComboBox.setSelectedIndex(3); 1362 } 1363 } 1364 } 1365 }); 1366 1367 if (!shouldRemove) { 1368 if (!shouldMerge) { 1369 loadComboBox.setSelectedIndex(0); 1370 } else { 1371 loadComboBox.setSelectedIndex(2); 1372 } 1373 } 1374 else { 1375 if (!shouldMerge) { 1376 loadComboBox.setSelectedIndex(1); 1377 } else { 1378 loadComboBox.setSelectedIndex(3); 1379 } 1380 } 1381 1382 Object[][] bundleObjects = { 1383 { "Prompt when opening bundles", PREF_OPEN_ASK }, 1384 { "Prompt for location for zipped data", PREF_ZIDV_ASK } 1385 }; 1386 JPanel bundlePanelInner = makePrefPanel(bundleObjects, widgets, getStore()); 1387 JPanel bundlePanel = GuiUtils.topCenter(loadComboBox, bundlePanelInner); 1388 bundlePanel.setBorder(BorderFactory.createTitledBorder("When Opening a Bundle")); 1389 1390 Object[][] layerObjects = { 1391 { "Show windows when they are created", PREF_SHOWCONTROLWINDOW }, 1392 { "Use fast rendering", PREF_FAST_RENDER, Boolean.FALSE, "<html>Turn this on for better performance at the risk of having funky displays</html>" }, 1393 { "Auto-select data when loading a template", IdvConstants.PREF_AUTOSELECTDATA, Boolean.FALSE, "<html>When loading a display template should the data be automatically selected</html>" }, 1394 }; 1395 JPanel layerPanel = makePrefPanel(layerObjects, widgets, getStore()); 1396 layerPanel.setBorder(BorderFactory.createTitledBorder("Layer Controls")); 1397 1398 Object[][] layerclosedObjects = { 1399 { "Remove the display", DisplayControl.PREF_REMOVEONWINDOWCLOSE, Boolean.FALSE }, 1400 { "Remove standalone displays", DisplayControl.PREF_STANDALONE_REMOVEONCLOSE, Boolean.FALSE } 1401 }; 1402 JPanel layerclosedPanel = makePrefPanel(layerclosedObjects, widgets, getStore()); 1403 layerclosedPanel.setBorder(BorderFactory.createTitledBorder("When Layer Control Window is Closed")); 1404 1405 JPanel outerPanel = new JPanel(); 1406 1407 // Outer panel layout 1408 GroupLayout layout = new GroupLayout(outerPanel); 1409 outerPanel.setLayout(layout); 1410 layout.setHorizontalGroup( 1411 layout.createParallelGroup(LEADING) 1412 .addGroup(layout.createSequentialGroup() 1413 .addContainerGap() 1414 .addGroup(layout.createParallelGroup(TRAILING) 1415 .addComponent(generalPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1416 .addComponent(layerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1417 .addGap(GAP_RELATED) 1418 .addGroup(layout.createParallelGroup(LEADING) 1419 .addComponent(bundlePanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1420 .addComponent(layerclosedPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1421 .addContainerGap()) 1422 ); 1423 layout.setVerticalGroup( 1424 layout.createParallelGroup(LEADING) 1425 .addGroup(layout.createSequentialGroup() 1426 .addContainerGap() 1427 .addGroup(layout.createParallelGroup(LEADING, false) 1428 .addComponent(bundlePanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1429 .addComponent(generalPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1430 .addPreferredGap(RELATED) 1431 .addGroup(layout.createParallelGroup(LEADING, false) 1432 .addComponent(layerclosedPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1433 .addComponent(layerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1434 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 1435 ); 1436 this.add(Constants.PREF_LIST_GENERAL, "General Preferences", basicManager, outerPanel, widgets); 1437 } 1438 1439 /** 1440 * <p>This determines whether the IDV should do a remove display and data 1441 * before a bundle is loaded. It returns a 2 element boolean array. The 1442 * first element is whether the open should take place at all. The second 1443 * element determines whether displays and data should be removed before 1444 * the load.</p> 1445 * 1446 * <p>Overridden by McIDAS-V so that we can ask the user whether or not we 1447 * should limit the number of new windows a bundle can create.</p> 1448 * 1449 * @param name Bundle name - may be null. 1450 * 1451 * @return Element 0: did user hit cancel; Element 1: Should remove data 1452 * and displays; Element 2: limit new windows. 1453 * 1454 * @see IdvPreferenceManager#getDoRemoveBeforeOpening(String) 1455 */ 1456 @Override public boolean[] getDoRemoveBeforeOpening(String name) { 1457 IdvObjectStore store = getStore(); 1458 boolean shouldAsk = store.get(PREF_OPEN_ASK, true); 1459 boolean shouldRemove = store.get(PREF_OPEN_REMOVE, false); 1460 boolean shouldMerge = store.get(PREF_OPEN_MERGE, false); 1461 1462 if (shouldAsk) { 1463 JComboBox loadComboBox = new JComboBox(loadComboOptions); 1464 JCheckBox preferenceCbx = new JCheckBox("Save as default preference", true); 1465 JCheckBox askCbx = new JCheckBox("Don't show this window again", false); 1466 1467 if (!shouldRemove) { 1468 if (!shouldMerge) { 1469 loadComboBox.setSelectedIndex(0); 1470 } else { 1471 loadComboBox.setSelectedIndex(2); 1472 } 1473 } 1474 else { 1475 if (!shouldMerge) { 1476 loadComboBox.setSelectedIndex(1); 1477 } else { 1478 loadComboBox.setSelectedIndex(3); 1479 } 1480 } 1481 1482 JPanel inner = new JPanel(); 1483 GroupLayout layout = new GroupLayout(inner); 1484 inner.setLayout(layout); 1485 layout.setHorizontalGroup( 1486 layout.createParallelGroup(LEADING) 1487 .addGroup(layout.createSequentialGroup() 1488 .addContainerGap() 1489 .addGroup(layout.createParallelGroup(LEADING) 1490 .addComponent(loadComboBox, PREFERRED_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1491 .addComponent(preferenceCbx) 1492 .addComponent(askCbx)) 1493 .addContainerGap()) 1494 ); 1495 layout.setVerticalGroup( 1496 layout.createParallelGroup(LEADING) 1497 .addGroup(layout.createSequentialGroup() 1498 .addContainerGap() 1499 .addComponent(loadComboBox, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 1500 .addPreferredGap(RELATED) 1501 .addComponent(preferenceCbx) 1502 .addPreferredGap(RELATED) 1503 .addComponent(askCbx) 1504 .addContainerGap()) 1505 ); 1506 1507 if (!GuiUtils.showOkCancelDialog(null, "Open bundle", inner, null)) { 1508 return new boolean[] { false, false, false }; 1509 } 1510 1511 switch (loadComboBox.getSelectedIndex()) { 1512 case 0: // new windows 1513 shouldRemove = false; 1514 shouldMerge = false; 1515 break; 1516 case 1: // merge with existing tabs 1517 shouldRemove = true; 1518 shouldMerge = false; 1519 break; 1520 case 2: // add new tab(s) to current 1521 shouldRemove = false; 1522 shouldMerge = true; 1523 break; 1524 case 3: // replace session 1525 shouldRemove = true; 1526 shouldMerge = true; 1527 break; 1528 } 1529 1530 // Save these as default preference if the user wants to 1531 if (preferenceCbx.isSelected()) { 1532 store.put(PREF_OPEN_REMOVE, shouldRemove); 1533 store.put(PREF_OPEN_MERGE, shouldMerge); 1534 } 1535 store.put(PREF_OPEN_ASK, !askCbx.isSelected()); 1536 } 1537 return new boolean[] { true, shouldRemove, shouldMerge }; 1538 } 1539 1540 /** 1541 * Creates and adds the formats and data preference panel. 1542 */ 1543 protected void addFormatDataPreferences() { 1544 Hashtable<String, Component> widgets = new Hashtable<String, Component>(); 1545 1546 JPanel formatPanel = new JPanel(); 1547 formatPanel.setBorder(BorderFactory.createTitledBorder("Formats")); 1548 1549 // Date stuff 1550 JLabel dateLabel = McVGuiUtils.makeLabelRight("Date Format:", Width.ONEHALF); 1551 1552 String dateFormat = getStore().get(PREF_DATE_FORMAT, DEFAULT_DATE_FORMAT); 1553 1554 if (!dateFormats.contains(dateFormat)) { 1555 dateFormats.add(dateFormat); 1556 } 1557 1558 final JComboBox dateComboBox = McVGuiUtils.makeComboBox(dateFormats, dateFormat, Width.TRIPLE); 1559 widgets.put(PREF_DATE_FORMAT, dateComboBox); 1560 1561 JComponent dateHelpButton = getIdv().makeHelpButton("idv.tools.preferences.dateformat"); 1562 1563 JLabel dateExLabel = new JLabel(""); 1564 1565 // Time stuff 1566 JLabel timeLabel = McVGuiUtils.makeLabelRight("Time Zone:", Width.ONEHALF); 1567 1568 String timeString = getStore().get(PREF_TIMEZONE, DEFAULT_TIMEZONE); 1569 String[] zoneStrings = TimeZone.getAvailableIDs(); 1570 Arrays.sort(zoneStrings); 1571 1572 final JComboBox timeComboBox = McVGuiUtils.makeComboBox(zoneStrings, timeString, Width.TRIPLE); 1573 widgets.put(PREF_TIMEZONE, timeComboBox); 1574 1575 try { 1576 dateExLabel.setText("ex: " + new DateTime().toString()); 1577 } catch (Exception ve) { 1578 dateExLabel.setText("Can't format date: " + ve); 1579 } 1580 1581 ObjectListener timeLabelListener = new ObjectListener(dateExLabel) { 1582 public void actionPerformed(ActionEvent ae) { 1583 JLabel label = (JLabel) theObject; 1584 String format = dateComboBox.getSelectedItem().toString(); 1585 String zone = timeComboBox.getSelectedItem().toString(); 1586 try { 1587 TimeZone tz = TimeZone.getTimeZone(zone); 1588 // hack to make it the DateTime default 1589 if (format.equals(DEFAULT_DATE_FORMAT)) { 1590 if (zone.equals(DEFAULT_TIMEZONE)) { 1591 format = DateTime.DEFAULT_TIME_FORMAT + "'Z'"; 1592 } 1593 } 1594 label.setText("ex: " + new DateTime().formattedString(format, tz)); 1595 } catch (Exception ve) { 1596 label.setText("Invalid format or time zone"); 1597 LogUtil.userMessage("Invalid format or time zone"); 1598 } 1599 } 1600 }; 1601 dateComboBox.addActionListener(timeLabelListener); 1602 timeComboBox.addActionListener(timeLabelListener); 1603 1604 // Lat/Lon stuff 1605 JLabel latlonLabel = McVGuiUtils.makeLabelRight("Lat/Lon Format:", Width.ONEHALF); 1606 1607 String latlonFormatString = getStore().get(PREF_LATLON_FORMAT, "##0.0"); 1608 JComboBox latlonComboBox = McVGuiUtils.makeComboBox(defaultLatLonFormats, latlonFormatString, Width.TRIPLE); 1609 widgets.put(PREF_LATLON_FORMAT, latlonComboBox); 1610 1611 JComponent latlonHelpButton = getIdv().makeHelpButton("idv.tools.preferences.latlonformat"); 1612 1613 JLabel latlonExLabel = new JLabel(""); 1614 1615 try { 1616 latlonFormat.applyPattern(latlonFormatString); 1617 latlonExLabel.setText("ex: " + latlonFormat.format(latlonValue)); 1618 } catch (IllegalArgumentException iae) { 1619 latlonExLabel.setText("Bad format: " + latlonFormatString); 1620 } 1621 latlonComboBox.addActionListener(new ObjectListener(latlonExLabel) { 1622 public void actionPerformed(final ActionEvent ae) { 1623 JLabel label = (JLabel)theObject; 1624 JComboBox box = (JComboBox)ae.getSource(); 1625 String pattern = box.getSelectedItem().toString(); 1626 try { 1627 latlonFormat.applyPattern(pattern); 1628 label.setText("ex: " + latlonFormat.format(latlonValue)); 1629 } catch (IllegalArgumentException iae) { 1630 label.setText("bad pattern: " + pattern); 1631 LogUtil.userMessage("Bad format:" + pattern); 1632 } 1633 } 1634 }); 1635 1636 // Probe stuff 1637 JLabel probeLabel = McVGuiUtils.makeLabelRight("Probe Format:", Width.ONEHALF); 1638 1639 String probeFormat = getStore().get(DisplayControl.PREF_PROBEFORMAT, DisplayControl.DEFAULT_PROBEFORMAT); 1640 1641 JComboBox probeComboBox = McVGuiUtils.makeComboBox(probeFormatsList, probeFormat, Width.TRIPLE); 1642 widgets.put(DisplayControl.PREF_PROBEFORMAT, probeComboBox); 1643 1644 JComponent probeHelpButton = getIdv().makeHelpButton("idv.tools.preferences.probeformat"); 1645 1646 // Distance stuff 1647 JLabel distanceLabel = McVGuiUtils.makeLabelRight("Distance Unit:", Width.ONEHALF); 1648 1649 Unit distanceUnit = null; 1650 try { 1651 distanceUnit = ucar.visad.Util.parseUnit(getStore().get(PREF_DISTANCEUNIT, "km")); 1652 } catch (Exception exc) {} 1653 JComboBox distanceComboBox = getIdv().getDisplayConventions().makeUnitBox(distanceUnit, null); 1654 McVGuiUtils.setComponentWidth(distanceComboBox, Width.TRIPLE); 1655 widgets.put(PREF_DISTANCEUNIT, distanceComboBox); 1656 1657 // Locale stuff (largely ripped out of IDV prefs) 1658 JLabel localeLabel = McVGuiUtils.makeLabelRight("Number Style:", Width.ONEHALF); 1659 String defaultLocale = getStore().get(PREF_LOCALE, "SYSTEM_LOCALE"); 1660 JRadioButton sysLocale = new JRadioButton("System Default", 1661 defaultLocale.equals("SYSTEM_LOCALE")); 1662 1663 sysLocale.setToolTipText( 1664 "Use the system default locale for number formatting"); 1665 1666 JRadioButton usLocale = new JRadioButton("English/US", 1667 !defaultLocale.equals("SYSTEM_LOCALE")); 1668 1669 usLocale.setToolTipText("Use the US number formatting"); 1670 GuiUtils.buttonGroup(sysLocale, usLocale); 1671 widgets.put("SYSTEM_LOCALE", sysLocale); 1672 widgets.put("US_LOCALE", usLocale); 1673 1674 // Format panel layout 1675 GroupLayout formatLayout = new GroupLayout(formatPanel); 1676 formatPanel.setLayout(formatLayout); 1677 formatLayout.setHorizontalGroup( 1678 formatLayout.createParallelGroup(LEADING) 1679 .addGroup(formatLayout.createSequentialGroup() 1680 .addContainerGap() 1681 .addGroup(formatLayout.createParallelGroup(LEADING) 1682 .addGroup(formatLayout.createSequentialGroup() 1683 .addComponent(dateLabel) 1684 .addGap(GAP_RELATED) 1685 .addComponent(dateComboBox) 1686 .addGap(GAP_RELATED) 1687 .addComponent(dateHelpButton) 1688 .addGap(GAP_RELATED) 1689 .addComponent(dateExLabel)) 1690 .addGroup(formatLayout.createSequentialGroup() 1691 .addComponent(timeLabel) 1692 .addGap(GAP_RELATED) 1693 .addComponent(timeComboBox)) 1694 .addGroup(formatLayout.createSequentialGroup() 1695 .addComponent(latlonLabel) 1696 .addGap(GAP_RELATED) 1697 .addComponent(latlonComboBox) 1698 .addGap(GAP_RELATED) 1699 .addComponent(latlonHelpButton) 1700 .addGap(GAP_RELATED) 1701 .addComponent(latlonExLabel)) 1702 .addGroup(formatLayout.createSequentialGroup() 1703 .addComponent(probeLabel) 1704 .addGap(GAP_RELATED) 1705 .addComponent(probeComboBox) 1706 .addGap(GAP_RELATED) 1707 .addComponent(probeHelpButton)) 1708 .addGroup(formatLayout.createSequentialGroup() 1709 .addComponent(distanceLabel) 1710 .addGap(GAP_RELATED) 1711 .addComponent(distanceComboBox)) 1712 .addGroup(formatLayout.createSequentialGroup() 1713 .addComponent(localeLabel) 1714 .addGap(GAP_RELATED) 1715 .addComponent(sysLocale) 1716 .addGap(GAP_RELATED) 1717 .addComponent(usLocale))) 1718 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 1719 ); 1720 formatLayout.setVerticalGroup( 1721 formatLayout.createParallelGroup(LEADING) 1722 .addGroup(formatLayout.createSequentialGroup() 1723 .addGroup(formatLayout.createParallelGroup(BASELINE) 1724 .addComponent(dateComboBox) 1725 .addComponent(dateLabel) 1726 .addComponent(dateHelpButton) 1727 .addComponent(dateExLabel)) 1728 .addPreferredGap(RELATED) 1729 .addGroup(formatLayout.createParallelGroup(BASELINE) 1730 .addComponent(timeComboBox) 1731 .addComponent(timeLabel)) 1732 .addPreferredGap(RELATED) 1733 .addGroup(formatLayout.createParallelGroup(BASELINE) 1734 .addComponent(latlonLabel) 1735 .addComponent(latlonComboBox) 1736 .addComponent(latlonHelpButton) 1737 .addComponent(latlonExLabel)) 1738 .addPreferredGap(RELATED) 1739 .addGroup(formatLayout.createParallelGroup(BASELINE) 1740 .addComponent(probeComboBox) 1741 .addComponent(probeLabel) 1742 .addComponent(probeHelpButton)) 1743 .addPreferredGap(RELATED) 1744 .addGroup(formatLayout.createParallelGroup(BASELINE) 1745 .addComponent(distanceComboBox) 1746 .addComponent(distanceLabel)) 1747 .addPreferredGap(RELATED) 1748 .addGroup(formatLayout.createParallelGroup(BASELINE) 1749 .addComponent(localeLabel) 1750 .addComponent(sysLocale) 1751 .addComponent(usLocale)) 1752 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 1753 ); 1754 1755 JPanel dataPanel = new JPanel(); 1756 dataPanel.setBorder(BorderFactory.createTitledBorder("Data")); 1757 1758 // Sampling stuff 1759 JLabel sampleLabel = McVGuiUtils.makeLabelRight("Sampling Mode:", Width.ONEHALF); 1760 1761 String sampleValue = getStore().get(PREF_SAMPLINGMODE, DisplayControlImpl.WEIGHTED_AVERAGE); 1762 JRadioButton sampleWA = new JRadioButton(DisplayControlImpl.WEIGHTED_AVERAGE, 1763 sampleValue.equals(DisplayControlImpl.WEIGHTED_AVERAGE)); 1764 1765 sampleWA.setToolTipText("Use a weighted average sampling"); 1766 JRadioButton sampleNN = new JRadioButton(DisplayControlImpl.NEAREST_NEIGHBOR, 1767 sampleValue.equals(DisplayControlImpl.NEAREST_NEIGHBOR)); 1768 1769 sampleNN.setToolTipText("Use a nearest neighbor sampling"); 1770 GuiUtils.buttonGroup(sampleWA, sampleNN); 1771 widgets.put("WEIGHTED_AVERAGE", sampleWA); 1772 widgets.put("NEAREST_NEIGHBOR", sampleNN); 1773 1774 // Pressure stuff 1775 JLabel verticalLabel = McVGuiUtils.makeLabelRight("Pressure to Height:", Width.ONEHALF); 1776 1777 String verticalValue = getStore().get(PREF_VERTICALCS, DataUtil.STD_ATMOSPHERE); 1778 JRadioButton verticalSA = new JRadioButton("Standard Atmosphere", verticalValue.equals(DataUtil.STD_ATMOSPHERE)); 1779 verticalSA.setToolTipText("Use a standard atmosphere height approximation"); 1780 JRadioButton verticalV5D = new JRadioButton("Vis5D", verticalValue.equals(DataUtil.VIS5D_VERTICALCS)); 1781 verticalV5D.setToolTipText("Use the Vis5D vertical transformation"); 1782 GuiUtils.buttonGroup(verticalSA, verticalV5D); 1783 widgets.put(DataUtil.STD_ATMOSPHERE, verticalSA); 1784 widgets.put(DataUtil.VIS5D_VERTICALCS, verticalV5D); 1785 1786 // Caching stuff 1787 JLabel cacheLabel = McVGuiUtils.makeLabelRight("Caching:", Width.ONEHALF); 1788 1789 JCheckBox cacheCheckBox = new JCheckBox("Cache Data in Memory", getStore().get(PREF_DOCACHE, true)); 1790 widgets.put(PREF_DOCACHE, cacheCheckBox); 1791 1792 JLabel cacheEmptyLabel = McVGuiUtils.makeLabelRight("", Width.ONEHALF); 1793 1794 JTextField cacheTextField = McVGuiUtils.makeTextField(Misc.format(getStore().get(PREF_CACHESIZE, 20.0))); 1795 JComponent cacheTextFieldComponent = GuiUtils.hbox(new JLabel("Disk Cache Size: "), cacheTextField, new JLabel(" megabytes")); 1796 widgets.put(PREF_CACHESIZE, cacheTextField); 1797 1798 // Image stuff 1799 JLabel imageLabel = McVGuiUtils.makeLabelRight("Max Image Size:", Width.ONEHALF); 1800 1801 JTextField imageField = McVGuiUtils.makeTextField(Misc.format(getStore().get(PREF_MAXIMAGESIZE, -1))); 1802 JComponent imageFieldComponent = GuiUtils.hbox(imageField, new JLabel(" pixels (-1 = no limit)")); 1803 widgets.put(PREF_MAXIMAGESIZE, imageField); 1804 1805 // Grid stuff 1806 JLabel gridLabel = McVGuiUtils.makeLabelRight("Grid Threshold:", Width.ONEHALF); 1807 1808 JTextField gridField = McVGuiUtils.makeTextField(Misc.format(getStore().get(PREF_FIELD_CACHETHRESHOLD, 1000000.))); 1809 JComponent gridFieldComponent = GuiUtils.hbox(gridField, new JLabel(" bytes (Cache grids larger than this to disk)")); 1810 widgets.put(PREF_FIELD_CACHETHRESHOLD, gridField); 1811 1812 // Data panel layout 1813 GroupLayout dataLayout = new GroupLayout(dataPanel); 1814 dataPanel.setLayout(dataLayout); 1815 dataLayout.setHorizontalGroup( 1816 dataLayout.createParallelGroup(LEADING) 1817 .addGroup(dataLayout.createSequentialGroup() 1818 .addContainerGap() 1819 .addGroup(dataLayout.createParallelGroup(LEADING) 1820 .addGroup(dataLayout.createSequentialGroup() 1821 .addComponent(sampleLabel) 1822 .addGap(GAP_RELATED) 1823 .addComponent(sampleWA) 1824 .addGap(GAP_RELATED) 1825 .addComponent(sampleNN)) 1826 .addGroup(dataLayout.createSequentialGroup() 1827 .addComponent(verticalLabel) 1828 .addGap(GAP_RELATED) 1829 .addComponent(verticalSA) 1830 .addGap(GAP_RELATED) 1831 .addComponent(verticalV5D)) 1832 .addGroup(dataLayout.createSequentialGroup() 1833 .addComponent(cacheLabel) 1834 .addGap(GAP_RELATED) 1835 .addComponent(cacheCheckBox)) 1836 .addGroup(dataLayout.createSequentialGroup() 1837 .addComponent(cacheEmptyLabel) 1838 .addGap(GAP_RELATED) 1839 .addComponent(cacheTextFieldComponent)) 1840 .addGroup(dataLayout.createSequentialGroup() 1841 .addComponent(imageLabel) 1842 .addGap(GAP_RELATED) 1843 .addComponent(imageFieldComponent)) 1844 .addGroup(dataLayout.createSequentialGroup() 1845 .addComponent(gridLabel) 1846 .addGap(GAP_RELATED) 1847 .addComponent(gridFieldComponent))) 1848 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 1849 ); 1850 dataLayout.setVerticalGroup( 1851 dataLayout.createParallelGroup(LEADING) 1852 .addGroup(dataLayout.createSequentialGroup() 1853 .addGroup(dataLayout.createParallelGroup(BASELINE) 1854 .addComponent(sampleLabel) 1855 .addComponent(sampleWA) 1856 .addComponent(sampleNN)) 1857 .addPreferredGap(RELATED) 1858 .addGroup(dataLayout.createParallelGroup(BASELINE) 1859 .addComponent(verticalLabel) 1860 .addComponent(verticalSA) 1861 .addComponent(verticalV5D)) 1862 .addPreferredGap(RELATED) 1863 .addGroup(dataLayout.createParallelGroup(BASELINE) 1864 .addComponent(cacheLabel) 1865 .addComponent(cacheCheckBox)) 1866 .addPreferredGap(RELATED) 1867 .addGroup(dataLayout.createParallelGroup(BASELINE) 1868 .addComponent(cacheEmptyLabel) 1869 .addComponent(cacheTextFieldComponent)) 1870 .addPreferredGap(RELATED) 1871 .addGroup(dataLayout.createParallelGroup(BASELINE) 1872 .addComponent(imageLabel) 1873 .addComponent(imageFieldComponent)) 1874 .addPreferredGap(RELATED) 1875 .addGroup(dataLayout.createParallelGroup(BASELINE) 1876 .addComponent(gridLabel) 1877 .addComponent(gridFieldComponent)) 1878 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 1879 ); 1880 1881 JPanel outerPanel = new JPanel(); 1882 1883 // Outer panel layout 1884 GroupLayout layout = new GroupLayout(outerPanel); 1885 outerPanel.setLayout(layout); 1886 layout.setHorizontalGroup( 1887 layout.createParallelGroup(LEADING) 1888 .addGroup(layout.createSequentialGroup() 1889 .addContainerGap() 1890 .addGroup(layout.createParallelGroup(LEADING) 1891 .addComponent(formatPanel, TRAILING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 1892 .addComponent(dataPanel, TRAILING, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE)) 1893 .addContainerGap()) 1894 ); 1895 layout.setVerticalGroup( 1896 layout.createParallelGroup(LEADING) 1897 .addGroup(layout.createSequentialGroup() 1898 .addContainerGap() 1899 .addComponent(formatPanel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 1900 .addGap(GAP_UNRELATED) 1901 .addComponent(dataPanel, PREFERRED_SIZE, DEFAULT_SIZE, PREFERRED_SIZE) 1902 .addContainerGap(DEFAULT_SIZE, Short.MAX_VALUE)) 1903 ); 1904 1905 PreferenceManager formatsManager = new PreferenceManager() { 1906 public void applyPreference(XmlObjectStore theStore, Object data) { 1907 IdvPreferenceManager.applyWidgets((Hashtable)data, theStore); 1908 1909 // if we ever need to add formats and data prefs, here's where 1910 // they get saved off (unless we override applyWidgets). 1911 } 1912 }; 1913 1914 this.add(Constants.PREF_LIST_FORMATS_DATA, "", formatsManager, outerPanel, widgets); 1915 } 1916 1917 /** 1918 * Add in the user preference tab for the choosers to show. 1919 */ 1920 protected void addChooserPreferences() { 1921 Hashtable<String, JCheckBox> choosersData = new Hashtable<String, JCheckBox>(); 1922 List<JPanel> compList = new ArrayList<JPanel>(); 1923 1924 Boolean choosersAll = 1925 (Boolean) getIdv().getPreference(PROP_CHOOSERS_ALL, Boolean.TRUE); 1926 1927 final List<String[]> choosers = getChooserData(); 1928 1929 final JRadioButton useAllBtn = new JRadioButton("Use all data sources", 1930 choosersAll.booleanValue()); 1931 final JRadioButton useTheseBtn = 1932 new JRadioButton("Use selected data sources:", 1933 !choosersAll.booleanValue()); 1934 1935 GuiUtils.buttonGroup(useAllBtn, useTheseBtn); 1936 1937 final List<CheckboxCategoryPanel> chooserPanels = 1938 new ArrayList<CheckboxCategoryPanel>(); 1939 1940 final Hashtable<String, CheckboxCategoryPanel> chooserMap = 1941 new Hashtable<String, CheckboxCategoryPanel>(); 1942 1943 // create the checkbox + chooser name that'll show up in the preference 1944 // panel. 1945 for (String[] cs : choosers) { 1946 final String chooserCategory = getChooserCategory(cs[1]); 1947 String chooserShortName = getChooserShortName(cs[1]); 1948 1949 CheckboxCategoryPanel chooserPanel = 1950 (CheckboxCategoryPanel) chooserMap.get(chooserCategory); 1951 1952 if (chooserPanel == null) { 1953 chooserPanel = new CheckboxCategoryPanel(chooserCategory, false); 1954 chooserPanels.add(chooserPanel); 1955 chooserMap.put(chooserCategory, chooserPanel); 1956 compList.add(chooserPanel.getTopPanel()); 1957 compList.add(chooserPanel); 1958 } 1959 1960 JCheckBox cbx = new JCheckBox(chooserShortName, shouldShowChooser(cs[0], true)); 1961 choosersData.put(cs[0], cbx); 1962 chooserPanel.addItem(cbx); 1963 chooserPanel.add(GuiUtils.inset(cbx, new Insets(0, 20, 0, 0))); 1964 } 1965 1966 for (CheckboxCategoryPanel cbcp : chooserPanels) { 1967 cbcp.checkVisCbx(); 1968 } 1969 1970 // handle the user opting to enable all choosers. 1971 final JButton allOn = new JButton("All on"); 1972 allOn.addActionListener(new ActionListener() { 1973 public void actionPerformed(ActionEvent ae) { 1974 for (CheckboxCategoryPanel cbcp : chooserPanels) { 1975 cbcp.toggleAll(true); 1976 } 1977 } 1978 }); 1979 1980 // handle the user opting to disable all choosers. 1981 final JButton allOff = new JButton("All off"); 1982 allOff.addActionListener(new ActionListener() { 1983 public void actionPerformed(ActionEvent ae) { 1984 for (CheckboxCategoryPanel cbcp : chooserPanels) { 1985 cbcp.toggleAll(false); 1986 } 1987 } 1988 }); 1989 1990 final JPanel cbPanel = GuiUtils.top(GuiUtils.vbox(compList)); 1991 1992 JScrollPane cbScroller = new JScrollPane(cbPanel); 1993 cbScroller.getVerticalScrollBar().setUnitIncrement(10); 1994 cbScroller.setPreferredSize(new Dimension(300, 300)); 1995 1996 GuiUtils.enableTree(cbPanel, !useAllBtn.isSelected()); 1997 GuiUtils.enableTree(allOn, !useAllBtn.isSelected()); 1998 GuiUtils.enableTree(allOff, !useAllBtn.isSelected()); 1999 2000 JPanel widgetPanel = 2001 GuiUtils.topCenter( 2002 GuiUtils.hbox(useAllBtn, useTheseBtn), 2003 GuiUtils.leftCenter( 2004 GuiUtils.inset( 2005 GuiUtils.top(GuiUtils.vbox(allOn, allOff)), 2006 4), cbScroller)); 2007 JPanel choosersPanel = 2008 GuiUtils.topCenter( 2009 GuiUtils.inset( 2010 new JLabel("Note: This will take effect the next run"), 2011 4), widgetPanel); 2012 choosersPanel = GuiUtils.inset(GuiUtils.left(choosersPanel), 6); 2013 useAllBtn.addActionListener(new ActionListener() { 2014 public void actionPerformed(ActionEvent ae) { 2015 GuiUtils.enableTree(cbPanel, !useAllBtn.isSelected()); 2016 GuiUtils.enableTree(allOn, !useAllBtn.isSelected()); 2017 GuiUtils.enableTree(allOff, !useAllBtn.isSelected()); 2018 2019 } 2020 }); 2021 useTheseBtn.addActionListener(new ActionListener() { 2022 public void actionPerformed(ActionEvent ae) { 2023 GuiUtils.enableTree(cbPanel, !useAllBtn.isSelected()); 2024 GuiUtils.enableTree(allOn, !useAllBtn.isSelected()); 2025 GuiUtils.enableTree(allOff, !useAllBtn.isSelected()); 2026 } 2027 }); 2028 2029 PreferenceManager choosersManager = new PreferenceManager() { 2030 public void applyPreference(XmlObjectStore theStore, Object data) { 2031 2032 Hashtable<String, Boolean> newToShow = new Hashtable<String, Boolean>(); 2033 2034 Hashtable table = (Hashtable)data; 2035 for (Enumeration keys = table.keys(); keys.hasMoreElements(); ) { 2036 String chooserId = (String) keys.nextElement(); 2037 JCheckBox chooserCB = (JCheckBox) table.get(chooserId); 2038 newToShow.put(chooserId, Boolean.valueOf(chooserCB.isSelected())); 2039 } 2040 2041 choosersToShow = newToShow; 2042 theStore.put(PROP_CHOOSERS_ALL, Boolean.valueOf(useAllBtn.isSelected())); 2043 theStore.put(PROP_CHOOSERS, choosersToShow); 2044 } 2045 }; 2046 this.add(Constants.PREF_LIST_DATA_CHOOSERS, 2047 "What data sources should be shown in the user interface?", 2048 choosersManager, choosersPanel, choosersData); 2049 } 2050 2051 /** 2052 * <p>Return a list that contains a bunch of arrays of two strings.</p> 2053 * 2054 * <p>The first item in one of the arrays is the chooser id, and the second 2055 * item is the "name" of the chooser. The name is formed by working through 2056 * choosers.xml and concatenating each panel's category and title.</p> 2057 * 2058 * @return A list of chooser ids and names. 2059 */ 2060 private final List<String[]> getChooserData() { 2061 List<String[]> choosers = new ArrayList<String[]>(); 2062 String tempString; 2063 2064 try { 2065 // get the root element so we can iterate through 2066 final String xml = 2067 IOUtil.readContents(MCV_CHOOSERS, McIdasPreferenceManager.class); 2068 2069 final Element root = XmlUtil.getRoot(xml); 2070 if (root == null) { 2071 return null; 2072 } 2073 // grab all the children, which should be panels. 2074 final NodeList nodeList = XmlUtil.getElements(root); 2075 for (int i = 0; i < nodeList.getLength(); i++) { 2076 2077 final Element item = (Element)nodeList.item(i); 2078 2079 if (item.getTagName().equals(XmlUi.TAG_PANEL) || item.getTagName().equals("chooser")) { 2080 2081 // form the name of the chooser. 2082 final String title = 2083 XmlUtil.getAttribute(item, XmlUi.ATTR_TITLE, ""); 2084 2085 final String cat = 2086 XmlUtil.getAttribute(item, XmlUi.ATTR_CATEGORY, ""); 2087 2088 if (cat.equals("")) { 2089 tempString = title; 2090 } else { 2091 tempString = cat + ">" + title; 2092 } 2093 2094 final NodeList children = XmlUtil.getElements(item); 2095 2096 if (item.getTagName().equals("chooser")) { 2097 final String id = 2098 XmlUtil.getAttribute(item, XmlUi.ATTR_ID, ""); 2099 String[] tmp = {id, tempString}; 2100 choosers.add(tmp); 2101 } 2102 else { 2103 for (int j = 0; j < children.getLength(); j++) { 2104 final Element child = (Element)children.item(j); 2105 2106 // form the id of the chooser and add it to the list. 2107 if (child.getTagName().equals("chooser")) { 2108 final String id = 2109 XmlUtil.getAttribute(child, XmlUi.ATTR_ID, ""); 2110 String[] tmp = {id, tempString}; 2111 choosers.add(tmp); 2112 } 2113 } 2114 } 2115 } 2116 } 2117 } catch (Exception e) { 2118 e.printStackTrace(); 2119 } 2120 return choosers; 2121 } 2122 2123 /** 2124 * Parse the full chooser name for a category. 2125 * 2126 * @param chooserName Name of a chooser. Cannot be {@code null}. 2127 * 2128 * @return {@literal "Category"} associated with {@code chooserName} or 2129 * {@literal "Other"} if no category is available. 2130 */ 2131 private String getChooserCategory(String chooserName) { 2132 String chooserCategory = "Other"; 2133 int indexSep = chooserName.indexOf('>'); 2134 if (indexSep >= 0) { 2135 chooserCategory = chooserName.substring(0, indexSep); 2136 } 2137 return chooserCategory; 2138 } 2139 2140 /** 2141 * Parse the full chooser name for a short name. 2142 * 2143 * @param chooserName Name of a chooser. Cannot be {@code null}. 2144 * 2145 * @return The {@literal "short name"} of {@code chooserName}. 2146 */ 2147 private String getChooserShortName(String chooserName) { 2148 String chooserShortName = chooserName; 2149 int indexSep = chooserName.indexOf('>'); 2150 if (indexSep >= 0 && chooserName.length() > indexSep + 1) { 2151 chooserShortName = 2152 chooserName.substring(indexSep + 1, chooserName.length()); 2153 } 2154 return chooserShortName; 2155 } 2156 2157 public class IconCellRenderer extends DefaultListCellRenderer { 2158 2159 /** 2160 * Extends the default list cell renderer to use icons in addition to 2161 * the typical text. 2162 */ 2163 public Component getListCellRendererComponent(JList list, Object value, 2164 int index, boolean isSelected, boolean cellHasFocus) { 2165 2166 super.getListCellRendererComponent(list, value, index, isSelected, 2167 cellHasFocus); 2168 2169 if (value instanceof JLabel) { 2170 setText(((JLabel)value).getText()); 2171 setIcon(((JLabel)value).getIcon()); 2172 } 2173 2174 return this; 2175 } 2176 2177 /** 2178 * I wear some pretty fancy pants, so you'd better believe that I'm 2179 * going to enable fancy-pants text antialiasing. 2180 * 2181 * @param g The graphics object that we'll use as a base. 2182 */ 2183 protected void paintComponent(Graphics g) { 2184 Graphics2D g2d = (Graphics2D)g; 2185 g2d.setRenderingHints(getRenderingHints()); 2186 super.paintComponent(g2d); 2187 } 2188 } 2189} 2190