blob: 8764cd1b1d2209f3cbcf2d93f479b57401bfaff3 [file] [log] [blame]
/*
* 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.log4j.chainsaw.receivers;
import org.apache.log4j.Level;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import org.apache.log4j.chainsaw.PopupListener;
import org.apache.log4j.chainsaw.SmallButton;
import org.apache.log4j.chainsaw.help.HelpManager;
import org.apache.log4j.chainsaw.helper.SwingHelper;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
import org.apache.log4j.chainsaw.icons.LevelIconFactory;
import org.apache.log4j.chainsaw.icons.LineIconFactory;
import org.apache.log4j.chainsaw.messages.MessageCenter;
import org.apache.log4j.chainsaw.prefs.LoadSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SaveSettingsEvent;
import org.apache.log4j.chainsaw.prefs.SettingsListener;
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.net.SocketNodeEventListener;
import org.apache.log4j.plugins.*;
import org.apache.log4j.spi.LoggerRepository;
import org.apache.log4j.spi.LoggerRepositoryEx;
import javax.swing.*;
import javax.swing.event.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.ExpandVetoException;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import java.io.File;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;
/**
* This panel is used to manage all the Receivers configured within Log4j
*
* @author Paul Smith <psmith@apache.org>
* @author Scott Deboy <sdeboy@apache.org>
*/
public class ReceiversPanel extends JPanel implements SettingsListener {
final Action newReceiverButtonAction;
final Action pauseReceiverButtonAction;
final Action playReceiverButtonAction;
final Action shutdownReceiverButtonAction;
final Action saveReceiversButtonAction;
final Action restartReceiverButtonAction;
private final Action showReceiverHelpAction;
private final Action startAllAction;
private final JPopupMenu popupMenu = new ReceiverPopupMenu();
private final JTree receiversTree = new JTree();
private final NewReceiverPopupMenu newReceiverPopup =
new NewReceiverPopupMenu();
private final ReceiverToolbar buttonPanel;
private final JSplitPane splitter = new JSplitPane();
private final PluginPropertyEditorPanel pluginEditorPanel =
new PluginPropertyEditorPanel();
private final Logger logger = LogManager.getLogger(ReceiversPanel.class);
private final PluginRegistry pluginRegistry;
public ReceiversPanel() {
super(new BorderLayout());
LoggerRepository repo = LogManager.getLoggerRepository();
final ReceiversTreeModel model = new ReceiversTreeModel();
if (repo instanceof LoggerRepositoryEx) {
pluginRegistry = ((LoggerRepositoryEx) repo).getPluginRegistry();
pluginRegistry.addPluginListener(model);
//iterate over visual receivers and call setcontainer
Collection c = pluginRegistry.getPlugins(VisualReceiver.class);
for (Object aC : c) {
((VisualReceiver) aC).setContainer(this);
}
pluginRegistry.addPluginListener(new PluginListener() {
public void pluginStarted(PluginEvent e) {
//if we get a plugin started callback, set the container
if (e.getPlugin() instanceof VisualReceiver) {
((VisualReceiver) e.getPlugin()).setContainer(ReceiversPanel.this);
}
}
public void pluginStopped(PluginEvent e) {
}
});
} else {
pluginRegistry = null;
}
receiversTree.setModel(model);
receiversTree.setExpandsSelectedPaths(true);
model.addTreeModelListener(
new TreeModelListener() {
public void treeNodesChanged(TreeModelEvent e) {
expandRoot();
}
public void treeNodesInserted(TreeModelEvent e) {
expandRoot();
}
public void treeNodesRemoved(TreeModelEvent e) {
expandRoot();
}
public void treeStructureChanged(TreeModelEvent e) {
expandRoot();
}
private void expandRoot() {
receiversTree.expandPath(
new TreePath(model.getPathToRoot(model.RootNode)));
}
});
receiversTree.expandPath(
new TreePath(model.getPathToRoot(model.RootNode)));
receiversTree.addTreeWillExpandListener(
new TreeWillExpandListener() {
public void treeWillCollapse(TreeExpansionEvent event)
throws ExpandVetoException {
if (event.getPath().getLastPathComponent() == model.RootNode) {
throw new ExpandVetoException(event);
}
}
public void treeWillExpand(TreeExpansionEvent event) {
}
});
receiversTree.addTreeSelectionListener(
e -> {
TreePath path = e.getNewLeadSelectionPath();
if (path != null) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) path.getLastPathComponent();
if (
(node != null) && (node.getUserObject() != null)
&& (node.getUserObject() instanceof Plugin)) {
Plugin p = (Plugin) node.getUserObject();
logger.debug("plugin=" + p);
pluginEditorPanel.setPlugin(p);
} else {
pluginEditorPanel.setPlugin(null);
}
}
});
receiversTree.setToolTipText("Allows you to manage Log4j Receivers");
newReceiverButtonAction =
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
newReceiverPopup.show(
buttonPanel.newReceiverButton, 0,
buttonPanel.newReceiverButton.getHeight());
}
};
newReceiverButtonAction.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_NEW_RECEIVER));
newReceiverButtonAction.putValue(
Action.SHORT_DESCRIPTION, "Creates and configures a new Receiver");
newReceiverButtonAction.putValue(Action.NAME, "New Receiver");
newReceiverButtonAction.putValue(
Action.MNEMONIC_KEY, KeyEvent.VK_N);
newReceiverButtonAction.setEnabled(true);
playReceiverButtonAction =
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
playCurrentlySelectedReceiver();
}
};
playReceiverButtonAction.putValue(
Action.SHORT_DESCRIPTION, "Resumes the selected Node");
playReceiverButtonAction.putValue(Action.NAME, "Resume");
playReceiverButtonAction.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_RESUME_RECEIVER));
playReceiverButtonAction.setEnabled(false);
playReceiverButtonAction.putValue(
Action.MNEMONIC_KEY, KeyEvent.VK_R);
pauseReceiverButtonAction =
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
pauseCurrentlySelectedReceiver();
}
};
pauseReceiverButtonAction.putValue(
Action.SHORT_DESCRIPTION,
"Pause the selected Receiver. All events received will be discarded.");
pauseReceiverButtonAction.putValue(Action.NAME, "Pause");
pauseReceiverButtonAction.putValue(
Action.MNEMONIC_KEY, KeyEvent.VK_P);
pauseReceiverButtonAction.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.PAUSE));
pauseReceiverButtonAction.setEnabled(false);
shutdownReceiverButtonAction =
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
shutdownCurrentlySelectedReceiver();
}
};
shutdownReceiverButtonAction.putValue(
Action.SHORT_DESCRIPTION,
"Shuts down the selected Receiver, and removes it from the Plugin registry");
shutdownReceiverButtonAction.putValue(Action.NAME, "Shutdown");
shutdownReceiverButtonAction.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_STOP_RECEIVER));
shutdownReceiverButtonAction.putValue(
Action.MNEMONIC_KEY, KeyEvent.VK_S);
shutdownReceiverButtonAction.setEnabled(false);
saveReceiversButtonAction =
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
saveReceivers();
}
};
saveReceiversButtonAction.putValue(
Action.SHORT_DESCRIPTION,
"Save the current receiver configuration");
saveReceiversButtonAction.putValue(Action.NAME, "Save receivers");
saveReceiversButtonAction.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.FILE_SAVE_AS));
saveReceiversButtonAction.putValue(
Action.MNEMONIC_KEY, KeyEvent.VK_V);
restartReceiverButtonAction =
new AbstractAction() {
public void actionPerformed(ActionEvent e) {
Receiver selectedReceiver = getCurrentlySelectedReceiver();
if (selectedReceiver == null) {
return;
}
selectedReceiver.shutdown();
selectedReceiver.activateOptions();
//allow the visual receiver to get a container on restart
if (selectedReceiver instanceof VisualReceiver) {
((VisualReceiver) selectedReceiver).setContainer(ReceiversPanel.this);
}
}
};
restartReceiverButtonAction.putValue(
Action.SHORT_DESCRIPTION,
"Restarts the selected Receiver");
restartReceiverButtonAction.putValue(Action.NAME, "Restart");
restartReceiverButtonAction.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.ICON_RESTART));
restartReceiverButtonAction.putValue(
Action.MNEMONIC_KEY, KeyEvent.VK_R);
restartReceiverButtonAction.setEnabled(false);
showReceiverHelpAction =
new AbstractAction("Help") {
public void actionPerformed(ActionEvent e) {
Receiver receiver = getCurrentlySelectedReceiver();
if (receiver != null) {
HelpManager.getInstance().showHelpForClass(receiver.getClass());
}
}
};
showReceiverHelpAction.putValue(
Action.SMALL_ICON, new ImageIcon(ChainsawIcons.HELP));
showReceiverHelpAction.putValue(
Action.SHORT_DESCRIPTION, "Displays the JavaDoc page for this Plugin");
startAllAction =
new AbstractAction(
"(Re)start All Receivers", new ImageIcon(ChainsawIcons.ICON_RESTART_ALL)) {
public void actionPerformed(ActionEvent e) {
if (
JOptionPane.showConfirmDialog(
null,
"This will cause any active Receiver to stop, and disconnect. Is this ok?",
"Confirm", JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION) {
new Thread(
() -> {
Collection allReceivers =
pluginRegistry.getPlugins(Receiver.class);
for (Object allReceiver : allReceivers) {
Receiver item = (Receiver) allReceiver;
item.shutdown();
item.activateOptions();
}
updateReceiverTreeInDispatchThread();
MessageCenter.getInstance().getLogger().info(
"All Receivers have been (re)started");
}).start();
}
}
};
startAllAction.putValue(
Action.SHORT_DESCRIPTION,
"Ensures that any Receiver that isn't active, is started, and any started action is stopped, and then restarted");
receiversTree.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
receiversTree.setCellRenderer(new ReceiverTreeCellRenderer());
receiversTree.setRowHeight(19);
buttonPanel = new ReceiverToolbar();
receiversTree.addTreeSelectionListener(buttonPanel);
PopupListener popupListener = new PopupListener(popupMenu);
receiversTree.addMouseListener(popupListener);
this.addMouseListener(popupListener);
JComponent component = receiversTree;
JScrollPane pane = new JScrollPane(component);
splitter.setOrientation(JSplitPane.VERTICAL_SPLIT);
splitter.setTopComponent(pane);
splitter.setBottomComponent(pluginEditorPanel);
splitter.setResizeWeight(0.7);
add(buttonPanel, BorderLayout.NORTH);
add(splitter, BorderLayout.CENTER);
/**
* This Tree likes to be notified when Socket's are accepted so
* we listen for them and update the Tree.
*/
SocketNodeEventListener listener =
new SocketNodeEventListener() {
public void socketOpened(String remoteInfo) {
updateReceiverTreeInDispatchThread();
}
public void socketClosedEvent(Exception e) {
updateReceiverTreeInDispatchThread();
}
};
}
private void saveReceivers() {
File saveConfigFile = SwingHelper.promptForFile(this, null, "Save receiver configuration XML file", false);
if (saveConfigFile != null) {
ReceiversHelper.getInstance().saveReceiverConfiguration(saveConfigFile);
}
}
protected ReceiversTreeModel getReceiverTreeModel() {
return ((ReceiversTreeModel) receiversTree.getModel());
}
/**
*
*/
protected void updateCurrentlySelectedNodeInDispatchThread() {
SwingUtilities.invokeLater(
() -> {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) receiversTree
.getLastSelectedPathComponent();
if (node == null) {
return;
}
getReceiverTreeModel().nodeChanged(node);
updateActions();
});
}
/**
* Returns the currently selected Receiver, or null if there is no
* selected Receiver (this could be because a) nothing at all is selected
* or b) a non Receiver type node is selected
*
* @return Receiver or null
*/
private Receiver getCurrentlySelectedReceiver() {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) receiversTree.getLastSelectedPathComponent();
if (node == null) {
return null;
}
Object userObject = node.getUserObject();
if (userObject instanceof Receiver) {
return (Receiver) userObject;
}
return null;
}
private Receiver[] getSelectedReceivers() {
TreePath[] paths = receiversTree.getSelectionPaths();
Collection receivers = new ArrayList();
for (TreePath path : paths) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) path.getLastPathComponent();
if ((node != null) && node.getUserObject() instanceof Receiver) {
receivers.add(node.getUserObject());
}
}
return (Receiver[]) receivers.toArray(new Receiver[0]);
}
/**
* Returns the currently seleted node's User Object, or null
* if there is no selected node, or if the currently selected node has
* not user Object
*
* @return Object representing currently seleted Node's User Object
*/
private Object getCurrentlySelectedUserObject() {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) receiversTree.getLastSelectedPathComponent();
if (node == null) {
return null;
}
return node.getUserObject();
}
/**
* Takes the currently selected Receiver and pauess it, effectively
* discarding any received event BEFORE it is even posted to the logger
* repository.
* <p>
* The user is NOT asked to confirm this operation
*/
private void pauseCurrentlySelectedReceiver() {
new Thread(
() -> {
Object obj = getCurrentlySelectedUserObject();
if ((obj != null) && obj instanceof Pauseable) {
((Pauseable) obj).setPaused(true);
updateCurrentlySelectedNodeInDispatchThread();
}
}).start();
}
/**
* Ensures that the currently selected receiver active property is set to
* true
*/
private void playCurrentlySelectedReceiver() {
new Thread(
() -> {
Object obj = getCurrentlySelectedUserObject();
if ((obj != null) && obj instanceof Pauseable) {
((Pauseable) obj).setPaused(false);
updateCurrentlySelectedNodeInDispatchThread();
}
}).start();
}
/**
* Takes the currently selected Receiver and stops it, which effectively
* removes it from the PluginRegistry.
* <p>
* The user is asked to confirm this operation
*/
private void shutdownCurrentlySelectedReceiver() {
if (
JOptionPane.showConfirmDialog(
null,
"Are you sure you wish to shutdown this receiver?\n\nThis will disconnect any network resources, and remove it from the PluginRegistry.",
"Confirm stop of Receiver", JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) {
new Thread(
() -> {
Receiver[] receivers = getSelectedReceivers();
if (receivers != null) {
for (Receiver receiver : receivers) {
pluginRegistry.stopPlugin(receiver.getName());
}
}
}).start();
}
}
/**
* Sets the state of actions depending on certain conditions (i.e what is
* currently selected etc.)
*/
private void updateActions() {
Object object = getCurrentlySelectedUserObject();
if ((object != null) && object instanceof Pauseable) {
Pauseable pauseable = (Pauseable) object;
if (!pauseable.isPaused()) {
pauseReceiverButtonAction.setEnabled(true);
playReceiverButtonAction.setEnabled(false);
} else {
pauseReceiverButtonAction.setEnabled(false);
playReceiverButtonAction.setEnabled(true);
}
} else {
pauseReceiverButtonAction.setEnabled(false);
playReceiverButtonAction.setEnabled(false);
}
if (object instanceof Receiver) {
newReceiverButtonAction.setEnabled(true);
shutdownReceiverButtonAction.setEnabled(true);
restartReceiverButtonAction.setEnabled(true);
} else {
shutdownReceiverButtonAction.setEnabled(false);
restartReceiverButtonAction.setEnabled(false);
}
}
/**
* Ensures that the Receiver tree is updated with the latest information
* and that this operation occurs in the Swing Event Dispatch thread.
*/
public void updateReceiverTreeInDispatchThread() {
logger.debug(
"updateReceiverTreeInDispatchThread, should not be needed now");
// if (SwingUtilities.isEventDispatchThread()) {
// updateReceiverTree.run();
// } else {
// SwingUtilities.invokeLater(updateReceiverTree);
// }
}
/* (non-Javadoc)
* @see java.awt.Component#setVisible(boolean)
*/
public void setVisible(boolean aFlag) {
boolean oldValue = isVisible();
super.setVisible(aFlag);
firePropertyChange("visible", oldValue, isVisible());
}
public void loadSettings(LoadSettingsEvent event) {
}
/**
* Saves all the receivers which are active at shut down as a configuration
* file which can be loaded when Chainsaw will be restarted.
*/
public void saveSettings(SaveSettingsEvent event) {
File file = new File(SettingsManager.getInstance().getSettingsDirectory(), "receiver-config.xml");
ReceiversHelper.getInstance().saveReceiverConfiguration(file);
}
/**
* A popup menu that allows the user to choose which
* style of Receiver to create, which spawns a relevant Dialog
* to enter the information and create the Receiver
*
* @author Paul Smith &lt;psmith@apache.org&gt;
*/
class NewReceiverPopupMenu extends JPopupMenu {
NewReceiverPopupMenu() {
try {
final List receiverList =
ReceiversHelper.getInstance().getKnownReceiverClasses();
String separatorCheck = null;
for (Object aReceiverList : receiverList) {
final Class toCreate = (Class) aReceiverList;
Package thePackage = toCreate.getPackage();
final String name =
toCreate.getName().substring(thePackage.getName().length() + 1);
if (separatorCheck == null) {
separatorCheck = name.substring(0, 1);
} else {
String current = name.substring(0, 1);
if (!current.equals(separatorCheck)) {
addSeparator();
separatorCheck = current;
}
}
add(
new AbstractAction("New " + name + "...") {
public void actionPerformed(ActionEvent e) {
Container container = SwingUtilities.getAncestorOfClass(JFrame.class, ReceiversPanel.this);
final JDialog dialog = new JDialog((JFrame) container, "New " + toCreate.getName() + "...", true);
try {
final NewReceiverDialogPanel panel =
NewReceiverDialogPanel.create(toCreate);
dialog.getContentPane().add(panel);
dialog.pack();
SwingHelper.centerOnScreen(dialog);
/**
* Make the default button the ok button
*/
dialog.getRootPane().setDefaultButton(panel.getOkPanel().getOkButton());
/**
* Use the standard Cancel metaphor
*/
SwingHelper.configureCancelForDialog(dialog, panel.getOkPanel().getCancelButton());
panel.getOkPanel().getOkButton().addActionListener(
e2 -> {
Plugin plugin = panel.getPlugin();
if (plugin.getName() != null && !plugin.getName().trim().equals("")) {
dialog.dispose();
pluginRegistry.addPlugin(plugin);
plugin.activateOptions();
MessageCenter.getInstance().addMessage("Plugin '" + plugin.getName() + "' started");
} else {
MessageCenter.getInstance().getLogger().error("Name required to create receiver");
}
});
dialog.setVisible(true);
} catch (Exception e1) {
e1.printStackTrace();
MessageCenter.getInstance().getLogger().error(
"Failed to create the new Receiver dialog", e1);
}
}
});
}
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e.getMessage());
}
}
}
/**
* A popup menu class for when the user uses the popup trigger action
* on a node in the Receiver tree.
*
* @author Paul Smith &lt;psmith@apache.org&gt;
*/
class ReceiverPopupMenu extends JPopupMenu {
ReceiverPopupMenu() {
}
/* (non-Javadoc)
* @see javax.swing.JPopupMenu#show(java.awt.Component, int, int)
*/
public void show(Component invoker, int x, int y) {
DefaultMutableTreeNode node =
(DefaultMutableTreeNode) receiversTree.getLastSelectedPathComponent();
if (node == null) {
return;
}
Object userObject = node.getUserObject();
removeAll();
if (userObject == getRootOfTree().getUserObject()) {
buildForReceiversRoot();
} else if (getCurrentlySelectedReceiver() != null) {
buildForReceiverNode();
} else {
return;
}
this.invalidate();
this.validate();
super.show(invoker, x, y);
}
/**
*
*/
private DefaultMutableTreeNode getRootOfTree() {
return (DefaultMutableTreeNode) receiversTree.getModel().getRoot();
}
/**
* Builds the popup menu with relevant items for a selected
* Receiver node in the Tree.
*/
private void buildForReceiverNode() {
add(playReceiverButtonAction);
add(pauseReceiverButtonAction);
add(restartReceiverButtonAction);
add(shutdownReceiverButtonAction);
add(saveReceiversButtonAction);
addSeparator();
final Receiver r = getCurrentlySelectedReceiver();
add(createLevelRadioButton(r, Level.TRACE));
add(createLevelRadioButton(r, Level.DEBUG));
add(createLevelRadioButton(r, Level.INFO));
add(createLevelRadioButton(r, Level.WARN));
add(createLevelRadioButton(r, Level.ERROR));
addSeparator();
add(createLevelRadioButton(r, Level.OFF));
add(createLevelRadioButton(r, Level.ALL));
addSeparator();
add(showReceiverHelpAction);
}
private JRadioButtonMenuItem createLevelRadioButton(
final Receiver r, final Level l) {
Map<String, Icon> levelIconMap = LevelIconFactory.getInstance().getLevelToIconMap();
Action action =
new AbstractAction(
l.toString(), levelIconMap.get(l.toString())) {
public void actionPerformed(ActionEvent e) {
if (r != null) {
r.setThreshold(l);
updateCurrentlySelectedNodeInDispatchThread();
}
}
};
JRadioButtonMenuItem item = new JRadioButtonMenuItem(action);
item.setSelected(r.getThreshold() == l);
return item;
}
/**
* Builds a relevant set of menus for when the Root node in the Receiver
* tree has been selected
*/
private void buildForReceiversRoot() {
JMenuItem startAll = new JMenuItem(startAllAction);
add(newReceiverButtonAction);
addSeparator();
add(startAll);
}
}
/**
* A simple Panel that has toolbar buttons for restarting,
* playing, pausing, and stoping receivers
*
* @author Paul Smith &lt;psmith@apache.org&gt;
*/
private class ReceiverToolbar extends JToolBar
implements TreeSelectionListener {
final SmallButton newReceiverButton;
private ReceiverToolbar() {
setFloatable(false);
SmallButton restartReceiverButton = new SmallButton(restartReceiverButtonAction);
restartReceiverButton.setText(null);
SmallButton shutdownReceiverButton =
new SmallButton(shutdownReceiverButtonAction);
shutdownReceiverButton.setText(null);
SmallButton saveReceiversButton =
new SmallButton(saveReceiversButtonAction);
saveReceiversButton.setText(null);
SmallButton restartAllButton = new SmallButton(startAllAction);
restartAllButton.setText(null);
newReceiverButton = new SmallButton(newReceiverButtonAction);
newReceiverButton.setText(null);
newReceiverButton.addMouseListener(new PopupListener(newReceiverPopup));
add(newReceiverButton);
add(restartAllButton);
addSeparator();
add(restartReceiverButton);
add(shutdownReceiverButton);
add(saveReceiversButton);
addSeparator();
Action closeAction =
new AbstractAction(null, LineIconFactory.createCloseIcon()) {
public void actionPerformed(ActionEvent e) {
ReceiversPanel.this.setVisible(false);
}
};
closeAction.putValue(
Action.SHORT_DESCRIPTION, "Closes the Receiver panel");
add(Box.createHorizontalGlue());
add(new SmallButton(closeAction));
add(Box.createHorizontalStrut(5));
}
/**
* Ensures the enabled property of the actions is set properly
* according to the currently selected node in the tree
*/
public void valueChanged(TreeSelectionEvent e) {
updateActions();
}
}
}