001/* 002 * This file is part of McIDAS-V 003 * 004 * Copyright 2007-2016 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.chooser.adde; 030 031import static edu.wisc.ssec.mcidasv.servermanager.EntryTransforms.strToEntryType; 032import static edu.wisc.ssec.mcidasv.servermanager.AddeEntry.DEFAULT_ACCOUNT; 033import static edu.wisc.ssec.mcidasv.util.CollectionHelpers.arrList; 034import static edu.wisc.ssec.mcidasv.McIDASV.isLoopback; 035 036import static javax.swing.GroupLayout.DEFAULT_SIZE; 037import static javax.swing.GroupLayout.Alignment.BASELINE; 038import static javax.swing.GroupLayout.Alignment.LEADING; 039import static javax.swing.GroupLayout.Alignment.TRAILING; 040import static javax.swing.LayoutStyle.ComponentPlacement.RELATED; 041import static javax.swing.LayoutStyle.ComponentPlacement.UNRELATED; 042 043import java.awt.Component; 044import java.awt.event.ActionEvent; 045import java.awt.event.ActionListener; 046import java.awt.event.ItemEvent; 047import java.awt.event.ItemListener; 048import java.awt.event.KeyEvent; 049import java.awt.event.KeyListener; 050import java.awt.event.MouseAdapter; 051import java.awt.event.MouseEvent; 052import java.io.EOFException; 053import java.io.InputStream; 054import java.net.ConnectException; 055import java.net.URL; 056import java.net.URLConnection; 057import java.util.ArrayList; 058import java.util.Arrays; 059import java.util.Collections; 060import java.util.Comparator; 061import java.util.Enumeration; 062import java.util.HashMap; 063import java.util.Hashtable; 064import java.util.LinkedHashMap; 065import java.util.List; 066import java.util.Map; 067import java.util.Objects; 068import java.util.Vector; 069 070import javax.swing.GroupLayout; 071import javax.swing.JButton; 072import javax.swing.JCheckBox; 073import javax.swing.JComboBox; 074import javax.swing.JComponent; 075import javax.swing.JLabel; 076import javax.swing.JMenu; 077import javax.swing.JMenuItem; 078import javax.swing.JPanel; 079import javax.swing.JPopupMenu; 080import javax.swing.JTabbedPane; 081import javax.swing.JTextField; 082import javax.swing.SwingUtilities; 083 084import edu.wisc.ssec.mcidasv.ui.MenuScroller; 085import org.bushe.swing.event.annotation.AnnotationProcessor; 086import org.bushe.swing.event.annotation.EventSubscriber; 087import org.slf4j.Logger; 088import org.slf4j.LoggerFactory; 089import org.w3c.dom.Element; 090 091import edu.wisc.ssec.mcidas.adde.AddeURLException; 092import edu.wisc.ssec.mcidas.adde.DataSetInfo; 093 094import visad.DateTime; 095 096import ucar.unidata.idv.chooser.IdvChooser; 097import ucar.unidata.idv.chooser.IdvChooserManager; 098import ucar.unidata.idv.chooser.adde.AddeServer; 099import ucar.unidata.idv.chooser.adde.AddeServer.Group; 100import ucar.unidata.util.DatedThing; 101import ucar.unidata.util.GuiUtils; 102import ucar.unidata.util.LogUtil; 103import ucar.unidata.util.Misc; 104import ucar.unidata.util.PreferenceList; 105import ucar.unidata.util.StringUtil; 106import ucar.unidata.xml.XmlObjectStore; 107 108import edu.wisc.ssec.mcidasv.Constants; 109import edu.wisc.ssec.mcidasv.McIDASV; 110import edu.wisc.ssec.mcidasv.ParameterSet; 111import edu.wisc.ssec.mcidasv.PersistenceManager; 112import edu.wisc.ssec.mcidasv.servermanager.AddeAccount; 113import edu.wisc.ssec.mcidasv.servermanager.AddeEntry; 114import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EditorAction; 115import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EntrySource; 116import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EntryType; 117import edu.wisc.ssec.mcidasv.servermanager.AddeEntry.EntryValidity; 118import edu.wisc.ssec.mcidasv.servermanager.EntryStore; 119import edu.wisc.ssec.mcidasv.servermanager.EntryTransforms; 120import edu.wisc.ssec.mcidasv.servermanager.LocalEntryEditor; 121import edu.wisc.ssec.mcidasv.servermanager.RemoteAddeEntry; 122import edu.wisc.ssec.mcidasv.servermanager.RemoteEntryEditor; 123import edu.wisc.ssec.mcidasv.servermanager.TabbedAddeManager; 124import edu.wisc.ssec.mcidasv.ui.ParameterTree; 125import edu.wisc.ssec.mcidasv.ui.UIManager; 126import edu.wisc.ssec.mcidasv.util.CollectionHelpers; 127import edu.wisc.ssec.mcidasv.util.McVGuiUtils; 128import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Position; 129import edu.wisc.ssec.mcidasv.util.McVGuiUtils.TextColor; 130import edu.wisc.ssec.mcidasv.util.McVGuiUtils.Width; 131 132/** 133 * 134 * @version $Revision$ 135 */ 136public class AddeChooser extends ucar.unidata.idv.chooser.adde.AddeChooser implements Constants { 137 138 private static final Logger logger = LoggerFactory.getLogger(AddeChooser.class); 139 140 private JComboBox serverSelector; 141 142 /** List of descriptors */ 143 private PreferenceList descList; 144 145 /** Descriptor/name hashtable */ 146 protected Hashtable descriptorTable; 147 148 /** List of available descriptors. */ 149 protected List<String> descriptorList; 150 151 /** List of comments associated with list of descriptors. */ 152 protected List<String> commentList; 153 154 /** Property for the descriptor table */ 155 public static final String DESCRIPTOR_TABLE = "DESCRIPTOR_TABLE"; 156 157 /** Connect button--we need to be able to disable this */ 158 JButton connectButton = McVGuiUtils.makeImageTextButton(ICON_CONNECT_SMALL, "Connect"); 159 160 /** Parameter button--we need to be able to disable this */ 161 JButton parameterButton = 162 McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/document-open22.png", 163 this, "doParameters", null, "Load parameter set"); 164 165 /** Manage button */ 166 JButton manageButton = 167 McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/preferences-system22.png", 168 this, "doManager", null, "Manage servers"); 169 170 /** Public button--we need to draw a menu from this */ 171 JButton publicButton = 172 McVGuiUtils.makeImageButton("/edu/wisc/ssec/mcidasv/resources/icons/toolbar/show-layer-controls22.png", 173 this, "showGroups", null, "List public datasets"); 174 175 /** descriptor label */ 176 protected JLabel descriptorLabel = new JLabel(getDescriptorLabel()+":"); 177 178 /** A widget for the list of dataset descriptors */ 179 protected JComboBox descriptorComboBox = new JComboBox(); 180 181 /** The descriptor names */ 182 protected String[] descriptorNames; 183 184 /** Flag to keep from infinite looping */ 185 protected boolean ignoreDescriptorChange = false; 186 187 /** 188 * List of JComponent-s that depend on a descriptor being selected 189 * to be enabled 190 */ 191 protected ArrayList compsThatNeedDescriptor = new ArrayList(); 192 193 /** Selection label text */ 194 protected String LABEL_SELECT = " -- Select -- "; 195 196 /** Separator string */ 197 protected static String separator = "----------------"; 198 199 /** Name separator string */ 200 protected static String nameSeparator = " - "; 201 202 /** Reference back to the server manager */ 203 protected EntryStore serverManager; 204 205 public boolean allServersFlag; 206 207 /** Command for opening up the server manager */ 208 protected static final String CMD_MANAGER = "cmd.manager"; 209 210 private String lastBadServer = ""; 211 private String lastBadGroup = ""; 212 213 private String lastServerName = ""; 214 private String lastServerGroup = ""; 215 private String lastServerUser = ""; 216 private String lastServerProj = ""; 217 private AddeServer lastServer = new AddeServer(""); 218 219 private List<AddeServer> addeServers; 220 221 /** Used for parameter set restore */ 222 private static final String TAG_FOLDER = "folder"; 223 private static final String TAG_DEFAULT = "default"; 224 private static final String ATTR_NAME = "name"; 225 private static final String ATTR_SERVER = "server"; 226 private static final String ATTR_GROUP = "GROUP"; 227 private static final String ATTR_DESCRIPTOR = "DESCRIPTOR"; 228 private static final String ATTR_POS = "POS"; 229 private static final String ATTR_DAY = "DAY"; 230 private static final String ATTR_TIME = "TIME"; 231 private List restoreTimes = new ArrayList(); 232 public Element restoreElement; 233 private boolean shouldAddSource = false; 234 final JCheckBox cb = new JCheckBox("Add source",shouldAddSource); 235 236 /** Maps favorite type to the BundleTree that shows the Manage window for the type */ 237 private Hashtable parameterTrees = new Hashtable(); 238 239 /** 240 * Create an AddeChooser associated with an IdvChooser 241 * 242 * @param mgr The chooser manager 243 * @param root The chooser.xml node 244 */ 245 public AddeChooser(IdvChooserManager mgr, Element root) { 246 super(mgr, root); 247 AnnotationProcessor.process(this); 248 descriptorList = new ArrayList<String>(); 249 commentList = new ArrayList<String>(); 250 251 simpleMode = !getProperty(IdvChooser.ATTR_SHOWDETAILS, true); 252 253 loadButton = McVGuiUtils.makeImageTextButton(ICON_ACCEPT_SMALL, getLoadCommandName()); 254 loadButton.setActionCommand(getLoadCommandName()); 255 loadButton.addActionListener(this); 256 257 cancelButton = McVGuiUtils.makeImageButton(ICON_CANCEL, "Cancel"); 258 cancelButton.setActionCommand(GuiUtils.CMD_CANCEL); 259 cancelButton.addActionListener(this); 260 cancelButton.setEnabled(false); 261 262 serverSelector = getServerSelector(); 263 264 serverSelector.setToolTipText("Right click to manage servers"); 265 serverSelector.getEditor().getEditorComponent().addMouseListener( 266 new MouseAdapter() { 267 public void mouseReleased(MouseEvent e) { 268 if (!SwingUtilities.isRightMouseButton(e)) { 269 return; 270 } 271 272 AddeServer server = getAddeServer(); 273 if (server == null) { 274 return; 275 } 276 List<JMenuItem> items = new ArrayList<JMenuItem>(); 277 278 // Set the right-click behavior 279 if (isLocalServer()) { 280 items.add(GuiUtils.makeMenuItem("Manage local ADDE data", 281 AddeChooser.this, 282 "doManager", null)); 283 } 284 else { 285 items.add(GuiUtils.makeMenuItem("Manage ADDE servers", 286 AddeChooser.this, 287 "doManager", null)); 288 } 289 JPopupMenu popup = GuiUtils.makePopupMenu(items); 290 popup.show(serverSelector, e.getX(), e.getY()); 291 } 292 }); 293 serverSelector.setMaximumRowCount(16); 294 295 groupSelector.setToolTipText("Right click to manage servers"); 296 groupSelector.getEditor().getEditorComponent().addMouseListener( 297 new MouseAdapter() { 298 public void mouseReleased(MouseEvent e) { 299 if (!SwingUtilities.isRightMouseButton(e)) { 300 return; 301 } 302 303 AddeServer server = getAddeServer(); 304 if (server == null) { 305 return; 306 } 307 List<JMenuItem> items = new ArrayList<JMenuItem>(); 308 309 // Set the right-click behavior 310 if (isLocalServer()) { 311 items.add(GuiUtils.makeMenuItem("Manage local ADDE data", 312 AddeChooser.this, "doManager", null)); 313 } 314 else { 315 items.add(GuiUtils.makeMenuItem("Manage ADDE servers", 316 AddeChooser.this, "doManager", null)); 317 } 318 JPopupMenu popup = GuiUtils.makePopupMenu(items); 319 popup.show(groupSelector, e.getX(), e.getY()); 320 } 321 }); 322 groupSelector.setMaximumRowCount(16); 323 324 // serverManager = ((McIDASV)getIdv()).getServerManager(); 325 // serverManager.addManagedChooser(this); 326 addServerComp(descriptorLabel); 327 // addServerComp(descriptorComboBox); 328 329 descriptorComboBox.addItemListener(new ItemListener() { 330 public void itemStateChanged(ItemEvent e) { 331 if ( !ignoreDescriptorChange 332 && (e.getStateChange() == e.SELECTED)) { 333 descriptorChanged(); 334 } 335 } 336 }); 337 338 // Update the server list and load the saved state 339 updateServerList(); 340 loadServerState(); 341 342 // Default to no parameter button unless the overriding class wants one 343 hideParameterButton(); 344 } 345 346 /** 347 * Force a reload of the available servers and groups. 348 */ 349 public void updateServerList() { 350 updateServers(); 351 updateGroups(); 352 } 353 354 /** 355 * Returns a {@link java.util.Map Map} containing {@code user} and {@code proj} 356 * keys for the given {@code server/group} combination. 357 * 358 * <p>The values are either the specific ADDE account details for 359 * {@code server/group} or {@link edu.wisc.ssec.mcidasv.servermanager.AddeEntry#DEFAULT_ACCOUNT DEFAULT_ACCOUNT} 360 * values. 361 * 362 * @param server Server name. Should not be {@code null}. 363 * @param group Group name on {@code name}. Should not be {@code null}. 364 * 365 * @return {@code Map} containing the accounting details for {@code server/group}. 366 */ 367 protected Map<String, String> getAccounting(final String server, final String group) { 368 Map<String, String> acctInfo = new HashMap<String, String>(); 369 EntryStore entryStore = ((McIDASV)getIdv()).getServerManager(); 370 String strType = this.getDataType(); 371 EntryType type = strToEntryType(strType); 372 AddeAccount acct = entryStore.getAccountingFor(server, group, type); 373 acctInfo.put("user", acct.getUsername()); 374 acctInfo.put("proj", acct.getProject()); 375 return acctInfo; 376 } 377 378 /** 379 * Returns a {@link java.util.Map Map} containing {@code user} and {@code proj} 380 * keys for the given {@code server/group} combination. 381 * 382 * <p>The values are either the specific ADDE account details for 383 * {@code server/group} or {@link edu.wisc.ssec.mcidasv.servermanager.AddeEntry#DEFAULT_ACCOUNT DEFAULT_ACCOUNT} 384 * values. 385 * 386 * @param server Server name. Should not be {@code null}. 387 * @param group Group name on {@code name}. Should not be {@code null}. 388 * 389 * @return {@code Map} containing the accounting details for {@code server/group}. 390 */ 391 protected Map<String, String> getAccounting(final AddeServer server, final String group) { 392 return getAccounting(server.getName(), group); 393 } 394 395 private List<AddeServer> getManagedServers(final String type) { 396 EntryStore entryStore = ((McIDASV)getIdv()).getServerManager(); 397 return arrList(entryStore.getIdvStyleEntries(type)); 398 } 399 400 public void updateServers() { 401 Object selected = serverSelector.getSelectedItem(); 402 403 String type = getGroupType(); 404 List<AddeServer> managedServers = getManagedServers(type); 405 List<AddeServer> localList = arrList(); 406 List<AddeServer> remoteList = arrList(); 407 addeServers = CollectionHelpers.arrList(); 408 for (AddeServer server : managedServers) { 409 if (server.getIsLocal()) 410 localList.add(server); 411 else 412 remoteList.add(server); 413 } 414 415// logger.debug("{}: updateServers: local size={} contents={}", new Object[] { getDataType(), localList.size(), localList }); 416// logger.debug("{}: updateServers: remote size={} contents={}", new Object[] { getDataType(), remoteList.size(), remoteList }); 417 418 // server list doesn't need a separator if there's only remote servers 419 if (!localList.isEmpty()) { 420 addeServers.addAll(localList); 421 addeServers.add(new AddeServer(separator)); 422 } 423 Comparator<AddeServer> byServer = new ServerComparator(); 424 Collections.sort(remoteList, byServer); 425 addeServers.addAll(remoteList); 426 427 // always making this call helps to ensure the chooser stays up to date 428 // with the server manager. 429 GuiUtils.setListData(serverSelector, addeServers); 430 if (!addeServers.isEmpty()) { 431 if (selected == null || !containsServerName(addeServers, selected)) { 432 selected = serverSelector.getItemAt(0); 433// logger.debug("updateServers: selecting item at idx=0, item={} chooser={}", selected, this.getDataType()); 434 } 435 436 int index = getSelectorIndex(selected, serverSelector); 437 serverSelector.setSelectedIndex(index); 438 } 439 } 440 441 /** 442 * Searches the given {@link java.util.List List} of {@link ucar.unidata.idv.chooser.adde.AddeServer AddeServers} 443 * for {@code server}. 444 * 445 * @param servers Servers to search. {@code null} is permitted. 446 * @param server Server to search for within {@code servers}. {@code null} is permitted. 447 * 448 * @return {@code true} if {@code servers} contains {@code server} or {@code false} otherwise. 449 */ 450 protected static boolean containsServerName(final List<AddeServer> servers, final Object server) { 451 if (servers == null || server == null) { 452 return false; 453 } 454 String serverName = (server instanceof AddeServer) ? ((AddeServer)server).getName() : server.toString(); 455 for (AddeServer tmp : servers) { 456 if (tmp.getName().equals(serverName)) { 457 return true; 458 } 459 } 460 return false; 461 } 462 463 /** 464 * Searches the given {@link java.util.List List} of {@link ucar.unidata.idv.chooser.adde.AddeServer.Group Groups} 465 * for {@code group}. 466 * 467 * @param groups Groups to search. {@code null} is permitted. 468 * @param group Group to search for within {@code group}. {@code null} is permitted. 469 * 470 * @return {@code true} if {@code groups} contains {@code group} or {@code false} otherwise. 471 */ 472 protected static boolean containsGroupName(final List<Group> groups, final Object group) { 473 if (groups == null || group == null) { 474 return false; 475 } 476 String groupName = (group instanceof Group) ? ((Group)group).getName() : group.toString(); 477 for (Group tmp : groups) { 478 if (tmp.getName().equals(groupName)) { 479 return true; 480 } 481 } 482 return false; 483 } 484 485 /** 486 * Sort the groups alphabetically 487 */ 488 public void updateGroups() { 489 if (addingServer || groupSelector == null || getAddeServer() == null) 490 return; 491 492 Object selected = groupSelector.getSelectedItem(); 493 494 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 495 496 List<Group> groups = CollectionHelpers.arrList(); 497 if (isLocalServer()) { 498 groups.addAll(servManager.getIdvStyleLocalGroups()); 499 } else { 500 String sel = null; 501 Object obj = serverSelector.getSelectedItem(); 502 if (obj instanceof String) { 503 sel = (String)obj; 504// logger.debug("updateGroups: string={} chooser={}", sel, this.getDataType()); 505 } else if (obj instanceof AddeServer) { 506 sel = ((AddeServer)obj).getName(); 507// logger.debug("updateGroups: server selection={} chooser={}", sel, this.getDataType()); 508 } else { 509 sel = obj.toString(); 510// logger.debug("updateGroups: unknown type={}; toString={}", sel.getClass().getName(), sel); 511 } 512 513 EntryType selType = strToEntryType(getGroupType()); 514 groups.addAll(servManager.getIdvStyleRemoteGroups(sel, selType)); 515 } 516// logger.trace("updateGroups: selected={} (type={}) chooser={} contents={}", new Object[] { serverSelector.getSelectedItem(), serverSelector.getSelectedItem().getClass().getName(), this.getDataType(), groups}); 517 Comparator<Group> byGroup = new GroupComparator(); 518 Collections.sort(groups, byGroup); 519 GuiUtils.setListData(groupSelector, groups); 520 if (!groups.isEmpty()) { 521 if (selected == null || !containsGroupName(groups, selected)) { 522 selected = groupSelector.getItemAt(0); 523 } 524 groupSelector.setSelectedItem(selected); 525 } 526 } 527 528 /** 529 * Load any saved server state 530 */ 531 //TODO: Make loadServerState protected in IDV, remove from here 532 private void loadServerState() { 533 if (addeServers == null) { 534// logger.debug("loadServerState: addeServers == null chooser={}", this.getDataType()); 535 return; 536 } 537 String id = getId(); 538 String[] serverState = 539 (String[]) getIdv().getStore().get(Constants.PREF_SERVERSTATE + '.' + id); 540 if (serverState == null) { 541// serverState = Constants.DEFAULT_SERVERSTATE; 542// logger.debug("loadServerState: serverState == null chooser={}",this.getDataType()); 543 return; 544 } 545 AddeServer server = AddeServer.findServer(addeServers, serverState[0]); 546 if (server == null) { 547// logger.debug("loadServerState: server == null chooser={}",this.getDataType()); 548 return; 549 } 550// logger.debug("loadServerState: selecting server={} chooser={}", server, this.getDataType()); 551 serverSelector.setSelectedItem(server); 552 setGroups(); 553 updateGroups(); 554 if (serverState[1] != null) { 555 Group group = new Group(getDataType(), serverState[1], serverState[1]); 556 int index = getSelectorIndex(group, groupSelector); 557 if (index >= 0) { 558// logger.debug("loadServerState: selecting index={} group={} chooser={}", new Object[] { index, group, this.getDataType() }); 559 groupSelector.setSelectedIndex(index); 560 } else { 561// logger.debug("loadServerState: group == null chooser={}", this.getDataType()); 562 } 563 } else { 564// logger.debug("loadServerState: serverState[1] == null chooser={}", this.getDataType()); 565 } 566 } 567 568 /** 569 * Decide if the server you're asking about is actually a separator 570 */ 571 protected static boolean isSeparator(AddeServer checkServer) { 572 if (checkServer != null) { 573 if (checkServer.getName().equals(separator)) { 574 return true; 575 } 576 } 577 return false; 578 } 579 580 /** 581 * Decide if the server you're asking about is local 582 */ 583 protected boolean isLocalServer() { 584 return isLocalServer(getAddeServer()); 585 } 586 587 protected static boolean isLocalServer(AddeServer checkServer) { 588 if (checkServer != null) { 589 return checkServer.getIsLocal(); 590 } 591 return false; 592 } 593 594 private void setBadServer(String name, String group) { 595 if (name == null) { 596 name = ""; 597 } 598 if (group == null) { 599 group = ""; 600 } 601 602 lastBadServer = name; 603 lastBadGroup = group; 604 } 605 606 private boolean isBadServer(String name, String group) { 607 assert lastBadServer != null; 608 assert lastBadGroup != null; 609 return lastBadServer.equals(name) && lastBadGroup.equals(group); 610 } 611 612 private void setLastServer(String name, String group, AddeServer server) { 613// logger.trace("name='{}' group='{}' server='{}' old: name='{}' group='{}' server='{}'", new Object[] { name, group, server, lastServerName, lastServerGroup, lastServer }); 614 if (name == null) { 615 name = ""; 616 } 617 if (group == null) { 618 group = ""; 619 } 620 if (server == null) { 621 server = new AddeServer(name); 622 Group addeGroup = new Group(getDataType(), group, group); 623 server.addGroup(addeGroup); 624 } 625 lastServerName = name; 626 lastServerGroup = group; 627 lastServer = server; 628 } 629 630 private boolean isLastServer(String name, String group) { 631 assert lastServer != null; 632 assert lastServerName != null; 633 assert lastServerGroup != null; 634 return lastServerName.equals(name) && lastServerGroup.equals(group); 635 } 636 637 @EventSubscriber(eventClass=EntryStore.Event.class) 638 public void onServerManagerDataEvent(EntryStore.Event evt) { 639 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 640// logger.debug("onServerManagerDataEvent: evt={} server={}", evt, servManager.getLastAdded()); 641 this.updateServerList(); 642 } 643 644 @EventSubscriber(eventClass=TabbedAddeManager.Event.class) 645 public void onServerManagerWindowEvent(TabbedAddeManager.Event evt) { 646// logger.debug("onServerManagerWindowEvent: caught event bus obj"); 647 } 648 649 private boolean addingServer = false; 650 651 /** 652 * Search a given {@link JComboBox} for the index of a given object. Mostly 653 * useful for searching {@link #serverSelector} or {@link #groupSelector}. 654 * 655 * @param needle An object. {@code null} values are permitted. 656 * @param haystack {@code JComboBox} to search. {@code null} values are 657 * permitted, but return {@code -1}. 658 * 659 * @return Either the index of {@code needle} within {@code haystack}, or 660 * {@code -1} if {@code needle} could not be found (or {@code haystack} is 661 * {@code null}). 662 */ 663 protected static int getSelectorIndex(final Object needle, 664 final JComboBox haystack) 665 { 666 if (haystack == null) { 667 return -1; 668 } 669 670 String name = null; 671 if (needle instanceof AddeServer) { 672 name = ((AddeServer)needle).getName(); 673 } else if (needle instanceof Group) { 674 name = ((Group)needle).getName(); 675 } else if (needle instanceof AddeEntry) { 676 name = ((AddeEntry)needle).getAddress(); 677 } else { 678 name = needle.toString(); 679 } 680 681 if (isLoopback(name)) { 682 return 0; 683 } 684 685 for (int i = 0; i < haystack.getItemCount(); i++) { 686 Object item = haystack.getItemAt(i); 687 String tmpName; 688 if (item instanceof AddeServer) { 689 tmpName = ((AddeServer)item).getName(); 690 } else { 691 tmpName = item.toString(); 692 } 693 694 if (name.equals(tmpName)) { 695 return i; 696 } 697 } 698 return -1; 699 } 700 701 /** 702 * Get the selected AddeServer 703 * 704 * @return the server or null 705 */ 706 protected AddeServer getAddeServer() { 707 if (lastServerName != null && lastServerName.equals("unset")) { 708 return null; 709 } 710 711 Object selected = serverSelector.getSelectedItem(); 712 if ((selected != null) && (selected instanceof AddeServer)) { 713 AddeServer server = (AddeServer)selected; 714 String group = getGroup(true); 715 Map<String, String> accounting = getAccounting(server, group); 716// logger.trace("accounting: new: u='{}' p='{}' old: u='{}' p='{}'", new Object[] { accounting.get("user"), accounting.get("proj"), lastServerUser, lastServerProj }); 717 lastServerUser = accounting.get("user"); 718 lastServerProj = accounting.get("proj"); 719 setLastServer(server.getName(), group, server); 720 return (AddeServer)selected; 721 } else if ((selected != null) && (selected instanceof String)) { 722 723 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 724 String server = (String)selected; 725 String group = getGroup(true); 726 727 if (isBadServer(server, group)) { 728// logger.trace("getAddeServer: returning null; known bad server; server={} group={}", server, group); 729 return null; 730 } 731 732 if (isLastServer(server, group)) { 733// logger.trace("getAddeServer: returning last server name; server={} group={}", server, group); 734 return lastServer; 735 } 736 737 EditorAction editorAction = EditorAction.INVALID; 738 if (!isLoopback(server)) { 739 RemoteEntryEditor editor = new RemoteEntryEditor(servManager, server, ""); 740 editor.setVisible(true); 741 editorAction = editor.getEditorAction(); 742 } else { 743 LocalEntryEditor editor = new LocalEntryEditor(servManager, group); 744 editor.setVisible(true); 745 editorAction = editor.getEditorAction(); 746 } 747 748 int servIndex = 0; 749 int groupIndex = 0; 750 751 if (editorAction != EditorAction.CANCELLED && editorAction != EditorAction.INVALID) { 752 753 List<AddeServer> added = arrList(EntryTransforms.convertMcvServers(servManager.getLastAddedByType(strToEntryType(getDataType())))); 754 AddeServer first = null; 755 if (!added.isEmpty()) { 756 first = added.get(0); 757 servIndex = getSelectorIndex(first, serverSelector); 758 setLastServer(server, group, first); 759 } 760 761 serverSelector.setSelectedIndex(servIndex); 762 groupSelector.setSelectedIndex(groupIndex); 763// logger.trace("getAddeServer: serverIdx={} groupIdx={}", servIndex, groupIndex); 764 765 return first; 766 } else { 767// logger.trace("getAddeServer: returning null due to cancel request"); 768 setBadServer(server, group); 769 return null; 770 } 771 772 773 774 } else if (selected == null) { 775// logger.trace("getAddeServer: null object in selector; returning null"); 776 } else { 777// logger.debug("getAddeServer: unknown obj type={}; toString={}", selected.getClass().getName(), selected.toString()); 778 } 779 return null; 780 } 781 782 /** 783 * A utility to add a component to the list of components that 784 * need the descriptor 785 * 786 * @param comp The component 787 * @return The component 788 */ 789 protected JComponent addDescComp(JComponent comp) { 790 compsThatNeedDescriptor.add(comp); 791 return comp; 792 } 793 794 /** 795 * Set LABEL_SELECT from elsewhere 796 */ 797 protected void setSelectString(String string) { 798 LABEL_SELECT = string; 799 } 800 801 /** 802 * Reset the descriptor stuff 803 */ 804 protected void resetDescriptorBox() { 805 ignoreDescriptorChange = true; 806 descriptorComboBox.setSelectedItem(LABEL_SELECT); 807 ignoreDescriptorChange = false; 808 } 809 810 /** 811 * Handle when the user presses the connect button 812 * 813 * @throws Exception On badness 814 */ 815 public void handleConnect() throws Exception { 816 AddeServer server = getAddeServer(); 817 if (server == null) { 818 return; 819 } 820 setState(STATE_CONNECTING); 821 connectToServer(); 822 handleUpdate(); 823 } 824 825 /** 826 * Show the user a descriptive error message in a dialog (if in foreground 827 * mode) depending on the state of {@code e}. 828 * 829 * @param e Exception to handle. Cannot be {@code null}. 830 * 831 * @throws NullPointerException if {@code e} is {@code null}. 832 * 833 * @see #handleConnectionError(String, Exception) 834 */ 835 @Override protected void handleConnectionError(Exception e) { 836 handleConnectionError("", e); 837 } 838 839 /** 840 * Show the user a descriptive error message (with optional details) in a 841 * dialog. 842 * 843 * @param details Details about the context of {@code e}. {@code null} will 844 * be treated as an empty {@code String}. 845 * @param e Exception to handle. Cannot be {@code null}. 846 * 847 * @throws NullPointerException if {@code e} is {@code null}. 848 */ 849 protected void handleConnectionError(String details, Exception e) { 850 Objects.requireNonNull(e, "Cannot handle null exception"); 851 logger.error("attempting to handle connection error", e); 852 853 if ((details != null) && !details.isEmpty()) { 854 details = details+":\n"; 855 } else { 856 details = ""; 857 } 858 859 boolean isError = true; 860 if (e.getMessage() != null) { 861 String msg = e.getMessage(); 862 int msgPos = msg.indexOf("AddeURLException:"); 863 if ((msgPos >= 0) && (msg.length() > 18)) { 864 msg = msg.substring(msgPos + 18); 865 GuiUtils.showDialog("ADDE Error", new JLabel(details+msg)); 866 } else if (msg.indexOf("Connecting to server:localhost:") >= 0) { 867 GuiUtils.showDialog("ADDE Error", new JLabel("Local server is not responding.")); 868 } else if (msg.toLowerCase().contains("unknownhostexception")) { 869 LogUtil.userErrorMessage("Could not access server: " + getServer()); 870 } else if ((e instanceof AddeURLException) || msg.toLowerCase().contains("server unable to resolve this dataset")) { 871 handleUnknownDataSetError(); 872 } else if ((msg.toLowerCase().contains("no images satisfy")) 873 || (msg.toLowerCase().contains("error generating list of files"))) 874 { 875 LogUtil.userErrorMessage("No data available for the selection"); 876 isError = false; 877 } else { 878 LogUtil.logException("Encountered a problem (server: '" + getServer()+"'):\n"+details, e); 879 } 880 } else { 881 LogUtil.userErrorMessage("Encountered a problem (server: '" + getServer() + "'):\n" + details +e); 882 } 883 884 if (isError && (getState() == STATE_CONNECTED)) { 885 setHaveData(false); 886 resetDescriptorBox(); 887 updateStatus(); 888 setState(STATE_UNCONNECTED); 889 } 890 } 891 892 /** 893 * Handle unknown data set error 894 */ 895 @Override protected void handleUnknownDataSetError() { 896 String server = getServer(); 897 String group = getGroup(); 898 Map<String, String> acct = getAccounting(server, group); 899 String user = acct.get("user"); 900 String proj = acct.get("proj"); 901 902 StringBuilder msg = new StringBuilder("Could not connect to dataset \""); 903 msg.append(getGroup()).append("\" on server \"").append(getServer()).append("\"."); 904 if (DEFAULT_ACCOUNT.getUsername().equals(user) && DEFAULT_ACCOUNT.getProject().equals(proj)) { 905 msg.append("\n\nDataset may require ADDE accounting information."); 906 } else { 907 msg.append("\n\nAccounting information:\nusername: \"") 908 .append(user).append("\"\nproject: \"").append(proj).append('"'); 909 } 910 LogUtil.userErrorMessage(msg.toString()); 911 setState(STATE_UNCONNECTED); 912 } 913 914 /** 915 * Handle the event 916 * 917 * @param ae The event 918 */ 919 public void actionPerformed(ActionEvent ae) { 920 String cmd = ae.getActionCommand(); 921 if (cmd.equals(CMD_MANAGER)) { 922 doManager(); 923 } 924 else { 925 super.actionPerformed(ae); 926 } 927 } 928 929 /** 930 * Go directly to the Server Manager 931 */ 932 public void doManager() { 933// if (isLocalServer()) { 934// ((McIDASV)getIdv()).showAddeManager(); 935// return; 936// } 937 getIdv().getPreferenceManager().showTab(Constants.PREF_LIST_ADDE_SERVERS); 938 } 939 940 /** 941 * Show the parameter restore tree 942 */ 943 public void doParameters() { 944 JPopupMenu popup = new JPopupMenu(); 945 JMenuItem mi = new JMenuItem("Manage..."); 946 mi.addActionListener(new ActionListener() { 947 public void actionPerformed(ActionEvent ae) { 948 System.out.println(ae); 949 showParameterSetDialog(getParameterSetType()); 950 } 951 }); 952 popup.add(mi); 953 954 // Add the checkbox to automatically create a data source 955 cb.addActionListener(new ActionListener() { 956 public void actionPerformed(ActionEvent ae) { 957 shouldAddSource = cb.isSelected(); 958 } 959 }); 960 popup.addSeparator(); 961 popup.add(cb); 962 963 final PersistenceManager pm = (PersistenceManager)getIdv().getPersistenceManager(); 964 List<ParameterSet> parameterSets = pm.getAllParameterSets(getParameterSetType()); 965 966 for (int i=0; i<parameterSets.size(); i++) { 967 if (i==0) popup.addSeparator(); 968 final ParameterSet ps = parameterSets.get(i); 969 970 // Parameter set at root 971 if (ps.getCategories().size() == 0) { 972 mi = new JMenuItem(ps.getName()); 973 mi.addActionListener(new ActionListener() { 974 public void actionPerformed(ActionEvent ae) { 975 restoreParameterSet(ps.getElement()); 976 } 977 }); 978 popup.add(mi); 979 } 980 981 // Recurse into folders 982 else { 983 // Find or make the menu for the given parameter set 984 JMenu m = getPopupSubMenuForParameterSet(popup, ps); 985 // Create parameter set entry 986 mi = new JMenuItem(ps.getName()); 987 mi.addActionListener(new ActionListener() { 988 public void actionPerformed(ActionEvent ae) { 989 restoreParameterSet(ps.getElement()); 990 } 991 }); 992 m.add(mi); 993 } 994 995 } 996 997 popup.show(parameterButton, 0, (int) parameterButton.getBounds().getHeight()); 998 } 999 1000 private JMenu getPopupSubMenuForParameterSet(JPopupMenu popup, final ParameterSet ps) { 1001 List<String> menuNames = ps.getCategories(); 1002 if (menuNames.size() < 1) return null; 1003 1004 // Build the complete menu 1005 String menuName = menuNames.get(0); 1006 menuNames.remove(0); 1007 JMenu theMenu = new JMenu(); 1008 1009 // Look for the menu in popup 1010 boolean found = false; 1011 for (int i=0; i<popup.getComponentCount(); i++) { 1012 Component thisComponent = popup.getComponent(i); 1013 if (thisComponent instanceof JMenu && ((JMenu)thisComponent).getText().equals(menuName)) { 1014 theMenu = mergeMenuNames((JMenu)thisComponent, menuNames); 1015 found = true; 1016 } 1017 } 1018 1019 // Make a new menu, add the root, return the leaf 1020 if (!found) { 1021 JMenu theRoot = new JMenu(menuName); 1022 theMenu = makeMenuRecursive(theRoot, menuNames); 1023 popup.add(theRoot); 1024 } 1025 1026 return theMenu; 1027 } 1028 1029 /** 1030 * Make a new recursive menu 1031 * 1032 * @param rootMenu The root menu to add items to 1033 * @param menuNames List of string names for submenus 1034 * @return A new JMenu representing the leaf 1035 */ 1036 private JMenu makeMenuRecursive(JMenu rootMenu, List<String> menuNames) { 1037 if (menuNames.size() < 1) return rootMenu; 1038 JMenu newMenu = new JMenu(menuNames.get(0)); 1039 rootMenu.add(newMenu); 1040 menuNames.remove(0); 1041 return makeMenuRecursive(newMenu, menuNames); 1042 } 1043 1044 /** 1045 * Recurse into a menu, returning either a pointer to the designated names path 1046 * or a pointer to the leaf menu added by merging new names 1047 * 1048 * @param thisMenu The root menu to merge 1049 * @param menuNames List of string names to look for 1050 * @return A new JMenu representing the leaf matched by menuNames 1051 */ 1052 private JMenu mergeMenuNames(JMenu thisMenu, List<String> menuNames) { 1053 if (menuNames.size() < 1) return thisMenu; 1054 boolean found = false; 1055 String menuName = menuNames.get(0); 1056 for (int i=0; i<thisMenu.getItemCount(); i++) { 1057 JMenuItem mi = thisMenu.getItem(i); 1058 if (!(mi instanceof JMenu)) continue; 1059 if (mi.getText().equals(menuName)) { 1060 menuNames.remove(0); 1061 thisMenu = mergeMenuNames((JMenu)mi, menuNames); 1062 found = true; 1063 } 1064 } 1065 if (!found) { 1066 thisMenu = makeMenuRecursive(thisMenu, menuNames); 1067 } 1068 return thisMenu; 1069 } 1070 1071 /** 1072 * Return the parameter type associated with this chooser. Override! 1073 */ 1074 protected String getParameterSetType() { 1075 return "adde"; 1076 } 1077 1078 /** 1079 * Show the parameter set manager. 1080 */ 1081 private void showParameterSetDialog(final String parameterSetType) { 1082 ParameterTree tree = (ParameterTree) parameterTrees.get(parameterSetType); 1083 if (tree == null) { 1084 tree = new ParameterTree((UIManager)getIdv().getIdvUIManager() , parameterSetType); 1085 parameterTrees.put(parameterSetType, tree); 1086 } 1087 else { 1088 //DAVEP 1089 System.out.println("Should refresh the parameter tree here"); 1090 } 1091 tree.setVisible(true); 1092 } 1093 1094 /** 1095 * Clear the selected parameter set. 1096 */ 1097 protected void clearParameterSet() { 1098 restoreElement = null; 1099 restoreTimes = new ArrayList(); 1100 shouldAddSource = false; 1101 } 1102 1103 /** 1104 * Restore the selected parameter set using element attributes. 1105 * 1106 * @param restoreElement {@code Element} with the desired attributes. 1107 * {@code null} values are permitted. 1108 * 1109 * @return {@code true} if the parameter set was restored, {@code false} 1110 * otherwise. 1111 */ 1112 protected boolean restoreParameterSet(Element restoreElement) { 1113 if (restoreElement == null) return false; 1114 if (!restoreElement.getTagName().equals("default")) return false; 1115 1116 this.restoreElement = restoreElement; 1117 1118 boolean oldISCE = ignoreStateChangedEvents; 1119 ignoreStateChangedEvents = true; 1120 1121 // Restore server 1122 String server = restoreElement.getAttribute(ATTR_SERVER); 1123 if (server != null) serverSelector.setSelectedItem(new AddeServer(server)); 1124 1125 // Restore group 1126 String group = restoreElement.getAttribute(ATTR_GROUP); 1127 if (group != null) groupSelector.setSelectedItem(group); 1128 1129 // Act as though the user hit "connect" 1130 readFromServer(); 1131 1132 // Restore descriptor 1133 String descriptor = restoreElement.getAttribute(ATTR_DESCRIPTOR); 1134 if (descriptor != null) { 1135 Enumeration enumeration = descriptorTable.keys(); 1136 for (int i = 0; enumeration.hasMoreElements(); i++) { 1137 String key = enumeration.nextElement().toString(); 1138 Object val = descriptorTable.get(key); 1139 if (descriptor.equals(val)) { 1140 descriptorComboBox.setSelectedItem(val + nameSeparator + key); 1141 descriptorChanged(); 1142 break; 1143 } 1144 } 1145 } 1146 1147 // Restore date/time 1148 if (restoreElement.hasAttribute(ATTR_POS)) { 1149 setDoAbsoluteTimes(false); 1150 Integer pos = new Integer(restoreElement.getAttribute(ATTR_POS)); 1151 if (pos.intValue() >= 0) { 1152 getRelativeTimesList().setSelectedIndex(pos); 1153 } 1154 restoreTimes = new ArrayList(); 1155 } 1156 else if ((restoreElement.hasAttribute(ATTR_DAY)) && (restoreElement.hasAttribute(ATTR_TIME))) { 1157 setDoAbsoluteTimes(true); 1158 String dateStr = restoreElement.getAttribute(ATTR_DAY); 1159 String timeStr = restoreElement.getAttribute(ATTR_TIME); 1160 List dateS = StringUtil.split(dateStr, ","); 1161 List timeS = StringUtil.split(timeStr, ","); 1162 int numImages = timeS.size(); 1163 restoreTimes = new ArrayList(); 1164 try { 1165 DateTime dt = new DateTime(); 1166 dt.resetFormat(); 1167 String dtformat = dt.getFormatPattern(); 1168 for (int ix=0; ix<numImages; ix++) { 1169 DateTime restoreTime = dt.createDateTime((String)dateS.get(ix) + " " + (String)timeS.get(ix)); 1170 restoreTimes.add(restoreTime); 1171 } 1172 } catch (Exception e) { 1173 System.out.println("Exception e=" + e); 1174 return false; 1175 } 1176 } 1177 1178 System.out.println("Returning from AddeChooser.restoreParameterSet()"); 1179 1180 ignoreStateChangedEvents = oldISCE; 1181 return true; 1182 } 1183 1184 /** 1185 * Set the absolute times list. The times list can contain any of the object types 1186 * that makeDatedObjects knows how to handle, i.e., Date, visad.DateTime, DatedThing, AddeImageDescriptor, etc. 1187 * 1188 * @param times List of thinggs to put into absolute times list 1189 */ 1190 protected void setAbsoluteTimes(List times) { 1191 super.setAbsoluteTimes(times); 1192 restoreAbsoluteTimes(); 1193 } 1194 1195 protected void restoreAbsoluteTimes() { 1196 List allTimes = makeDatedObjects(super.getAbsoluteTimes()); 1197 if (restoreTimes.size() > 0 && allTimes.size() > 0) { 1198 int[] indices = new int[restoreTimes.size()]; 1199 try { 1200 DateTime rtdt; 1201 DateTime atdt; 1202 DatedThing at; 1203 for (int i = 0; i < restoreTimes.size(); i++) { 1204 rtdt = (DateTime)restoreTimes.get(i); 1205 for (int j = 0; j < allTimes.size(); j++) { 1206 at = (DatedThing)allTimes.get(j); 1207 atdt = new DateTime(at.getDate()); 1208 if (atdt.equals(rtdt)) { 1209 indices[i] = j; 1210 } 1211 } 1212 } 1213 } catch (Exception e) { 1214 System.out.println("Exception e=" + e); 1215 } 1216 setSelectedAbsoluteTimes(indices); 1217 } 1218 } 1219 1220 /** 1221 * show/hide the parameter restore button 1222 */ 1223 public void showParameterButton() { 1224 parameterButton.setVisible(true); 1225 } 1226 1227 public void hideParameterButton() { 1228 parameterButton.setVisible(false); 1229 } 1230 1231 /** 1232 * Override and simulate clicking Add Source if requested 1233 */ 1234 public void setHaveData(boolean have) { 1235 super.setHaveData(have); 1236 if (have && shouldAddSource) { 1237 // Even though setHaveData should mean we can go, we can't... wait a few jiffies 1238 Misc.runInABit(100, AddeChooser.this, "doClickLoad", null); 1239 } 1240 } 1241 1242 public void doClickLoad() { 1243 loadButton.doClick(); 1244 } 1245 1246 public void showServers() { 1247 allServersFlag = !allServersFlag; 1248 XmlObjectStore store = getIdv().getStore(); 1249 store.put(Constants.PREF_SYSTEMSERVERSIMG, allServersFlag); 1250 store.save(); 1251 updateServers(); 1252 updateGroups(); 1253 } 1254 1255 protected String getStateString() { 1256 int state = getState(); 1257 switch (state) { 1258 case STATE_CONNECTED: return "Connected to server"; 1259 case STATE_UNCONNECTED: return "Not connected to server"; 1260 case STATE_CONNECTING: return "Connecting to server"; 1261 default: return "Unknown state: " + state; 1262 } 1263 } 1264 1265 /** 1266 * Disable/enable any components that depend on the server. 1267 * Try to update the status label with what we know here. 1268 */ 1269 protected void updateStatus() { 1270 super.updateStatus(); 1271 if (getState() == STATE_CONNECTED) { 1272 lastServer = new AddeServer(""); 1273 lastServerGroup = ""; 1274 lastServerName = ""; 1275 lastServerProj = ""; 1276 lastServerUser = ""; 1277 1278 if (!haveDescriptorSelected()) { 1279 if (!usingStations() || haveStationSelected()) { 1280 // String name = getDataName().toLowerCase(); 1281 String name = getDescriptorLabel().toLowerCase(); 1282 if (StringUtil.startsWithVowel(name)) { 1283 setStatus("Please select an " + name); 1284 } else { 1285 setStatus("Please select a " + name); 1286 } 1287 } 1288 } 1289 } 1290 1291 GuiUtils.enableTree(connectButton, getState() != STATE_CONNECTING); 1292 } 1293 1294 /** 1295 * Get the data type ID 1296 * 1297 * @return the data type 1298 */ 1299 public String getDataType() { 1300 return "ANY"; 1301 } 1302 1303 /** 1304 * Check if the server is ok 1305 * 1306 * @return status code 1307 */ 1308 protected int checkIfServerIsOk() { 1309 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 1310 if (isLocalServer() && !servManager.checkLocalServer()) { 1311 LogUtil.userErrorMessage("Local servers are stopped.\n\nLocal servers can be restarted from the 'Tools' menu:\n Tools > Manage ADDE Datasets >\nLocal Servers > Start Local Servers"); 1312 logger.info("Local servers are stopped"); 1313 return STATUS_ERROR; 1314 } 1315 try { 1316 StringBuffer buff = getUrl(REQ_TEXT); 1317 appendKeyValue(buff, PROP_FILE, FILE_PUBLICSRV); 1318 URL url = new URL(buff.toString()); 1319 URLConnection urlc = url.openConnection(); 1320 InputStream is = urlc.getInputStream(); 1321 is.close(); 1322 return STATUS_OK; 1323 } catch (AddeURLException ae) { 1324 String aes = ae.toString(); 1325 if (aes.indexOf("Invalid project number") >= 0 || 1326 aes.indexOf("Invalid user id") >= 0 || 1327 aes.indexOf("Accounting data") >= 0) { 1328 LogUtil.userErrorMessage("Invalid login.\n\nPlease verify your username and password."); 1329 logger.info("Invalid login"); 1330 setState(STATE_UNCONNECTED); 1331 setHaveData(false); 1332 resetDescriptorBox(); 1333 return STATUS_NEEDSLOGIN; 1334 } 1335 if (aes.indexOf("cannot run server 'txtgserv'") >= 0) { 1336 return STATUS_OK; 1337 } 1338 LogUtil.userErrorMessage("Error connecting to server " + getServer() + ":\n" + ae.getMessage()); 1339 logger.info("Error connecting to server"); 1340 setState(STATE_UNCONNECTED); 1341 setHaveData(false); 1342 resetDescriptorBox(); 1343 return STATUS_ERROR; 1344 } catch (ConnectException exc) { 1345 setState(STATE_UNCONNECTED); 1346 setHaveData(false); 1347 resetDescriptorBox(); 1348 String message = "Error connecting to server " + getServer(); 1349 String info = "Error connecting to server"; 1350 if (isLocalServer()) { 1351 if (!servManager.checkLocalServer()) { 1352 message += "\n\nLocal servers can be restarted from the 'Tools' menu:\n Tools > Manage ADDE Datasets >\n Local Servers > Start Local Servers"; 1353 info += " (Local servers are stopped)"; 1354 } 1355 else { 1356 message += "\n\nLocal servers appear to be running.\nYour firewall may be preventing access."; 1357 info += " (Local servers are running)"; 1358 } 1359 } 1360 LogUtil.userErrorMessage(message); 1361 logger.info(info); 1362 return STATUS_ERROR; 1363 } catch (EOFException exc) { 1364 setState(STATE_UNCONNECTED); 1365 setHaveData(false); 1366 resetDescriptorBox(); 1367 LogUtil.userErrorMessage("Server " + getServer() + " is not responding"); 1368 logger.info("Server is not responding"); 1369 return STATUS_ERROR; 1370 } catch (Exception exc) { 1371 setState(STATE_UNCONNECTED); 1372 setHaveData(false); 1373 resetDescriptorBox(); 1374 logException("Connecting to server: " + getServer(), exc); 1375 logger.info("Error connecting to server"); 1376 return STATUS_ERROR; 1377 } 1378 } 1379 1380 public boolean canAccessServer() { 1381 return (checkIfServerIsOk() == STATUS_OK); 1382 } 1383 1384 public Map<String, String> getAccountingInfo() { 1385 AddeServer server = getAddeServer(); 1386 Map<String, String> map = new LinkedHashMap<String, String>(); 1387 if (server != null) { 1388 List<AddeServer.Group> groups = server.getGroups(); 1389 Map<String, String>acctInfo = getAccounting(server, groups.get(0).toString()); 1390 map.put("user", acctInfo.get("user")); 1391 map.put("proj", acctInfo.get("proj")); 1392 map.put("server", server.getName()); 1393 map.put("group", getGroup()); 1394 } else { 1395 map.put("user", RemoteAddeEntry.DEFAULT_ACCOUNT.getUsername()); 1396 map.put("proj", RemoteAddeEntry.DEFAULT_ACCOUNT.getUsername()); 1397 map.put("server", ""); 1398 map.put("group", ""); 1399 } 1400 return map; 1401 } 1402 1403 /** 1404 * Saves the currently selected server and group to a chooser-specific 1405 * preference. Preference ID is {@code PREF_SERVERSTATE+'.'+getId()}. 1406 */ 1407 @Override public void saveServerState() { 1408 String[] serverState = { getServer(), getGroup() }; 1409 getIdv().getStore().put(PREF_SERVERSTATE+'.'+getId(), serverState); 1410 getIdv().getStore().save(); 1411 } 1412 1413 /** 1414 * Connect to the server. 1415 */ 1416 protected void connectToServer() { 1417 clearParameterSet(); 1418 setDescriptors(null); 1419 setDoAbsoluteTimes(false); 1420 if (!canAccessServer()) { 1421 return; 1422 } 1423 readFromServer(); 1424 saveServerState(); 1425 ignoreStateChangedEvents = true; 1426 if (descList != null) { 1427 descList.saveState(groupSelector); 1428 } 1429 ignoreStateChangedEvents = false; 1430 } 1431 1432 /** 1433 * Do server connection stuff... override this with type-specific methods 1434 */ 1435 protected void readFromServer() { 1436 readDescriptors(); 1437 readTimes(); 1438 } 1439 1440// what the request needs to look like: 1441// adde://localhost:8112/imagedata?&PORT=112&COMPRES S=gzip&USER=idv&PROJ=0 1442// &VERSION=1&DEBUG=false&TRAC E=0&GROUP=MYDATA&DESCRIPTOR=ENTRY4&BAND=1 1443// &LATLON= 30.37139 71.74912&PLACE=CENTER&SIZE=1000 1000&UNI T=BRIT 1444// &MAG=1 1&SPAC=1&NAV=X&AUX=YES&DOC=X&POS=0 1445 1446 /** 1447 * Generate a list of image descriptors for the descriptor list. 1448 */ 1449 protected void readDescriptors() { 1450 try { 1451 StringBuffer buff = getGroupUrl(REQ_DATASETINFO, getGroup()); 1452 buff.append("&type=").append(getDataType()); 1453 logger.debug("readDesc: buff={}", buff.toString()); 1454 DataSetInfo dsinfo = new DataSetInfo(buff.toString()); 1455 1456 descriptorTable = dsinfo.getDescriptionTable(); 1457 descriptorList.clear(); 1458 commentList.clear(); 1459 descriptorList.addAll(dsinfo.getDescriptorList()); 1460 commentList.addAll(dsinfo.getCommentList()); 1461 int count = commentList.size(); 1462 String[] names = new String[count]; 1463 for (int i = 0; i < count; i++) { 1464 if (!isLocalServer()) { 1465 names[i] = descriptorList.get(i) + nameSeparator + commentList.get(i); 1466 } else { 1467 names[i] = commentList.get(i); 1468 } 1469 } 1470 logger.debug("readDesc: names={}", names); 1471 Arrays.sort(names); 1472 setDescriptors(names); 1473 setState(STATE_CONNECTED); 1474 } catch (Exception e) { 1475 handleConnectionError(e); 1476 } 1477 } 1478 1479 /** 1480 * Initialize the descriptor list from a list of names 1481 * 1482 * @param names list of names 1483 */ 1484 protected void setDescriptors(String[] names) { 1485 synchronized (WIDGET_MUTEX) { 1486 ignoreDescriptorChange = true; 1487 descriptorComboBox.removeAllItems(); 1488 descriptorNames = names; 1489 if ((names == null) || (names.length == 0)) { 1490 return; 1491 } 1492 descriptorComboBox.addItem(LABEL_SELECT); 1493 for (int j = 0; j < names.length; j++) { 1494 logger.trace("adding names[{}]='{}' to combo box", j, names[j]); 1495 descriptorComboBox.addItem(names[j]); 1496 } 1497 ignoreDescriptorChange = false; 1498 } 1499 } 1500 1501 /** 1502 * Respond to a change in the descriptor list. 1503 */ 1504 protected void descriptorChanged() { 1505 readTimes(); 1506 updateStatus(); 1507 } 1508 1509 /** 1510 * Check if a descriptor (image type) has been chosen 1511 * 1512 * @return true if an image type has been chosen 1513 */ 1514 protected boolean haveDescriptorSelected() { 1515 if (!GuiUtils.anySelected(descriptorComboBox)) { 1516 return false; 1517 } 1518 return getDescriptor() != null; 1519 } 1520 1521 /** 1522 * Get the selected descriptor. 1523 * 1524 * @return the currently selected descriptor. 1525 */ 1526 protected String getDescriptor() { 1527 return getDescriptorFromSelection(getSelectedDescriptor()); 1528 } 1529 1530 /** 1531 * Get the descriptor relating to the selection. 1532 * 1533 * @param selection String name from the widget. Can be {@code null}. 1534 * 1535 * @return Either the descriptor associated with {@code selection} or {@code null} if {@link #descriptorTable} or 1536 * {@code selection} is {@code null}. 1537 */ 1538 protected String getDescriptorFromSelection(String selection) { 1539 if (descriptorTable == null) { 1540 return null; 1541 } 1542 if (selection == null) { 1543 return null; 1544 } 1545 1546 String descriptor = null; 1547 if (!selection.contains(nameSeparator)) { 1548 descriptor = (String)descriptorTable.get(selection); 1549 } else { 1550 String[] toks = selection.split(nameSeparator, 2); 1551 String firstToken = toks[0].trim(); 1552 if (descriptorList.contains(firstToken)) { 1553 descriptor = firstToken; 1554 } else { 1555 String key = toks[1].trim(); 1556 descriptor = (String)descriptorTable.get(key); 1557 } 1558 } 1559 return descriptor; 1560 } 1561 1562 /** 1563 * Get the selected descriptor. 1564 * 1565 * @return the selected descriptor 1566 */ 1567 public String getSelectedDescriptor() { 1568 String selection = (String)descriptorComboBox.getSelectedItem(); 1569 if (selection == null) { 1570 return null; 1571 } 1572 if (selection.equals(LABEL_SELECT)) { 1573 return null; 1574 } 1575 return selection; 1576 } 1577 1578 /** 1579 * Get the descriptor table for this chooser 1580 * 1581 * @return a Hashtable of descriptors and names 1582 */ 1583 public Hashtable getDescriptorTable() { 1584 return descriptorTable; 1585 } 1586 1587 /** 1588 * Get any extra key=value pairs that are appended to all requests. 1589 * 1590 * @param buff The buffer to append onto 1591 */ 1592 protected void appendMiscKeyValues(StringBuffer buff) { 1593 appendKeyValue(buff, PROP_COMPRESS, DEFAULT_COMPRESS); 1594 appendKeyValue(buff, PROP_PORT, DEFAULT_PORT); 1595 // appendKeyValue(buff, PROP_DEBUG, DEFAULT_DEBUG); 1596 appendKeyValue(buff, PROP_DEBUG, Boolean.toString(EntryStore.isAddeDebugEnabled(false))); 1597 appendKeyValue(buff, PROP_VERSION, DEFAULT_VERSION); 1598 appendKeyValue(buff, PROP_USER, getLastAddedUser()); 1599 appendKeyValue(buff, PROP_PROJ, getLastAddedProj()); 1600 } 1601 1602 public String getLastAddedUser() { 1603 if ((lastServerUser != null) && !lastServerUser.isEmpty()) { 1604 logger.debug("getLastAddedUser: using non-default {}", lastServerUser); 1605 return lastServerUser; 1606 } else { 1607 logger.debug("getLastAddedUser: using default {}", DEFAULT_USER); 1608 return DEFAULT_USER; 1609 } 1610 } 1611 1612 public String getLastAddedProj() { 1613 if ((lastServerProj != null) && !lastServerProj.isEmpty()) { 1614 logger.debug("getLastAddedProj: using non-default {}", lastServerProj); 1615 return lastServerProj; 1616 } else { 1617 logger.debug("getLastAddedProj: using default {}", DEFAULT_PROJ); 1618 return DEFAULT_PROJ; 1619 } 1620 } 1621 1622 /** 1623 * Show the groups dialog. This method is not meant to be called 1624 * but is public by reason of implementation (or insanity). 1625 */ 1626 public void showGroups() { 1627 JPopupMenu popup = new JPopupMenu(); 1628 popup.add(new JMenuItem("Reading public datasets...")); 1629 1630 1631 List groups = readGroups(); 1632 popup.removeAll(); 1633 if ((groups == null) || (groups.isEmpty())) { 1634 popup.add(new JMenuItem("The list of public datasets is not available")); 1635 popup.show(publicButton, 0, (int) publicButton.getBounds().getHeight()); 1636 return; 1637 } 1638 1639 JMenuItem mi; 1640 for (int i = 0; i < groups.size(); i++) { 1641 final String group = groups.get(i).toString(); 1642 mi = new JMenuItem(group); 1643 mi.addActionListener(ae -> { 1644 EntryStore servManager = ((McIDASV)getIdv()).getServerManager(); 1645 1646 servManager.addEntry( 1647 new RemoteAddeEntry.Builder(lastServerName, group) 1648 .account(lastServerUser, lastServerProj) 1649 .type(strToEntryType(getDataType())) 1650 .source(EntrySource.USER) 1651 .validity(EntryValidity.VERIFIED) 1652 .build()); 1653 1654 groupSelector.setSelectedItem(group); 1655 doConnect(); 1656 }); 1657 popup.add(mi); 1658 } 1659 MenuScroller foo = new MenuScroller(popup, 125); 1660 foo.setParent(publicButton); 1661 popup.show(publicButton, 0, (int) publicButton.getBounds().getHeight()); 1662 } 1663 1664 /** 1665 * return the String id of the chosen server name 1666 * 1667 * @return the server name 1668 */ 1669 public String getServer() { 1670 AddeServer server = getAddeServer(); 1671 if (server != null) { 1672 return server.getName(); 1673 } else { 1674 return ""; 1675 } 1676 } 1677 1678 protected String getGroup() { 1679 return getGroup(false); 1680 } 1681 1682 /** 1683 * Is the group selector editable? 1684 * 1685 * @return Always returns {@code true}. 1686 */ 1687 protected boolean isGroupEditable() { 1688 return true; 1689 } 1690 1691 /** 1692 * Get the image group from the GUI. 1693 * 1694 * @return The image group. 1695 */ 1696 protected String getGroup(final boolean fromGetServer) { 1697 Object selected = groupSelector.getSelectedItem(); 1698 if (selected == null) { 1699 return null; 1700 } 1701 1702 if (selected instanceof AddeServer.Group) { 1703 AddeServer.Group group = (AddeServer.Group) selected; 1704 return group.getName(); 1705 } 1706 1707 if (selected instanceof String) { 1708 return (String)selected; 1709 } 1710 1711 String groupName = selected.toString().trim(); 1712 if (!fromGetServer && (!groupName.isEmpty())) { 1713 //Force the get in case they typed a server name 1714 getServer(); 1715 1716 AddeServer server = getAddeServer(); 1717 if (server != null) { 1718 AddeServer.Group group = 1719 getIdv().getIdvChooserManager().addAddeServerGroup( 1720 server, groupName, getGroupType()); 1721 if (!group.getActive()) { 1722 getIdv().getIdvChooserManager().activateAddeServerGroup( 1723 server, group); 1724 } 1725 //Now put the list of groups back in to the selector 1726 setGroups(); 1727 groupSelector.setSelectedItem(group); 1728 } 1729 } 1730 return groupName; 1731 } 1732 1733 /** 1734 * Get the server selector 1735 * @return The server selector 1736 */ 1737 public JComboBox getServerSelector() { 1738 if (serverSelector == null) 1739 serverSelector = super.getServerSelector(); 1740 1741 ItemListener[] ell = serverSelector.getItemListeners(); 1742 for (int i=0; i < ell.length; i++) { 1743 serverSelector.removeItemListener((ItemListener)ell[i]); 1744 } 1745 updateServers(); 1746 updateGroups(); 1747 serverSelector.addItemListener(new ItemListener() { 1748 public void itemStateChanged(ItemEvent e) { 1749 if (!ignoreStateChangedEvents) { 1750 Object selected = serverSelector.getSelectedItem(); 1751 if (selected instanceof AddeServer) { 1752 AddeServer selectedServer = (AddeServer)selected; 1753 if (selectedServer != null) { 1754 if (isSeparator(selectedServer)) { 1755 connectButton.setEnabled(false); 1756 return; 1757 } 1758 } 1759 } 1760 setState(STATE_UNCONNECTED); 1761 connectButton.setEnabled(true); 1762// setGroups(); 1763 resetDescriptorBox(); 1764 updateGroups(); 1765// System.err.println("itemStateChanged"); 1766 } 1767// else { 1768// System.out.println("Ignoring state change here..."); 1769// } 1770 } 1771 }); 1772 1773 serverSelector.getEditor().getEditorComponent().addKeyListener(new KeyListener() { 1774 public void keyTyped(final KeyEvent e) {} 1775 public void keyPressed(final KeyEvent e) {} 1776 public void keyReleased(final KeyEvent e) { 1777 JTextField field = (JTextField)serverSelector.getEditor().getEditorComponent(); 1778 boolean partialMatch = false; 1779 for (int i = 0; i < serverSelector.getItemCount(); i++) { 1780 String entry = serverSelector.getItemAt(i).toString(); 1781 if (entry.toLowerCase().startsWith(field.getText().toLowerCase())) 1782 partialMatch = true; 1783 } 1784 1785 if (!partialMatch && groupSelector != null) { 1786 logger.debug("aha! chooser=", getDataType()); 1787 ((JTextField)groupSelector.getEditor().getEditorComponent()).setText(""); 1788 } 1789 } 1790 }); 1791 1792 return serverSelector; 1793 } 1794 1795 /** 1796 * Enable or disable the GUI widgets based on what has been 1797 * selected. 1798 */ 1799 protected void enableWidgets() { 1800 synchronized (WIDGET_MUTEX) { 1801 boolean newEnabledState = (getState() == STATE_CONNECTED); 1802 for (int i = 0; i < compsThatNeedDescriptor.size(); i++) { 1803 JComponent comp = (JComponent) compsThatNeedDescriptor.get(i); 1804 if (comp.isEnabled() != newEnabledState) { 1805 GuiUtils.enableTree(comp, newEnabledState); 1806 } 1807 } 1808 if (drivercbx != null) { 1809 boolean descriptorState = newEnabledState && haveDescriptorSelected(); 1810// logger.trace("hrm set drivercbx={}", anyTimeDrivers() && descriptorState); 1811 drivercbx.setEnabled(anyTimeDrivers() && descriptorState); 1812 } 1813 } 1814 } 1815 1816 /** 1817 * Add a listener to the given combobox that will set the 1818 * state to unconnected 1819 * 1820 * @param box The box to listen to. 1821 */ 1822 protected void clearOnChange(final JComboBox box) { 1823 box.addItemListener(new ItemListener() { 1824 public void itemStateChanged(ItemEvent e) { 1825 if ( !ignoreStateChangedEvents) { 1826 setState(STATE_UNCONNECTED); 1827 GuiUtils.setListData(descriptorComboBox, new Vector()); 1828// System.err.println("clearOnChange"); 1829 } 1830// else { 1831// System.out.println("Ignoring state change in clearOnChange for: " + box.toString()); 1832// } 1833 } 1834 }); 1835 } 1836 1837 /** 1838 * Get the descriptor widget label 1839 * 1840 * @return label for the descriptor widget 1841 */ 1842 public String getDescriptorLabel() { 1843 return "Descriptor"; 1844 } 1845 1846 protected int getNumTimesToSelect() { 1847 return 5; 1848 } 1849 1850 /** 1851 * Get the default selected index for the relative times list. 1852 * 1853 * @return default index 1854 */ 1855 protected int getDefaultRelativeTimeIndex() { 1856 return 4; 1857 } 1858 1859 /** 1860 * Check the times lists 1861 */ 1862 protected void checkTimesLists() { 1863 super.checkTimesLists(); 1864 if (timesCardPanelExtra == null) { 1865 return; 1866 } 1867 if (getDoAbsoluteTimes()) { 1868 timesCardPanelExtra.show("absolute"); 1869 } else { 1870 timesCardPanelExtra.show("relative"); 1871 } 1872 } 1873 1874 /** Card panel to hold extra relative and absolute time components */ 1875 protected GuiUtils.CardLayoutPanel timesCardPanelExtra; 1876 1877 /** 1878 * Set the relative and absolute extra components. 1879 */ 1880 protected JPanel makeTimesPanel(JComponent relativeCard, JComponent absoluteCard) { 1881// JPanel timesPanel = super.makeTimesPanel(false, true); 1882 JPanel timesPanel = super.makeTimesPanel(false, true, getIdv().getUseTimeDriver()); 1883 1884 // Make a new timesPanel that has extra components tacked on the bottom, inside the tabs 1885 Component[] comps = timesPanel.getComponents(); 1886 1887// if (drivercbx != null) { 1888// drivercbx.setEnabled(anyTimeDrivers()); 1889// } 1890 1891 if ((comps.length == 1) && (comps[0] instanceof JTabbedPane)) { 1892 timesCardPanelExtra = new GuiUtils.CardLayoutPanel(); 1893 if (relativeCard == null) { 1894 relativeCard = new JPanel(); 1895 } 1896 if (absoluteCard == null) { 1897 absoluteCard = new JPanel(); 1898 } 1899 timesCardPanelExtra.add(relativeCard, "relative"); 1900 timesCardPanelExtra.add(absoluteCard, "absolute"); 1901 timesPanel = GuiUtils.centerBottom(comps[0], timesCardPanelExtra); 1902 } 1903 1904 return timesPanel; 1905 } 1906 1907 private JPanel innerPanel = new JPanel(); 1908 1909 private JLabel statusLabel = new JLabel("Status"); 1910 1911 /** 1912 * Super setStatus() takes a second string to enable "simple" mode 1913 * which highlights the required component. We don't really care 1914 * about that feature, and we don't want getStatusLabel() to 1915 * change the label background color. 1916 */ 1917 @Override 1918 public void setStatus(String statusString, String foo) { 1919 if (statusString == null) { 1920 statusString = ""; 1921 } 1922 statusLabel.setText(statusString); 1923 } 1924 1925 protected void setInnerPanel(JPanel newInnerPanel) { 1926 innerPanel = newInnerPanel; 1927 } 1928 1929 /** 1930 * Make the UI for this selector. 1931 * 1932 * Thank you NetBeans for helping with the layout! 1933 * 1934 * @return The GUI. 1935 */ 1936 protected JComponent doMakeContents() { 1937 JPanel outerPanel = new JPanel(); 1938 1939 JLabel serverLabelInner = new JLabel("Server:"); 1940 McVGuiUtils.setLabelPosition(serverLabelInner, Position.RIGHT); 1941 JPanel serverLabel = GuiUtils.leftRight(parameterButton, serverLabelInner); 1942 McVGuiUtils.setComponentWidth(serverLabel); 1943 1944 clearOnChange(serverSelector); 1945 McVGuiUtils.setComponentWidth(serverSelector, Width.DOUBLE); 1946 1947 JLabel groupLabel = McVGuiUtils.makeLabelRight("Dataset:"); 1948 1949 groupSelector.setEditable(isGroupEditable()); 1950 clearOnChange(groupSelector); 1951 McVGuiUtils.setComponentWidth(groupSelector, Width.DOUBLE); 1952 1953 McVGuiUtils.setComponentWidth(connectButton, Width.DOUBLE); 1954 connectButton.setActionCommand(CMD_CONNECT); 1955 connectButton.addActionListener(this); 1956 1957 /** Set the attributes for the descriptor label and combo box, even though 1958 * they are not used here. Extending classes can add them to the panel if 1959 * necessary. 1960 */ 1961 McVGuiUtils.setComponentWidth(descriptorLabel); 1962 McVGuiUtils.setLabelPosition(descriptorLabel, Position.RIGHT); 1963 1964 McVGuiUtils.setComponentWidth(descriptorComboBox, Width.DOUBLEDOUBLE); 1965 1966 if (descriptorComboBox.getMinimumSize().getWidth() < ELEMENT_DOUBLE_WIDTH) { 1967 McVGuiUtils.setComponentWidth(descriptorComboBox, Width.DOUBLE); 1968 } 1969 1970 JLabel statusLabelLabel = McVGuiUtils.makeLabelRight(""); 1971 1972 statusLabel.setText("Status"); 1973 McVGuiUtils.setLabelPosition(statusLabel, Position.RIGHT); 1974 McVGuiUtils.setComponentColor(statusLabel, TextColor.STATUS); 1975 1976 JButton helpButton = McVGuiUtils.makeImageButton(ICON_HELP, "Show help"); 1977 helpButton.setActionCommand(GuiUtils.CMD_HELP); 1978 helpButton.addActionListener(this); 1979 1980 JButton refreshButton = McVGuiUtils.makeImageButton(ICON_REFRESH, "Refresh"); 1981 refreshButton.setActionCommand(GuiUtils.CMD_UPDATE); 1982 refreshButton.addActionListener(this); 1983 1984 McVGuiUtils.setComponentWidth(loadButton, Width.DOUBLE); 1985 1986 GroupLayout layout = new GroupLayout(outerPanel); 1987 outerPanel.setLayout(layout); 1988 layout.setHorizontalGroup( 1989 layout.createParallelGroup(LEADING) 1990 .addGroup(TRAILING, layout.createSequentialGroup() 1991 .addGroup(layout.createParallelGroup(TRAILING) 1992 .addGroup(layout.createSequentialGroup() 1993 .addContainerGap() 1994 .addComponent(helpButton) 1995 .addGap(GAP_RELATED) 1996 .addComponent(refreshButton) 1997 .addGap(GAP_RELATED) 1998 .addComponent(cancelButton) 1999 .addPreferredGap(RELATED) 2000 .addComponent(loadButton)) 2001 .addGroup(LEADING, layout.createSequentialGroup() 2002 .addContainerGap() 2003 .addGroup(layout.createParallelGroup(LEADING) 2004 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 2005 .addGroup(layout.createSequentialGroup() 2006 .addComponent(serverLabel) 2007 .addGap(GAP_RELATED) 2008 .addComponent(serverSelector) 2009 .addGap(GAP_RELATED) 2010 .addComponent(manageButton) 2011 .addGap(GAP_RELATED) 2012 .addComponent(groupLabel) 2013 .addGap(GAP_RELATED) 2014 .addComponent(groupSelector) 2015 .addGap(GAP_RELATED) 2016 .addComponent(publicButton) 2017 .addPreferredGap(RELATED, DEFAULT_SIZE, Short.MAX_VALUE) 2018 .addComponent(connectButton)) 2019 .addGroup(layout.createSequentialGroup() 2020 .addComponent(statusLabelLabel) 2021 .addGap(GAP_RELATED) 2022 .addComponent(statusLabel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE))))) 2023 .addContainerGap()) 2024 ); 2025 layout.setVerticalGroup( 2026 layout.createParallelGroup(LEADING) 2027 .addGroup(layout.createSequentialGroup() 2028 .addContainerGap() 2029 .addGroup(layout.createParallelGroup(BASELINE) 2030 .addComponent(serverLabel) 2031 .addComponent(serverSelector) 2032 .addComponent(manageButton) 2033 .addComponent(groupLabel) 2034 .addComponent(groupSelector) 2035 .addComponent(publicButton) 2036 .addComponent(connectButton)) 2037 .addPreferredGap(UNRELATED) 2038 .addComponent(innerPanel, DEFAULT_SIZE, DEFAULT_SIZE, Short.MAX_VALUE) 2039 .addPreferredGap(UNRELATED) 2040 .addGroup(layout.createParallelGroup(BASELINE) 2041 .addComponent(statusLabelLabel) 2042 .addComponent(statusLabel)) 2043 .addPreferredGap(UNRELATED) 2044 .addGroup(layout.createParallelGroup(BASELINE) 2045 .addComponent(loadButton) 2046 .addComponent(cancelButton) 2047 .addComponent(refreshButton) 2048 .addComponent(helpButton)) 2049 .addContainerGap()) 2050 ); 2051 2052 return outerPanel; 2053 2054 } 2055 2056 public class ServerComparator implements Comparator<AddeServer> { 2057 public int compare(AddeServer server1, AddeServer server2) { 2058 return server1.getName().compareTo(server2.getName()); 2059 } 2060 } 2061 2062 public class GroupComparator implements Comparator<Group> { 2063 public int compare(Group group1, Group group2) { 2064 return group1.getName().compareTo(group2.getName()); 2065 } 2066 } 2067} 2068