/** * 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.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 JButton refreshButton; private final JButton disconnectButton; private final JButton connectButton; private final ZooInspectorNodeViewersPanel nodeViewersPanel; private final ZooInspectorTreeViewer treeViewer; private final ZooInspectorManager zooInspectorManager; private final JButton addNodeButton; private final JButton deleteNodeButton; private final JButton nodeViewersButton; private final JButton aboutButton; private final List<NodeViewersChangeListener> listeners = new ArrayList<NodeViewersChangeListener>(); { listeners.add(this); } /** * @param zooInspectorManager * - the {@link ZooInspectorManager} for the application */ public ZooInspectorPanel(final ZooInspectorManager zooInspectorManager) { this.zooInspectorManager = zooInspectorManager; final ArrayList<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); this.setLayout(new BorderLayout()); JToolBar toolbar = new JToolBar(); toolbar.setFloatable(false); connectButton = new JButton(ZooInspectorIconResources.getConnectIcon()); disconnectButton = new JButton(ZooInspectorIconResources .getDisconnectIcon()); refreshButton = new JButton(ZooInspectorIconResources.getRefreshIcon()); addNodeButton = new JButton(ZooInspectorIconResources.getAddNodeIcon()); deleteNodeButton = new JButton(ZooInspectorIconResources .getDeleteNodeIcon()); nodeViewersButton = new JButton(ZooInspectorIconResources .getChangeNodeViewersIcon()); aboutButton = new JButton(ZooInspectorIconResources .getInformationIcon()); toolbar.add(connectButton); toolbar.add(disconnectButton); toolbar.add(refreshButton); toolbar.add(addNodeButton); toolbar.add(deleteNodeButton); toolbar.add(nodeViewersButton); toolbar.add(aboutButton); aboutButton.setEnabled(true); connectButton.setEnabled(true); disconnectButton.setEnabled(false); refreshButton.setEnabled(false); addNodeButton.setEnabled(false); deleteNodeButton.setEnabled(false); nodeViewersButton.setEnabled(true); nodeViewersButton.setToolTipText("Change Node Viewers"); aboutButton.setToolTipText("About ZooInspector"); connectButton.setToolTipText("Connect"); disconnectButton.setToolTipText("Disconnect"); refreshButton.setToolTipText("Refresh"); addNodeButton.setToolTipText("Add Node"); deleteNodeButton.setToolTipText("Delete Node"); connectButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ZooInspectorConnectionPropertiesDialog zicpd = new ZooInspectorConnectionPropertiesDialog( zooInspectorManager.getLastConnectionProps(), zooInspectorManager.getConnectionPropertiesTemplate(), ZooInspectorPanel.this); zicpd.setVisible(true); } }); disconnectButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { disconnect(); } }); refreshButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { treeViewer.refreshView(); } }); addNodeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final List<String> selectedNodes = treeViewer .getSelectedNodes(); if (selectedNodes.size() == 1) { final String nodeName = JOptionPane.showInputDialog( ZooInspectorPanel.this, "Please Enter a name for the new node", "Create Node", JOptionPane.INFORMATION_MESSAGE); if (nodeName != null && nodeName.length() > 0) { SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { @Override protected Boolean doInBackground() throws Exception { return ZooInspectorPanel.this.zooInspectorManager .createNode(selectedNodes.get(0), nodeName); } @Override protected void done() { treeViewer.refreshView(); } }; worker.execute(); } } else { JOptionPane.showMessageDialog(ZooInspectorPanel.this, "Please select 1 parent node for the new node."); } } }); deleteNodeButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { final List<String> selectedNodes = treeViewer .getSelectedNodes(); if (selectedNodes.size() == 0) { JOptionPane.showMessageDialog(ZooInspectorPanel.this, "Please select at least 1 node to be deleted"); } else { int answer = JOptionPane.showConfirmDialog( ZooInspectorPanel.this, "Are you sure you want to delete the selected nodes?" + "(This action cannot be reverted)", "Confirm Delete", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); if (answer == JOptionPane.YES_OPTION) { SwingWorker<Boolean, Void> worker = new SwingWorker<Boolean, Void>() { @Override protected Boolean doInBackground() throws Exception { for (String nodePath : selectedNodes) { ZooInspectorPanel.this.zooInspectorManager .deleteNode(nodePath); } return true; } @Override protected void done() { treeViewer.refreshView(); } }; worker.execute(); } } } }); nodeViewersButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ZooInspectorNodeViewersDialog nvd = new ZooInspectorNodeViewersDialog( JOptionPane.getRootFrame(), nodeViewers, listeners, zooInspectorManager); nvd.setVisible(true); } }); aboutButton.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { ZooInspectorAboutDialog zicpd = new ZooInspectorAboutDialog( JOptionPane.getRootFrame()); 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, 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(); connectButton.setEnabled(false); disconnectButton.setEnabled(true); refreshButton.setEnabled(true); addNodeButton.setEnabled(true); deleteNodeButton.setEnabled(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(); connectButton.setEnabled(true); disconnectButton.setEnabled(false); refreshButton.setEnabled(false); addNodeButton.setEnabled(false); deleteNodeButton.setEnabled(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); } }