zookeeper-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From an...@apache.org
Subject [04/45] zookeeper git commit: ZOOKEEPER-3030: MAVEN MIGRATION - Step 1.3 - move contrib directories
Date Mon, 06 Aug 2018 12:13:29 GMT
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/ZooInspector.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/ZooInspector.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/ZooInspector.java
new file mode 100644
index 0000000..0322d98
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/ZooInspector.java
@@ -0,0 +1,71 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector;
+
+import java.awt.event.WindowAdapter;
+import java.awt.event.WindowEvent;
+
+import javax.swing.JFrame;
+import javax.swing.JOptionPane;
+import javax.swing.UIManager;
+
+import org.apache.zookeeper.inspector.gui.IconResource;
+import org.apache.zookeeper.inspector.gui.ZooInspectorPanel;
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManagerImpl;
+
+/**
+ * 
+ */
+public class ZooInspector {
+	
+	public static IconResource iconResource;
+	
+    /**
+     * @param args
+     *            - not used. The value of these parameters will have no effect
+     *            on the application
+     */
+    public static void main(String[] args) {
+        try {
+            UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
+            JFrame frame = new JFrame("ZooInspector");
+            frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+            iconResource = new IconResource();
+            final ZooInspectorPanel zooInspectorPanel = new ZooInspectorPanel(
+                    new ZooInspectorManagerImpl(), iconResource);
+            frame.addWindowListener(new WindowAdapter() {
+                @Override
+                public void windowClosed(WindowEvent e) {
+                    super.windowClosed(e);
+                    zooInspectorPanel.disconnect(true);
+                }
+            });
+
+            frame.setContentPane(zooInspectorPanel);
+            frame.setSize(1024, 768);
+            frame.setVisible(true);
+        } catch (Exception e) {
+            LoggerFactory.getLogger().error(
+                    "Error occurred loading ZooInspector", e);
+            JOptionPane.showMessageDialog(null,
+                    "ZooInspector failed to start: " + e.getMessage(), "Error",
+                    JOptionPane.ERROR_MESSAGE);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java
new file mode 100644
index 0000000..a9e5ac4
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/BasicDataEncryptionManager.java
@@ -0,0 +1,50 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.encryption;
+
+/**
+ *
+ */
+public class BasicDataEncryptionManager implements DataEncryptionManager {
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.encryption.DataEncryptionManager#decryptData
+     * (byte[])
+     */
+    public String decryptData(byte[] encrypted) throws Exception {
+        return new String(encrypted);
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * org.apache.zookeeper.inspector.encryption.DataEncryptionManager#encryptData
+     * (java.lang.String)
+     */
+    public byte[] encryptData(String data) throws Exception {
+        if (data == null) {
+            return new byte[0];
+        }
+        return data.getBytes();
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java
new file mode 100644
index 0000000..15a9ee4
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/encryption/DataEncryptionManager.java
@@ -0,0 +1,39 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.encryption;
+
+/**
+ * A class which describes how data should be encrypted and decrypted
+ */
+public interface DataEncryptionManager {
+    /**
+     * @param data
+     *            - the data to be encrypted
+     * @return the encrypted data
+     * @throws Exception
+     */
+    public byte[] encryptData(String data) throws Exception;
+
+    /**
+     * @param encrypted
+     *            - the data to be decrypted
+     * @return the decrypted data
+     * @throws Exception
+     */
+    public String decryptData(byte[] encrypted) throws Exception;
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/IconResource.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/IconResource.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/IconResource.java
new file mode 100644
index 0000000..411900a
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/IconResource.java
@@ -0,0 +1,106 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.inspector.gui;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import javax.swing.ImageIcon;
+
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+
+/**
+ * @see http://standards.freedesktop.org/icon-naming-spec/icon-naming-spec-latest.html
+ * I tried to take icons that are available in the Tango icon set
+ */
+public class IconResource {
+
+    public static final String ICON_ChangeNodeViewers = "";
+    public static final String ICON_TREE_LEAF = "mimetypes/text-x-generic";
+    public static final String ICON_TREE_OPEN = "places/folder";
+    public static final String ICON_TREE_CLOSE = "places/folder";
+    public static final String ICON_INFORMATION = "status/info";
+    public static final String ICON_SAVE = "actions/document-save";
+    public static final String ICON_UP = "actions/up";
+    public static final String ICON_DOWN = "actions/down";
+    public static final String ICON_ADD = "actions/add";
+    public static final String ICON_REMOVE = "actions/remove";
+    public static final String ICON_START = "actions/media-playback-start";
+    public static final String ICON_STOP = "actions/media-playback-stop";
+    public static final String ICON_DOCUMENT_ADD = "actions/document-new";
+    public static final String ICON_REFRESH = "actions/view-refresh";
+    public static final String ICON_TRASH = "places/user-trash";
+    // better: actions/help-about, but not in tango
+    public static final String ICON_HELP_ABOUT = "status/info";
+
+    private static final String DEFAULT_THEME = "Tango";
+    private static final String DEFAULT_SIZE = "16x16";
+    private static final String FALLBACK_ICON = "face-surprise";
+
+    // compare http://standards.freedesktop.org/basedir-spec/basedir-spec-latest.html
+    private static final String[] DEFAULT_XDG_DATA_DIRS = new String[]{
+        "/usr/local/share",
+        "/usr/share"
+    };
+
+    private String theme = DEFAULT_THEME;
+    private String size = DEFAULT_SIZE;
+
+    public URL find(String name) {
+        String iconPath = buildIconPath(name);
+        URL iconUrl = findInPaths(iconPath);
+        if(null != iconUrl) return iconUrl;
+
+        iconUrl = getClass().getResource(iconPath);
+        if(null != iconUrl) return iconUrl;
+
+        if(!name.equals(FALLBACK_ICON)) return find(FALLBACK_ICON);
+        return null;
+    }
+
+    public ImageIcon get(String name, String description) {
+        URL iconUrl = find(name);
+        if(null==iconUrl) {
+            ImageIcon icon = new ImageIcon();
+            icon.setDescription(description);
+            return icon;
+        } else {
+            return new ImageIcon(iconUrl, description);
+        }
+    }
+
+    private URL findInPaths(String iconPath) {
+        for(String dataDir : DEFAULT_XDG_DATA_DIRS) {
+            File file = new File(dataDir + iconPath);
+            if(file.exists()) {
+                try {
+                    return file.toURI().toURL();
+                } catch (MalformedURLException e) {
+                    LoggerFactory.getLogger().warn(e.toString());
+                }
+            }
+        }
+        return null;
+    }
+
+    private String buildIconPath(String name) {
+        return "/icons/" + theme + "/" + size + "/" + name + ".png";
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.java
new file mode 100644
index 0000000..b0b1e98
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/NodeViewersChangeListener.java
@@ -0,0 +1,37 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.util.List;
+
+import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer;
+
+/**
+ * A Listener for changes to the configuration of which node viewers are shown
+ */
+public interface NodeViewersChangeListener {
+    /**
+     * Called when the node viewers configuration is changed (i.e node viewers
+     * are added, removed or the order of the node viewers is changed)
+     * 
+     * @param newViewers
+     *            - a {@link List} of {@link ZooInspectorNodeViewer}s which are
+     *            to be shown
+     */
+    public void nodeViewersChanged(List<ZooInspectorNodeViewer> newViewers);
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/Toolbar.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/Toolbar.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/Toolbar.java
new file mode 100644
index 0000000..06e80a8
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/Toolbar.java
@@ -0,0 +1,92 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.event.ActionListener;
+import java.util.HashMap;
+import java.util.Map;
+
+import javax.swing.JButton;
+import javax.swing.JToolBar;
+
+public class Toolbar {
+
+    private final IconResource iconResource;
+    private final JToolBar toolbar = new JToolBar();
+    private final Map<Button, JButton> buttons = new HashMap<Button, JButton>();
+
+    private static final Button[] buttonsToToggle = new Button[] {
+        Button.connect, Button.disconnect, Button.refresh, Button.addNode, Button.deleteNode
+    };
+
+    public Toolbar(IconResource iconResource) {
+        this.iconResource = iconResource;
+        init();
+    }
+
+    public void addActionListener(Button button, ActionListener actionListener) {
+        buttons.get(button).addActionListener(actionListener);
+    }
+
+    public JToolBar getJToolBar() {
+        return toolbar;
+    }
+
+    public void toggleButtons(boolean connected) {
+        for(Button button : buttonsToToggle) {
+            buttons.get(button).setEnabled(connected != button.enabled);
+        }
+    }
+
+    private void init() {
+        toolbar.setFloatable(false);
+        for(Button button : Button.values()) {
+            JButton jbutton = button.createJButton(iconResource);
+            buttons.put(button, jbutton);
+            toolbar.add(jbutton);
+        }
+    }
+
+    public static enum Button {
+        connect("Connect",IconResource.ICON_START,true),
+        disconnect("Disconnect",IconResource.ICON_STOP,false),
+        refresh("Refresh",IconResource.ICON_REFRESH,false),
+        addNode("Add Node",IconResource.ICON_DOCUMENT_ADD,false),
+        deleteNode("Delete Node",IconResource.ICON_TRASH,false),
+        nodeViewers("Change Node Viewers",IconResource.ICON_ChangeNodeViewers,true),
+        about("About ZooInspector",IconResource.ICON_HELP_ABOUT,true);
+
+        private String toolTip;
+        private String icon;
+        private boolean enabled;
+
+        Button(String toolTip, String icon, boolean enabled) {
+            this.toolTip = toolTip;
+            this.icon = icon;
+            this.enabled = enabled;
+        }
+
+        public JButton createJButton(IconResource iconResource) {
+            JButton jbutton = new JButton(iconResource.get(icon, toolTip));
+            jbutton.setEnabled(enabled);
+            jbutton.setToolTipText(toolTip);
+            return jbutton;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java
new file mode 100644
index 0000000..58096b2
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorAboutDialog.java
@@ -0,0 +1,79 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JEditorPane;
+import javax.swing.JPanel;
+
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+
+/**
+ * The About Dialog for the application
+ */
+public class ZooInspectorAboutDialog extends JDialog {
+    /**
+     * @param frame
+     *            - the Frame from which the dialog is displayed
+     */
+    public ZooInspectorAboutDialog(Frame frame, IconResource iconResource) {
+        super(frame);
+        this.setLayout(new BorderLayout());
+        this.setIconImage(iconResource.get(IconResource.ICON_INFORMATION, "About ZooInspector").getImage());
+        this.setTitle("About ZooInspector");
+        this.setModal(true);
+        this.setAlwaysOnTop(true);
+        this.setResizable(false);
+        JPanel panel = new JPanel();
+        panel.setLayout(new BorderLayout());
+        JEditorPane aboutPane = new JEditorPane();
+        aboutPane.setEditable(false);
+        aboutPane.setOpaque(false);
+        java.net.URL aboutURL = ZooInspectorAboutDialog.class
+                .getResource("about.html");
+        try {
+            aboutPane.setPage(aboutURL);
+        } catch (IOException e) {
+            LoggerFactory.getLogger().error(
+                    "Error loading about.html, file may be corrupt", e);
+        }
+        panel.add(aboutPane, BorderLayout.CENTER);
+        panel.setPreferredSize(new Dimension(600, 200));
+        JPanel buttonsPanel = new JPanel();
+        buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
+        JButton okButton = new JButton("OK");
+        okButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorAboutDialog.this.dispose();
+            }
+        });
+        buttonsPanel.add(okButton);
+        this.add(panel, BorderLayout.CENTER);
+        this.add(buttonsPanel, BorderLayout.SOUTH);
+        this.pack();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java
new file mode 100644
index 0000000..1647021
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorConnectionPropertiesDialog.java
@@ -0,0 +1,321 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.BorderLayout;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.Map.Entry;
+
+import javax.swing.JButton;
+import javax.swing.JComboBox;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JTextField;
+
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.Pair;
+
+/**
+ * The connection properties dialog. This is used to determine the settings for
+ * connecting to a zookeeper instance
+ */
+public class ZooInspectorConnectionPropertiesDialog extends JDialog {
+
+    private final Map<String, JComponent> components;
+
+    /**
+     * @param lastConnectionProps
+     *            - the last connection properties used. if this is the first
+     *            conneciton since starting the applications this will be the
+     *            default settings
+     * @param connectionPropertiesTemplateAndLabels
+     *            - the connection properties and labels to show in this dialog
+     * @param zooInspectorPanel
+     *            - the {@link ZooInspectorPanel} linked to this dialog
+     */
+    public ZooInspectorConnectionPropertiesDialog(
+            Properties lastConnectionProps,
+            Pair<Map<String, List<String>>, Map<String, String>> connectionPropertiesTemplateAndLabels,
+            final ZooInspectorPanel zooInspectorPanel) {
+        final Map<String, List<String>> connectionPropertiesTemplate = connectionPropertiesTemplateAndLabels
+                .getKey();
+        final Map<String, String> connectionPropertiesLabels = connectionPropertiesTemplateAndLabels
+                .getValue();
+        this.setLayout(new BorderLayout());
+        this.setTitle("Connection Settings");
+        this.setModal(true);
+        this.setAlwaysOnTop(true);
+        this.setResizable(false);
+        final JPanel options = new JPanel();
+        final JFileChooser fileChooser = new JFileChooser();
+        options.setLayout(new GridBagLayout());
+        int i = 0;
+        components = new HashMap<String, JComponent>();
+        for (Entry<String, List<String>> entry : connectionPropertiesTemplate
+                .entrySet()) {
+            int rowPos = 2 * i + 1;
+            JLabel label = new JLabel(connectionPropertiesLabels.get(entry
+                    .getKey()));
+            GridBagConstraints c1 = new GridBagConstraints();
+            c1.gridx = 0;
+            c1.gridy = rowPos;
+            c1.gridwidth = 1;
+            c1.gridheight = 1;
+            c1.weightx = 0;
+            c1.weighty = 0;
+            c1.anchor = GridBagConstraints.WEST;
+            c1.fill = GridBagConstraints.HORIZONTAL;
+            c1.insets = new Insets(5, 5, 5, 5);
+            c1.ipadx = 0;
+            c1.ipady = 0;
+            options.add(label, c1);
+            if (entry.getValue().size() == 0) {
+                JTextField text = new JTextField();
+                GridBagConstraints c2 = new GridBagConstraints();
+                c2.gridx = 2;
+                c2.gridy = rowPos;
+                c2.gridwidth = 1;
+                c2.gridheight = 1;
+                c2.weightx = 0;
+                c2.weighty = 0;
+                c2.anchor = GridBagConstraints.WEST;
+                c2.fill = GridBagConstraints.HORIZONTAL;
+                c2.insets = new Insets(5, 5, 5, 5);
+                c2.ipadx = 0;
+                c2.ipady = 0;
+                options.add(text, c2);
+                components.put(entry.getKey(), text);
+            } else if (entry.getValue().size() == 1) {
+                JTextField text = new JTextField(entry.getValue().get(0));
+                GridBagConstraints c2 = new GridBagConstraints();
+                c2.gridx = 2;
+                c2.gridy = rowPos;
+                c2.gridwidth = 1;
+                c2.gridheight = 1;
+                c2.weightx = 0;
+                c2.weighty = 0;
+                c2.anchor = GridBagConstraints.WEST;
+                c2.fill = GridBagConstraints.HORIZONTAL;
+                c2.insets = new Insets(5, 5, 5, 5);
+                c2.ipadx = 0;
+                c2.ipady = 0;
+                options.add(text, c2);
+                components.put(entry.getKey(), text);
+            } else {
+                List<String> list = entry.getValue();
+                JComboBox combo = new JComboBox(list.toArray(new String[list
+                        .size()]));
+                combo.setSelectedItem(list.get(0));
+                GridBagConstraints c2 = new GridBagConstraints();
+                c2.gridx = 2;
+                c2.gridy = rowPos;
+                c2.gridwidth = 1;
+                c2.gridheight = 1;
+                c2.weightx = 0;
+                c2.weighty = 0;
+                c2.anchor = GridBagConstraints.WEST;
+                c2.fill = GridBagConstraints.HORIZONTAL;
+                c2.insets = new Insets(5, 5, 5, 5);
+                c2.ipadx = 0;
+                c2.ipady = 0;
+                options.add(combo, c2);
+                components.put(entry.getKey(), combo);
+            }
+            i++;
+        }
+        loadConnectionProps(lastConnectionProps);
+        JPanel buttonsPanel = new JPanel();
+        buttonsPanel.setLayout(new GridBagLayout());
+        JButton loadPropsFileButton = new JButton("Load from file");
+        loadPropsFileButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                int result = fileChooser
+                        .showOpenDialog(ZooInspectorConnectionPropertiesDialog.this);
+                if (result == JFileChooser.APPROVE_OPTION) {
+                    File propsFilePath = fileChooser.getSelectedFile();
+                    Properties props = new Properties();
+                    try {
+                        FileReader reader = new FileReader(propsFilePath);
+                        try {
+                            props.load(reader);
+                            loadConnectionProps(props);
+                        } finally {
+                            reader.close();
+                        }
+                    } catch (IOException ex) {
+                        LoggerFactory
+                                .getLogger()
+                                .error(
+                                        "An Error occurred loading connection properties from file",
+                                        ex);
+                        JOptionPane
+                                .showMessageDialog(
+                                        ZooInspectorConnectionPropertiesDialog.this,
+                                        "An Error occurred loading connection properties from file",
+                                        "Error", JOptionPane.ERROR_MESSAGE);
+                    }
+                    options.revalidate();
+                    options.repaint();
+                }
+
+            }
+        });
+        GridBagConstraints c3 = new GridBagConstraints();
+        c3.gridx = 0;
+        c3.gridy = 0;
+        c3.gridwidth = 1;
+        c3.gridheight = 1;
+        c3.weightx = 0;
+        c3.weighty = 1;
+        c3.anchor = GridBagConstraints.SOUTHWEST;
+        c3.fill = GridBagConstraints.NONE;
+        c3.insets = new Insets(5, 5, 5, 5);
+        c3.ipadx = 0;
+        c3.ipady = 0;
+        buttonsPanel.add(loadPropsFileButton, c3);
+        JButton saveDefaultPropsFileButton = new JButton("Set As Default");
+        saveDefaultPropsFileButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+
+                Properties connectionProps = getConnectionProps();
+                try {
+                    zooInspectorPanel
+                            .setdefaultConnectionProps(connectionProps);
+                } catch (IOException ex) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "An Error occurred saving the default connection properties file",
+                                    ex);
+                    JOptionPane
+                            .showMessageDialog(
+                                    ZooInspectorConnectionPropertiesDialog.this,
+                                    "An Error occurred saving the default connection properties file",
+                                    "Error", JOptionPane.ERROR_MESSAGE);
+                }
+            }
+        });
+        GridBagConstraints c6 = new GridBagConstraints();
+        c6.gridx = 1;
+        c6.gridy = 0;
+        c6.gridwidth = 1;
+        c6.gridheight = 1;
+        c6.weightx = 1;
+        c6.weighty = 1;
+        c6.anchor = GridBagConstraints.SOUTHWEST;
+        c6.fill = GridBagConstraints.NONE;
+        c6.insets = new Insets(5, 5, 5, 5);
+        c6.ipadx = 0;
+        c6.ipady = 0;
+        buttonsPanel.add(saveDefaultPropsFileButton, c6);
+        JButton okButton = new JButton("OK");
+        okButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorConnectionPropertiesDialog.this.dispose();
+                Properties connectionProps = getConnectionProps();
+                zooInspectorPanel.connect(connectionProps);
+            }
+        });
+        GridBagConstraints c4 = new GridBagConstraints();
+        c4.gridx = 2;
+        c4.gridy = 0;
+        c4.gridwidth = 1;
+        c4.gridheight = 1;
+        c4.weightx = 0;
+        c4.weighty = 1;
+        c4.anchor = GridBagConstraints.SOUTH;
+        c4.fill = GridBagConstraints.HORIZONTAL;
+        c4.insets = new Insets(5, 5, 5, 5);
+        c4.ipadx = 0;
+        c4.ipady = 0;
+        buttonsPanel.add(okButton, c4);
+        JButton cancelButton = new JButton("Cancel");
+        cancelButton.addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorConnectionPropertiesDialog.this.dispose();
+            }
+        });
+        GridBagConstraints c5 = new GridBagConstraints();
+        c5.gridx = 3;
+        c5.gridy = 0;
+        c5.gridwidth = 1;
+        c5.gridheight = 1;
+        c5.weightx = 0;
+        c5.weighty = 1;
+        c5.anchor = GridBagConstraints.SOUTH;
+        c5.fill = GridBagConstraints.HORIZONTAL;
+        c5.insets = new Insets(5, 5, 5, 5);
+        c5.ipadx = 0;
+        c5.ipady = 0;
+        buttonsPanel.add(cancelButton, c5);
+        this.add(options, BorderLayout.CENTER);
+        this.add(buttonsPanel, BorderLayout.SOUTH);
+        this.pack();
+    }
+
+    private void loadConnectionProps(Properties props) {
+        if (props != null) {
+            for (Object key : props.keySet()) {
+                String propsKey = (String) key;
+                if (components.containsKey(propsKey)) {
+                    JComponent component = components.get(propsKey);
+                    String value = props.getProperty(propsKey);
+                    if (component instanceof JTextField) {
+                        ((JTextField) component).setText(value);
+                    } else if (component instanceof JComboBox) {
+                        ((JComboBox) component).setSelectedItem(value);
+                    }
+                }
+            }
+        }
+    }
+
+    private Properties getConnectionProps() {
+        Properties connectionProps = new Properties();
+        for (Entry<String, JComponent> entry : components.entrySet()) {
+            String value = null;
+            JComponent component = entry.getValue();
+            if (component instanceof JTextField) {
+                value = ((JTextField) component).getText();
+            } else if (component instanceof JComboBox) {
+                value = ((JComboBox) component).getSelectedItem().toString();
+            }
+            connectionProps.put(entry.getKey(), value);
+        }
+        return connectionProps;
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java
new file mode 100644
index 0000000..e3cc7b1
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersDialog.java
@@ -0,0 +1,631 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Component;
+import java.awt.FlowLayout;
+import java.awt.Frame;
+import java.awt.GridBagConstraints;
+import java.awt.GridBagLayout;
+import java.awt.Insets;
+import java.awt.datatransfer.Transferable;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import javax.swing.DefaultListCellRenderer;
+import javax.swing.DefaultListModel;
+import javax.swing.DropMode;
+import javax.swing.ImageIcon;
+import javax.swing.JButton;
+import javax.swing.JComponent;
+import javax.swing.JDialog;
+import javax.swing.JFileChooser;
+import javax.swing.JLabel;
+import javax.swing.JList;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JTextField;
+import javax.swing.ListSelectionModel;
+import javax.swing.TransferHandler;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+
+import org.apache.zookeeper.inspector.gui.Toolbar.Button;
+import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer;
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
+
+/**
+ * A {@link JDialog} for configuring which {@link ZooInspectorNodeViewer}s to
+ * show in the application
+ */
+public class ZooInspectorNodeViewersDialog extends JDialog implements
+        ListSelectionListener {
+
+    private final JList viewersList;
+    private final JFileChooser fileChooser = new JFileChooser(new File("."));
+    private final Map<Button, JButton> buttons = new HashMap<Button, JButton>();
+    /**
+     * @param frame
+     *            - the Frame from which the dialog is displayed
+     * @param currentViewers
+     *            - the {@link ZooInspectorNodeViewer}s to show
+     * @param listeners
+     *            - the {@link NodeViewersChangeListener}s which need to be
+     *            notified of changes to the node viewers configuration
+     * @param manager
+     *            - the {@link ZooInspectorManager} for the application
+     * 
+     */
+    public ZooInspectorNodeViewersDialog(Frame frame,
+            final List<ZooInspectorNodeViewer> currentViewers,
+            final Collection<NodeViewersChangeListener> listeners,
+            final ZooInspectorManager manager,
+            final IconResource iconResource) {
+        super(frame);
+        final List<ZooInspectorNodeViewer> newViewers = new ArrayList<ZooInspectorNodeViewer>(
+                currentViewers);
+        this.setLayout(new BorderLayout());
+        this.setIconImage(iconResource.get(IconResource.ICON_ChangeNodeViewers,"")
+                .getImage());
+        this.setTitle("About ZooInspector");
+        this.setModal(true);
+        this.setAlwaysOnTop(true);
+        this.setResizable(true);
+        final JPanel panel = new JPanel();
+        panel.setLayout(new GridBagLayout());
+        viewersList = new JList();
+        DefaultListModel model = new DefaultListModel();
+        for (ZooInspectorNodeViewer viewer : newViewers) {
+            model.addElement(viewer);
+        }
+        viewersList.setModel(model);
+        viewersList.setCellRenderer(new DefaultListCellRenderer() {
+            @Override
+            public Component getListCellRendererComponent(JList list,
+                    Object value, int index, boolean isSelected,
+                    boolean cellHasFocus) {
+                ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) value;
+                JLabel label = (JLabel) super.getListCellRendererComponent(
+                        list, value, index, isSelected, cellHasFocus);
+                label.setText(viewer.getTitle());
+                return label;
+            }
+        });
+        viewersList.setDropMode(DropMode.INSERT);
+        viewersList.enableInputMethods(true);
+        viewersList.setDragEnabled(true);
+        viewersList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+        viewersList.getSelectionModel().addListSelectionListener(this);
+        viewersList.setTransferHandler(new TransferHandler() {
+
+            @Override
+            public boolean canImport(TransferHandler.TransferSupport info) {
+                // we only import NodeViewers
+                if (!info
+                        .isDataFlavorSupported(ZooInspectorNodeViewer.nodeViewerDataFlavor)) {
+                    return false;
+                }
+
+                JList.DropLocation dl = (JList.DropLocation) info
+                        .getDropLocation();
+                if (dl.getIndex() == -1) {
+                    return false;
+                }
+                return true;
+            }
+
+            @Override
+            public boolean importData(TransferHandler.TransferSupport info) {
+                JList.DropLocation dl = (JList.DropLocation) info
+                        .getDropLocation();
+                DefaultListModel listModel = (DefaultListModel) viewersList
+                        .getModel();
+                int index = dl.getIndex();
+                boolean insert = dl.isInsert();
+                // Get the string that is being dropped.
+                Transferable t = info.getTransferable();
+                String data;
+                try {
+                    data = (String) t
+                            .getTransferData(ZooInspectorNodeViewer.nodeViewerDataFlavor);
+                } catch (Exception e) {
+                    return false;
+                }
+                try {
+                    ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) Class
+                            .forName(data).newInstance();
+                    if (listModel.contains(viewer)) {
+                        listModel.removeElement(viewer);
+                    }
+                    if (insert) {
+                        listModel.add(index, viewer);
+                    } else {
+                        listModel.set(index, viewer);
+                    }
+                    return true;
+                } catch (Exception e) {
+                    LoggerFactory.getLogger().error(
+                            "Error instantiating class: " + data, e);
+                    return false;
+                }
+
+            }
+
+            @Override
+            public int getSourceActions(JComponent c) {
+                return MOVE;
+            }
+
+            @Override
+            protected Transferable createTransferable(JComponent c) {
+                JList list = (JList) c;
+                ZooInspectorNodeViewer value = (ZooInspectorNodeViewer) list
+                        .getSelectedValue();
+                return value;
+            }
+        });
+        JScrollPane scroller = new JScrollPane(viewersList);
+        GridBagConstraints c1 = new GridBagConstraints();
+        c1.gridx = 0;
+        c1.gridy = 0;
+        c1.gridwidth = 3;
+        c1.gridheight = 3;
+        c1.weightx = 0;
+        c1.weighty = 1;
+        c1.anchor = GridBagConstraints.CENTER;
+        c1.fill = GridBagConstraints.BOTH;
+        c1.insets = new Insets(5, 5, 5, 5);
+        c1.ipadx = 0;
+        c1.ipady = 0;
+        panel.add(scroller, c1);
+
+        final JTextField newViewerTextField = new JTextField();
+
+        for(Button button : Button.values()) {
+            JButton jbutton = button.createJButton(iconResource);
+            buttons.put(button, jbutton);
+        }
+        GridBagConstraints c2 = new GridBagConstraints();
+        c2.gridx = 3;
+        c2.gridy = 0;
+        c2.gridwidth = 1;
+        c2.gridheight = 1;
+        c2.weightx = 0;
+        c2.weighty = 0;
+        c2.anchor = GridBagConstraints.NORTH;
+        c2.fill = GridBagConstraints.HORIZONTAL;
+        c2.insets = new Insets(5, 5, 5, 5);
+        c2.ipadx = 0;
+        c2.ipady = 0;
+        panel.add(buttons.get(Button.up), c2);
+        GridBagConstraints c3 = new GridBagConstraints();
+        c3.gridx = 3;
+        c3.gridy = 2;
+        c3.gridwidth = 1;
+        c3.gridheight = 1;
+        c3.weightx = 0;
+        c3.weighty = 0;
+        c3.anchor = GridBagConstraints.NORTH;
+        c3.fill = GridBagConstraints.HORIZONTAL;
+        c3.insets = new Insets(5, 5, 5, 5);
+        c3.ipadx = 0;
+        c3.ipady = 0;
+        panel.add(buttons.get(Button.down), c3);
+        GridBagConstraints c4 = new GridBagConstraints();
+        c4.gridx = 3;
+        c4.gridy = 1;
+        c4.gridwidth = 1;
+        c4.gridheight = 1;
+        c4.weightx = 0;
+        c4.weighty = 0;
+        c4.anchor = GridBagConstraints.NORTH;
+        c4.fill = GridBagConstraints.HORIZONTAL;
+        c4.insets = new Insets(5, 5, 5, 5);
+        c4.ipadx = 0;
+        c4.ipady = 0;
+        panel.add(buttons.get(Button.remove), c4);
+        GridBagConstraints c5 = new GridBagConstraints();
+        c5.gridx = 0;
+        c5.gridy = 3;
+        c5.gridwidth = 3;
+        c5.gridheight = 1;
+        c5.weightx = 0;
+        c5.weighty = 0;
+        c5.anchor = GridBagConstraints.CENTER;
+        c5.fill = GridBagConstraints.BOTH;
+        c5.insets = new Insets(5, 5, 5, 5);
+        c5.ipadx = 0;
+        c5.ipady = 0;
+        panel.add(newViewerTextField, c5);
+        GridBagConstraints c6 = new GridBagConstraints();
+        c6.gridx = 3;
+        c6.gridy = 3;
+        c6.gridwidth = 1;
+        c6.gridheight = 1;
+        c6.weightx = 0;
+        c6.weighty = 0;
+        c6.anchor = GridBagConstraints.CENTER;
+        c6.fill = GridBagConstraints.BOTH;
+        c6.insets = new Insets(5, 5, 5, 5);
+        c6.ipadx = 0;
+        c6.ipady = 0;
+        panel.add(buttons.get(Button.add), c6);
+        buttons.get(Button.up).addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                DefaultListModel listModel = (DefaultListModel) viewersList
+                        .getModel();
+                ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) viewersList
+                        .getSelectedValue();
+                int index = viewersList.getSelectedIndex();
+                if (listModel.contains(viewer)) {
+                    listModel.removeElementAt(index);
+                    listModel.insertElementAt(viewer, index - 1);
+                    viewersList.setSelectedValue(viewer, true);
+                }
+            }
+        });
+        buttons.get(Button.down).addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                DefaultListModel listModel = (DefaultListModel) viewersList
+                        .getModel();
+                ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) viewersList
+                        .getSelectedValue();
+                int index = viewersList.getSelectedIndex();
+                if (listModel.contains(viewer)) {
+                    listModel.removeElementAt(index);
+                    listModel.insertElementAt(viewer, index + 1);
+                    viewersList.setSelectedValue(viewer, true);
+                }
+            }
+        });
+        buttons.get(Button.remove).addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                DefaultListModel listModel = (DefaultListModel) viewersList
+                        .getModel();
+                ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) viewersList
+                        .getSelectedValue();
+                int index = viewersList.getSelectedIndex();
+                if (listModel.contains(viewer)) {
+                    listModel.removeElement(viewer);
+                    viewersList
+                            .setSelectedIndex(index == listModel.size() ? index - 1
+                                    : index);
+                }
+            }
+        });
+        buttons.get(Button.add).addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                String className = newViewerTextField.getText();
+                if (className == null || className.length() == 0) {
+                    JOptionPane
+                            .showMessageDialog(
+                                    ZooInspectorNodeViewersDialog.this,
+                                    "Please enter the full class name for a Node Viewer and click the add button",
+                                    "Input Error", JOptionPane.ERROR_MESSAGE);
+                } else {
+                    try {
+                        DefaultListModel listModel = (DefaultListModel) viewersList
+                                .getModel();
+                        ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) Class
+                                .forName(className).newInstance();
+                        if (listModel.contains(viewer)) {
+                            JOptionPane
+                                    .showMessageDialog(
+                                            ZooInspectorNodeViewersDialog.this,
+                                            "Node viewer already exists.  Each node viewer can only be added once.",
+                                            "Input Error",
+                                            JOptionPane.ERROR_MESSAGE);
+                        } else {
+                            listModel.addElement(viewer);
+                        }
+                    } catch (Exception ex) {
+                        LoggerFactory
+                                .getLogger()
+                                .error(
+                                        "An error occurred while instaniating the node viewer. ",
+                                        ex);
+                        JOptionPane.showMessageDialog(
+                                ZooInspectorNodeViewersDialog.this,
+                                "An error occurred while instaniating the node viewer: "
+                                        + ex.getMessage(), "Error",
+                                JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+
+        GridBagConstraints c7 = new GridBagConstraints();
+        c7.gridx = 0;
+        c7.gridy = 4;
+        c7.gridwidth = 1;
+        c7.gridheight = 1;
+        c7.weightx = 1;
+        c7.weighty = 0;
+        c7.anchor = GridBagConstraints.WEST;
+        c7.fill = GridBagConstraints.VERTICAL;
+        c7.insets = new Insets(5, 5, 5, 5);
+        c7.ipadx = 0;
+        c7.ipady = 0;
+        panel.add(buttons.get(Button.save), c7);
+        GridBagConstraints c8 = new GridBagConstraints();
+        c8.gridx = 1;
+        c8.gridy = 4;
+        c8.gridwidth = 1;
+        c8.gridheight = 1;
+        c8.weightx = 0;
+        c8.weighty = 0;
+        c8.anchor = GridBagConstraints.WEST;
+        c8.fill = GridBagConstraints.VERTICAL;
+        c8.insets = new Insets(5, 5, 5, 5);
+        c8.ipadx = 0;
+        c8.ipady = 0;
+        panel.add(buttons.get(Button.load), c8);
+        GridBagConstraints c9 = new GridBagConstraints();
+        c9.gridx = 2;
+        c9.gridy = 4;
+        c9.gridwidth = 1;
+        c9.gridheight = 1;
+        c9.weightx = 0;
+        c9.weighty = 0;
+        c9.anchor = GridBagConstraints.WEST;
+        c9.fill = GridBagConstraints.VERTICAL;
+        c9.insets = new Insets(5, 5, 5, 5);
+        c9.ipadx = 0;
+        c9.ipady = 0;
+        panel.add(buttons.get(Button.setDefaults), c9);
+        buttons.get(Button.save).addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                int result = fileChooser
+                        .showSaveDialog(ZooInspectorNodeViewersDialog.this);
+                if (result == JFileChooser.APPROVE_OPTION) {
+                    File selectedFile = fileChooser.getSelectedFile();
+                    int answer = JOptionPane.YES_OPTION;
+                    if (selectedFile.exists()) {
+                        answer = JOptionPane
+                                .showConfirmDialog(
+                                        ZooInspectorNodeViewersDialog.this,
+                                        "The specified file already exists.  do you want to overwrite it?",
+                                        "Confirm Overwrite",
+                                        JOptionPane.YES_NO_OPTION,
+                                        JOptionPane.WARNING_MESSAGE);
+                    }
+                    if (answer == JOptionPane.YES_OPTION) {
+                        DefaultListModel listModel = (DefaultListModel) viewersList
+                                .getModel();
+                        List<String> nodeViewersClassNames = new ArrayList<String>();
+                        Object[] modelContents = listModel.toArray();
+                        for (Object o : modelContents) {
+                            nodeViewersClassNames
+                                    .add(((ZooInspectorNodeViewer) o)
+                                            .getClass().getCanonicalName());
+                        }
+                        try {
+                            manager.saveNodeViewersFile(selectedFile,
+                                    nodeViewersClassNames);
+                        } catch (IOException ex) {
+                            LoggerFactory
+                                    .getLogger()
+                                    .error(
+                                            "Error saving node viewer configuration from file.",
+                                            ex);
+                            JOptionPane.showMessageDialog(
+                                    ZooInspectorNodeViewersDialog.this,
+                                    "Error saving node viewer configuration from file: "
+                                            + ex.getMessage(), "Error",
+                                    JOptionPane.ERROR_MESSAGE);
+                        }
+                    }
+                }
+            }
+        });
+        buttons.get(Button.load).addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                int result = fileChooser
+                        .showOpenDialog(ZooInspectorNodeViewersDialog.this);
+                if (result == JFileChooser.APPROVE_OPTION) {
+                    try {
+                        List<String> nodeViewersClassNames = manager
+                                .loadNodeViewersFile(fileChooser
+                                        .getSelectedFile());
+                        List<ZooInspectorNodeViewer> nodeViewers = new ArrayList<ZooInspectorNodeViewer>();
+                        for (String nodeViewersClassName : nodeViewersClassNames) {
+                            ZooInspectorNodeViewer viewer = (ZooInspectorNodeViewer) Class
+                                    .forName(nodeViewersClassName)
+                                    .newInstance();
+                            nodeViewers.add(viewer);
+                        }
+                        DefaultListModel model = new DefaultListModel();
+                        for (ZooInspectorNodeViewer viewer : nodeViewers) {
+                            model.addElement(viewer);
+                        }
+                        viewersList.setModel(model);
+                        panel.revalidate();
+                        panel.repaint();
+                    } catch (Exception ex) {
+                        LoggerFactory
+                                .getLogger()
+                                .error(
+                                        "Error loading node viewer configuration from file.",
+                                        ex);
+                        JOptionPane.showMessageDialog(
+                                ZooInspectorNodeViewersDialog.this,
+                                "Error loading node viewer configuration from file: "
+                                        + ex.getMessage(), "Error",
+                                JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+        buttons.get(Button.setDefaults).addActionListener(new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                int answer = JOptionPane
+                        .showConfirmDialog(
+                                ZooInspectorNodeViewersDialog.this,
+                                "Are you sure you want to save this configuration as the default?",
+                                "Confirm Set Defaults",
+                                JOptionPane.YES_NO_OPTION,
+                                JOptionPane.WARNING_MESSAGE);
+                if (answer == JOptionPane.YES_OPTION) {
+                    DefaultListModel listModel = (DefaultListModel) viewersList
+                            .getModel();
+                    List<String> nodeViewersClassNames = new ArrayList<String>();
+                    Object[] modelContents = listModel.toArray();
+                    for (Object o : modelContents) {
+                        nodeViewersClassNames.add(((ZooInspectorNodeViewer) o)
+                                .getClass().getCanonicalName());
+                    }
+                    try {
+                        manager
+                                .setDefaultNodeViewerConfiguration(nodeViewersClassNames);
+                    } catch (IOException ex) {
+                        LoggerFactory
+                                .getLogger()
+                                .error(
+                                        "Error setting default node viewer configuration.",
+                                        ex);
+                        JOptionPane.showMessageDialog(
+                                ZooInspectorNodeViewersDialog.this,
+                                "Error setting default node viewer configuration: "
+                                        + ex.getMessage(), "Error",
+                                JOptionPane.ERROR_MESSAGE);
+                    }
+                }
+            }
+        });
+
+        JPanel buttonsPanel = new JPanel();
+        buttonsPanel.setLayout(new FlowLayout(FlowLayout.CENTER, 10, 10));
+        JButton okButton = new JButton("OK");
+        okButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorNodeViewersDialog.this.dispose();
+                DefaultListModel listModel = (DefaultListModel) viewersList
+                        .getModel();
+                newViewers.clear();
+                Object[] modelContents = listModel.toArray();
+                for (Object o : modelContents) {
+                    newViewers.add((ZooInspectorNodeViewer) o);
+                }
+                currentViewers.clear();
+                currentViewers.addAll(newViewers);
+                for (NodeViewersChangeListener listener : listeners) {
+                    listener.nodeViewersChanged(currentViewers);
+                }
+            }
+        });
+        buttonsPanel.add(okButton);
+        JButton cancelButton = new JButton("Cancel");
+        cancelButton.addActionListener(new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorNodeViewersDialog.this.dispose();
+            }
+        });
+        buttonsPanel.add(cancelButton);
+        this.add(panel, BorderLayout.CENTER);
+        this.add(buttonsPanel, BorderLayout.SOUTH);
+        this.pack();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * javax.swing.event.ListSelectionListener#valueChanged(javax.swing.event
+     * .ListSelectionEvent)
+     */
+    public void valueChanged(ListSelectionEvent e) {
+        JButton removeButton = buttons.get(Button.remove);
+        JButton upButton = buttons.get(Button.up);
+        JButton downButton = buttons.get(Button.down);
+        int index = viewersList.getSelectedIndex();
+
+        if (index == -1) {
+            removeButton.setEnabled(false);
+            upButton.setEnabled(false);
+            downButton.setEnabled(false);
+        } else {
+            removeButton.setEnabled(true);
+            if (index == 0) {
+                upButton.setEnabled(false);
+            } else {
+                upButton.setEnabled(true);
+            }
+            if (index == ((DefaultListModel) viewersList.getModel()).getSize()) {
+                downButton.setEnabled(false);
+            } else {
+                downButton.setEnabled(true);
+            }
+        }
+    }
+
+    public static enum Button {
+        up("Move currently selected node viewer up",IconResource.ICON_UP,false),
+        down("Move currently selected node viewer down",IconResource.ICON_DOWN,false),
+        add("Add node viewer",IconResource.ICON_ADD,true),
+        remove("Remove currently selected node viewer",IconResource.ICON_REMOVE,false),
+        save("Save current node viewer configuration to file","Save"),
+        load("Load node viewer configuration from file","Load"),
+        setDefaults("Set current configuration asd defaults","Set as defaults");
+
+        private String toolTip;
+        private String icon;
+        private boolean enabled;
+
+        Button(String toolTip, String icon, boolean enabled) {
+            this.toolTip = toolTip;
+            this.icon = icon;
+            this.enabled = enabled;
+        }
+
+        Button(String toolTip, String icon) {
+            this(toolTip, icon, true);
+        }
+
+        public JButton createJButton(IconResource iconResource) {
+            ImageIcon imageIcon = iconResource.get(icon, toolTip);
+            JButton jbutton;
+
+            if(imageIcon == null) {
+                jbutton = new JButton(icon);
+            } else {
+                jbutton = new JButton(imageIcon);
+            }
+
+            jbutton.setEnabled(enabled);
+            jbutton.setToolTipText(toolTip);
+            return jbutton;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java
new file mode 100644
index 0000000..05c256b
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorNodeViewersPanel.java
@@ -0,0 +1,140 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.BorderLayout;
+import java.util.ArrayList;
+import java.util.List;
+
+import javax.swing.JPanel;
+import javax.swing.JTabbedPane;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.TreePath;
+
+import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
+import org.apache.zookeeper.inspector.manager.ZooInspectorNodeManager;
+
+/**
+ * This is the {@link JPanel} which contains the {@link ZooInspectorNodeViewer}s
+ */
+public class ZooInspectorNodeViewersPanel extends JPanel implements
+        TreeSelectionListener, ChangeListener {
+
+    private final List<ZooInspectorNodeViewer> nodeVeiwers = new ArrayList<ZooInspectorNodeViewer>();
+    private final List<Boolean> needsReload = new ArrayList<Boolean>();
+    private final JTabbedPane tabbedPane;
+    private final List<String> selectedNodes = new ArrayList<String>();
+    private final ZooInspectorNodeManager zooInspectorManager;
+
+    /**
+     * @param zooInspectorManager
+     *            - the {@link ZooInspectorManager} for the application
+     * @param nodeVeiwers
+     *            - the {@link ZooInspectorNodeViewer}s to show
+     */
+    public ZooInspectorNodeViewersPanel(
+            ZooInspectorNodeManager zooInspectorManager,
+            List<ZooInspectorNodeViewer> nodeVeiwers) {
+        this.zooInspectorManager = zooInspectorManager;
+        this.setLayout(new BorderLayout());
+        tabbedPane = new JTabbedPane(JTabbedPane.TOP,
+                JTabbedPane.WRAP_TAB_LAYOUT);
+        setNodeViewers(nodeVeiwers);
+        tabbedPane.addChangeListener(this);
+        this.add(tabbedPane, BorderLayout.CENTER);
+        reloadSelectedViewer();
+    }
+
+    /**
+     * @param nodeViewers
+     *            - the {@link ZooInspectorNodeViewer}s to show
+     */
+    public void setNodeViewers(List<ZooInspectorNodeViewer> nodeViewers) {
+        this.nodeVeiwers.clear();
+        this.nodeVeiwers.addAll(nodeViewers);
+        needsReload.clear();
+        tabbedPane.removeAll();
+        for (ZooInspectorNodeViewer nodeViewer : nodeVeiwers) {
+            nodeViewer.setZooInspectorManager(zooInspectorManager);
+            needsReload.add(true);
+            tabbedPane.add(nodeViewer.getTitle(), nodeViewer);
+        }
+        this.revalidate();
+        this.repaint();
+    }
+
+    private void reloadSelectedViewer() {
+        int index = this.tabbedPane.getSelectedIndex();
+        if (index != -1 && this.needsReload.get(index)) {
+            ZooInspectorNodeViewer viewer = this.nodeVeiwers.get(index);
+            viewer.nodeSelectionChanged(selectedNodes);
+            this.needsReload.set(index, false);
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * javax.swing.event.TreeSelectionListener#valueChanged(javax.swing.event
+     * .TreeSelectionEvent)
+     */
+    public void valueChanged(TreeSelectionEvent e) {
+        TreePath[] paths = e.getPaths();
+        selectedNodes.clear();
+        for (TreePath path : paths) {
+            boolean appended = false;
+            StringBuilder sb = new StringBuilder();
+            Object[] pathArray = path.getPath();
+            for (Object o : pathArray) {
+                if (o != null) {
+                    String nodeName = o.toString();
+                    if (nodeName != null) {
+                        if (nodeName.length() > 0) {
+                            appended = true;
+                            sb.append("/"); //$NON-NLS-1$
+                            sb.append(o.toString());
+                        }
+                    }
+                }
+            }
+            if (appended) {
+                selectedNodes.add(sb.toString());
+            }
+        }
+        for (int i = 0; i < needsReload.size(); i++) {
+            this.needsReload.set(i, true);
+        }
+        reloadSelectedViewer();
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @see
+     * javax.swing.event.ChangeListener#stateChanged(javax.swing.event.ChangeEvent
+     * )
+     */
+    public void stateChanged(ChangeEvent e) {
+        reloadSelectedViewer();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/b0df8fe1/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
----------------------------------------------------------------------
diff --git a/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
new file mode 100644
index 0000000..e816ceb
--- /dev/null
+++ b/zookeeper-contrib/zookeeper-contrib-zooinspector/src/main/java/org/apache/zookeeper/inspector/gui/ZooInspectorPanel.java
@@ -0,0 +1,258 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.zookeeper.inspector.gui;
+
+import java.awt.BorderLayout;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.ExecutionException;
+
+import javax.swing.JButton;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JScrollPane;
+import javax.swing.JSplitPane;
+import javax.swing.JToolBar;
+import javax.swing.SwingWorker;
+
+import org.apache.zookeeper.inspector.gui.actions.AddNodeAction;
+import org.apache.zookeeper.inspector.gui.actions.DeleteNodeAction;
+import org.apache.zookeeper.inspector.gui.nodeviewer.ZooInspectorNodeViewer;
+import org.apache.zookeeper.inspector.logger.LoggerFactory;
+import org.apache.zookeeper.inspector.manager.ZooInspectorManager;
+
+/**
+ * The parent {@link JPanel} for the whole application
+ */
+public class ZooInspectorPanel extends JPanel implements
+        NodeViewersChangeListener {
+    private final IconResource iconResource;
+    private final Toolbar toolbar;
+    private final ZooInspectorNodeViewersPanel nodeViewersPanel;
+    private final ZooInspectorTreeViewer treeViewer;
+    private final ZooInspectorManager zooInspectorManager;
+
+    private final List<NodeViewersChangeListener> listeners = new ArrayList<NodeViewersChangeListener>();
+    {
+        listeners.add(this);
+    }
+
+    /**
+     * @param zooInspectorManager
+     *            - the {@link ZooInspectorManager} for the application
+     */
+    public ZooInspectorPanel(final ZooInspectorManager zooInspectorManager, final IconResource iconResource) {
+        this.zooInspectorManager = zooInspectorManager;
+        this.iconResource = iconResource;
+        toolbar = new Toolbar(iconResource);
+        final List<ZooInspectorNodeViewer> nodeViewers = new ArrayList<ZooInspectorNodeViewer>();
+        try {
+            List<String> defaultNodeViewersClassNames = this.zooInspectorManager
+                    .getDefaultNodeViewerConfiguration();
+            for (String className : defaultNodeViewersClassNames) {
+                nodeViewers.add((ZooInspectorNodeViewer) Class.forName(
+                        className).newInstance());
+            }
+        } catch (Exception ex) {
+            LoggerFactory.getLogger().error(
+                    "Error loading default node viewers.", ex);
+            JOptionPane.showMessageDialog(ZooInspectorPanel.this,
+                    "Error loading default node viewers: " + ex.getMessage(),
+                    "Error", JOptionPane.ERROR_MESSAGE);
+        }
+        nodeViewersPanel = new ZooInspectorNodeViewersPanel(
+                zooInspectorManager, nodeViewers);
+        treeViewer = new ZooInspectorTreeViewer(zooInspectorManager,
+                nodeViewersPanel, iconResource);
+        this.setLayout(new BorderLayout());
+        
+        toolbar.addActionListener(Toolbar.Button.connect, new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorConnectionPropertiesDialog zicpd = new ZooInspectorConnectionPropertiesDialog(
+                        zooInspectorManager.getLastConnectionProps(),
+                        zooInspectorManager.getConnectionPropertiesTemplate(),
+                        ZooInspectorPanel.this);
+                zicpd.setVisible(true);
+            }
+        });
+        toolbar.addActionListener(Toolbar.Button.disconnect, new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                disconnect();
+            }
+        });
+        toolbar.addActionListener(Toolbar.Button.refresh, new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                treeViewer.refreshView();
+            }
+        });
+
+        toolbar.addActionListener(Toolbar.Button.addNode,
+                    new AddNodeAction(this, treeViewer, zooInspectorManager));
+        toolbar.addActionListener(Toolbar.Button.deleteNode,
+                    new DeleteNodeAction(this, treeViewer, zooInspectorManager));
+
+        toolbar.addActionListener(Toolbar.Button.nodeViewers, new ActionListener() {
+
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorNodeViewersDialog nvd = new ZooInspectorNodeViewersDialog(
+                        JOptionPane.getRootFrame(), nodeViewers, listeners,
+                        zooInspectorManager, iconResource);
+                nvd.setVisible(true);
+            }
+        });
+        toolbar.addActionListener(Toolbar.Button.about, new ActionListener() {
+            public void actionPerformed(ActionEvent e) {
+                ZooInspectorAboutDialog zicpd = new ZooInspectorAboutDialog(
+                        JOptionPane.getRootFrame(), iconResource);
+                zicpd.setVisible(true);
+            }
+        });
+        JScrollPane treeScroller = new JScrollPane(treeViewer);
+        JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT,
+                treeScroller, nodeViewersPanel);
+        splitPane.setResizeWeight(0.25);
+        this.add(splitPane, BorderLayout.CENTER);
+        this.add(toolbar.getJToolBar(), BorderLayout.NORTH);
+    }
+
+    /**
+     * @param connectionProps
+     *            the {@link Properties} for connecting to the zookeeper
+     *            instance
+     */
+    public void connect(final Properties connectionProps) {
+        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+            @Override
+            protected Boolean doInBackground() throws Exception {
+                zooInspectorManager.setLastConnectionProps(connectionProps);
+                return zooInspectorManager.connect(connectionProps);
+            }
+
+            @Override
+            protected void done() {
+                try {
+                    if (get()) {
+                        treeViewer.refreshView();
+                        toolbar.toggleButtons(true);
+                    } else {
+                        JOptionPane.showMessageDialog(ZooInspectorPanel.this,
+                                "Unable to connect to zookeeper", "Error",
+                                JOptionPane.ERROR_MESSAGE);
+                    }
+                } catch (InterruptedException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while connecting to ZooKeeper server",
+                                    e);
+                } catch (ExecutionException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while connecting to ZooKeeper server",
+                                    e);
+                }
+            }
+
+        };
+        worker.execute();
+    }
+
+    /**
+	 * 
+	 */
+    public void disconnect() {
+        disconnect(false);
+    }
+
+    /**
+     * @param wait
+     *            - set this to true if the method should only return once the
+     *            application has successfully disconnected
+     */
+    public void disconnect(boolean wait) {
+        SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() {
+
+            @Override
+            protected Boolean doInBackground() throws Exception {
+                return ZooInspectorPanel.this.zooInspectorManager.disconnect();
+            }
+
+            @Override
+            protected void done() {
+                try {
+                    if (get()) {
+                        treeViewer.clearView();
+                        toolbar.toggleButtons(false);
+                    }
+                } catch (InterruptedException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while disconnecting from ZooKeeper server",
+                                    e);
+                } catch (ExecutionException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while disconnecting from ZooKeeper server",
+                                    e);
+                }
+            }
+
+        };
+        worker.execute();
+        if (wait) {
+            while (!worker.isDone()) {
+                try {
+                    Thread.sleep(100);
+                } catch (InterruptedException e) {
+                    LoggerFactory
+                            .getLogger()
+                            .error(
+                                    "Error occurred while disconnecting from ZooKeeper server",
+                                    e);
+                }
+            }
+        }
+    }
+
+    /*
+     * (non-Javadoc)
+     * 
+     * @seeorg.apache.zookeeper.inspector.gui.NodeViewersChangeListener#
+     * nodeViewersChanged(java.util.List)
+     */
+    public void nodeViewersChanged(List<ZooInspectorNodeViewer> newViewers) {
+        this.nodeViewersPanel.setNodeViewers(newViewers);
+    }
+
+    /**
+     * @param connectionProps
+     * @throws IOException
+     */
+    public void setdefaultConnectionProps(Properties connectionProps)
+            throws IOException {
+        this.zooInspectorManager.saveDefaultConnectionFile(connectionProps);
+    }
+}


Mime
View raw message