You are viewing a plain text version of this content. The canonical link for it is here.
Posted to log4j-dev@logging.apache.org by ps...@apache.org on 2006/02/11 06:12:38 UTC
svn commit: r376931 - in
/logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf:
ZeroConfDeviceModel.java ZeroConfPlugin.java
Author: psmith
Date: Fri Feb 10 21:12:35 2006
New Revision: 376931
URL: http://svn.apache.org/viewcvs?rev=376931&view=rev
Log:
Changed the way the ZeroConfPlugin renders it's model, decided to use a JTable instead
because of the ease of coding in the auto-connect selection.
Added the ZeroConfDeviceModel to be able to easily serialize the model to disk.
Added:
logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfDeviceModel.java
Modified:
logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
Added: logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfDeviceModel.java
URL: http://svn.apache.org/viewcvs/logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfDeviceModel.java?rev=376931&view=auto
==============================================================================
--- logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfDeviceModel.java (added)
+++ logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfDeviceModel.java Fri Feb 10 21:12:35 2006
@@ -0,0 +1,130 @@
+package org.apache.log4j.chainsaw.zeroconf;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import javax.jmdns.ServiceEvent;
+import javax.jmdns.ServiceInfo;
+import javax.jmdns.ServiceListener;
+import javax.swing.ImageIcon;
+import javax.swing.table.AbstractTableModel;
+
+import org.apache.log4j.chainsaw.icons.ChainsawIcons;
+
+public class ZeroConfDeviceModel extends AbstractTableModel implements ServiceListener {
+
+ private List deviceList = new ArrayList();
+ private ZeroConfPreferenceModel zeroConfPreferenceModel;
+ private transient ZeroConfPlugin plugin;
+
+ public ZeroConfDeviceModel() {
+ }
+
+ public int getRowCount() {
+ return deviceList.size();
+ }
+
+ public int getColumnCount() {
+ return 4;
+ }
+
+ public ServiceInfo getServiceInfoAtRow(int row) {
+ return (ServiceInfo) deviceList.get(row);
+ }
+ public Object getValueAt(int rowIndex, int columnIndex) {
+ ServiceInfo info = (ServiceInfo) deviceList.get(rowIndex);
+ if(info == null) {
+ return "";
+ }
+ switch(columnIndex) {
+ case 0:
+ return getAutoConnectHandle(info);
+ case 1:
+ return info.getAddress().getHostName() + ":" + info.getPort();
+ case 2:
+ return zeroConfPreferenceModel.getAutoConnectDevices().contains(getAutoConnectHandle(info))?Boolean.TRUE:Boolean.FALSE;
+ case 3:
+ return plugin.isConnectedTo(info)?"Connected":"Not Connected";
+// return plugin.isConnectedTo(info)?new ImageIcon(ChainsawIcons.ANIM_NET_CONNECT):new ImageIcon();
+ default:
+ return "";
+ }
+ }
+
+ private String getAutoConnectHandle(ServiceInfo info) {
+ return info.getName();
+ }
+
+ public void serviceAdded(ServiceEvent event) {
+ }
+
+ public void serviceRemoved(ServiceEvent event) {
+ for (Iterator iter = deviceList.iterator(); iter.hasNext();) {
+ ServiceInfo info = (ServiceInfo) iter.next();
+ if(info.getName().equals(event.getName())) {
+ iter.remove();
+ }
+ }
+ fireTableDataChanged();
+ }
+
+ public void serviceResolved(ServiceEvent event) {
+ deviceList.add(event.getInfo());
+ fireTableDataChanged();
+ }
+
+ public void setZeroConfPreferenceModel(
+ ZeroConfPreferenceModel zeroConfPreferenceModel) {
+ this.zeroConfPreferenceModel = zeroConfPreferenceModel;
+ }
+
+ public String getColumnName(int column) {
+ switch(column) {
+ case 0:
+ return "ZeroConf name";
+ case 1:
+ return "Address:Port";
+ case 2:
+ return "Auto-connect";
+ case 3:
+ return "Connection Status";
+ default:
+ return "";
+ }
+ }
+
+ public boolean isCellEditable(int rowIndex, int columnIndex) {
+ return columnIndex == 2;
+ }
+
+ public Class getColumnClass(int columnIndex) {
+ switch(columnIndex) {
+ case 2:
+ return Boolean.class;
+ default:
+ return super.getColumnClass(columnIndex);
+ }
+ }
+
+ public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+ if(columnIndex!=2 || !(aValue instanceof Boolean)) {
+ return;
+ }
+ boolean autoConnect = ((Boolean)aValue).booleanValue();
+ Object device = this.deviceList.get(rowIndex);
+ String autoConnectHandle = getAutoConnectHandle((ServiceInfo) device);
+ if(autoConnect) {
+ zeroConfPreferenceModel.getAutoConnectDevices().add(autoConnectHandle);
+ }else {
+ zeroConfPreferenceModel.getAutoConnectDevices().remove(autoConnectHandle);
+ }
+ fireTableDataChanged();
+ }
+
+ void setZeroConfPluginParent(ZeroConfPlugin parent) {
+ this.plugin = parent;
+ }
+
+
+}
Modified: logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java
URL: http://svn.apache.org/viewcvs/logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java?rev=376931&r1=376930&r2=376931&view=diff
==============================================================================
--- logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java (original)
+++ logging/chainsaw/trunk/zeroconf/org/apache/log4j/chainsaw/zeroconf/ZeroConfPlugin.java Fri Feb 10 21:12:35 2006
@@ -3,7 +3,6 @@
import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Container;
-import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
@@ -19,32 +18,28 @@
import javax.jmdns.ServiceInfo;
import javax.jmdns.ServiceListener;
import javax.swing.AbstractAction;
-import javax.swing.BorderFactory;
-import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JCheckBox;
+import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
-import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
-import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTabbedPane;
+import javax.swing.JTable;
import javax.swing.JToolBar;
-import javax.swing.ListCellRenderer;
-import javax.swing.ListModel;
import javax.swing.SwingUtilities;
-import javax.swing.event.ListDataEvent;
-import javax.swing.event.ListDataListener;
+import javax.swing.event.TableModelEvent;
+import javax.swing.event.TableModelListener;
+import javax.swing.table.DefaultTableCellRenderer;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
-import org.apache.log4j.chainsaw.ModifiableListModel;
import org.apache.log4j.chainsaw.SmallButton;
import org.apache.log4j.chainsaw.help.HelpManager;
import org.apache.log4j.chainsaw.icons.ChainsawIcons;
@@ -52,6 +47,7 @@
import org.apache.log4j.chainsaw.prefs.SettingsManager;
import org.apache.log4j.net.SocketHubReceiver;
import org.apache.log4j.net.ZeroConfSocketHubAppender;
+import org.apache.log4j.net.ZeroConfSocketHubAppenderTestBed;
import org.apache.log4j.net.Zeroconf4log4j;
import org.apache.log4j.plugins.Plugin;
import org.apache.log4j.plugins.PluginEvent;
@@ -66,7 +62,6 @@
* whatever people are calling it) and allow the user to double click on
* 'devices' to try and connect to them with no configuration needed.
*
- * TODO add autoConnect visuals, and save it in a model
* TODO need to handle
* NON-log4j devices that may be broadcast in the interested zones
* TODO add the
@@ -84,11 +79,11 @@
private static final Icon DEVICE_DISCOVERED_ICON = new ImageIcon(ChainsawIcons.ANIM_RADIO_TOWER);
- private ModifiableListModel discoveredDevices = new ModifiableListModel();
+ private ZeroConfDeviceModel discoveredDevices = new ZeroConfDeviceModel();
- private final JList listBox = new JList(discoveredDevices);
-
- private final JScrollPane scrollPane = new JScrollPane(listBox);
+ private JTable deviceTable = new JTable(discoveredDevices);
+
+ private final JScrollPane scrollPane = new JScrollPane(deviceTable);
private JmDNS jmDNS;
@@ -139,12 +134,11 @@
ZeroConfSocketHubAppender.DEFAULT_ZEROCONF_ZONE,
new ZeroConfServiceListener());
- listBox.setCellRenderer(new ServiceInfoListCellRenderer());
- listBox.setLayoutOrientation(JList.HORIZONTAL_WRAP);
- listBox.setFixedCellHeight(75);
- listBox.setFixedCellWidth(200);
- listBox.setVisibleRowCount(-1);
- listBox.addMouseListener(new ConnectorMouseListener());
+ jmDNS.addServiceListener(ZeroConfSocketHubAppender.DEFAULT_ZEROCONF_ZONE, discoveredDevices);
+
+ deviceTable.addMouseListener(new ConnectorMouseListener());
+
+
JToolBar toolbar = new JToolBar();
SmallButton helpButton = new SmallButton(helpItem.getAction());
helpButton.setText(helpItem.getText());
@@ -167,17 +161,12 @@
for (Iterator iter = serviceInfoToReceiveMap.entrySet().iterator(); iter.hasNext();) {
Map.Entry entry = (Map.Entry) iter.next();
if(entry.getValue() == plugin) {
- serviceInfoToReceiveMap.remove(entry.getKey());
+ iter.remove();
}
}
}
// need to make sure that the menu item tracking this item has it's icon and enabled state updade
- JMenuItem item = locateMatchingMenuItem(plugin.getName());
- if (item!=null) {
- item.setEnabled(true);
- item.setIcon(null);
- }
- discoveredDevices.fireContentsChanged();
+ discoveredDevices.fireTableDataChanged();
}});
File fileLocation = getPreferenceFileLocation();
@@ -192,20 +181,8 @@
}else {
this.preferenceModel = new ZeroConfPreferenceModel();
}
-
- discoveredDevices.addListDataListener(new ListDataListener() {
-
- public void intervalAdded(ListDataEvent e) {
- setIconIfNeeded();
- }
-
- public void intervalRemoved(ListDataEvent e) {
- setIconIfNeeded();
- }
-
- public void contentsChanged(ListDataEvent e) {
- setIconIfNeeded();
- }});
+ discoveredDevices.setZeroConfPreferenceModel(preferenceModel);
+ discoveredDevices.setZeroConfPluginParent(this);
}
/**
@@ -216,7 +193,7 @@
Container container = this.getParent();
if(container instanceof JTabbedPane) {
JTabbedPane tabbedPane = (JTabbedPane) container;
- Icon icon = discoveredDevices.getSize()==0?null:DEVICE_DISCOVERED_ICON;
+ Icon icon = discoveredDevices.getRowCount()==0?null:DEVICE_DISCOVERED_ICON;
tabbedPane.setIconAt(tabbedPane.indexOfTab(getName()), icon);
}else {
LOG.warn("Parent is not a TabbedPane, not setting icon: " + container.getClass().getName());
@@ -241,22 +218,15 @@
insertToLeftOfHelp(menuBar, connectToMenu);
connectToMenu.add(nothingToConnectTo);
- discoveredDevices.addListDataListener(new ListDataListener() {
-
- public void intervalAdded(ListDataEvent e) {
- if(discoveredDevices.getSize()>0) {
- connectToMenu.remove(nothingToConnectTo);
- }
- }
+ discoveredDevices.addTableModelListener(new TableModelListener (){
- public void intervalRemoved(ListDataEvent e) {
- if(discoveredDevices.getSize()==0) {
+ public void tableChanged(TableModelEvent e) {
+ if(discoveredDevices.getRowCount()==0) {
connectToMenu.add(nothingToConnectTo,0);
+ }else if(discoveredDevices.getRowCount()>0) {
+ connectToMenu.remove(nothingToConnectTo);
}
- }
-
- public void contentsChanged(ListDataEvent e) {
}});
nothingToConnectTo.setEnabled(false);
@@ -266,6 +236,12 @@
}
}
+ /**
+ * Hack method to locate the JMenu that is the Help menu, and inserts the new menu
+ * just to the left of it.
+ * @param menuBar
+ * @param item
+ */
private void insertToLeftOfHelp(JMenuBar menuBar, JMenu item) {
for (int i = 0; i < menuBar.getMenuCount(); i++) {
JMenu menu = menuBar.getMenu(i);
@@ -276,6 +252,12 @@
LOG.warn("menu '" + item.getText() + "' was NOT added because the 'Help' menu could not be located");
}
+ /**
+ * When a device is discovered, we create a menu item for it so it can be connected to via that
+ * GUI mechanism, and also if the device is one of the auto-connect devices then a background thread
+ * is created to connect the device.
+ * @param info
+ */
private void deviceDiscovered(final ServiceInfo info) {
final String name = info.getName();
// TODO currently adding ALL devices to autoConnectlist
@@ -288,13 +270,7 @@
connectTo(info);
}});
- if(discoveredDevices.getSize()>0) {
- for (int i = 0; i < discoveredDevices.getSize(); i++) {
- if (name.compareToIgnoreCase(((ServiceInfo) discoveredDevices
- .elementAt(i)).getName()) < 0) {
- discoveredDevices.insertElementAt(info, i);
- }
- }
+ if(discoveredDevices.getRowCount()>0) {
Component[] menuComponents = connectToMenu.getMenuComponents();
boolean located = false;
for (int i = 0; i < menuComponents.length; i++) {
@@ -312,7 +288,6 @@
connectToMenu.insert(connectToDeviceMenuItem,0);
}
}else {
- discoveredDevices.addElement(info);
connectToMenu.insert(connectToDeviceMenuItem,0);
}
// if the device name is one of the autoconnect devices, then connect immediately
@@ -327,13 +302,11 @@
}
}
+ /**
+ * When a device is removed or disappears we need to remove any JMenu item associated with it.
+ * @param name
+ */
private void deviceRemoved(String name) {
- for (int i = 0; i < discoveredDevices.getSize(); i++) {
- if (name.compareToIgnoreCase(((ServiceInfo) discoveredDevices
- .elementAt(i)).getName()) == 0) {
- discoveredDevices.remove(i);
- }
- }
Component[] menuComponents = connectToMenu.getMenuComponents();
for (int i = 0; i < menuComponents.length; i++) {
Component c = menuComponents[i];
@@ -347,6 +320,11 @@
}
}
+ /**
+ * Listens out on the JmDNS/ZeroConf network for new devices that appear
+ * and adds/removes these device information from the list/model.
+ *
+ */
private class ZeroConfServiceListener implements ServiceListener {
public void serviceAdded(final ServiceEvent event) {
@@ -380,76 +358,21 @@
}
- private class ServiceInfoListCellRenderer implements
- ListCellRenderer {
-
- private JPanel panel = new JPanel(new BorderLayout(15, 15));
-
- private final ImageIcon ICON = new ImageIcon(
- ChainsawIcons.ANIM_RADIO_TOWER);
-
- private JLabel iconLabel = new JLabel(ICON);
-
- private JLabel nameLabel = new JLabel();
-
- private JLabel detailLabel = new JLabel();
-
- private JCheckBox autoConnect = new JCheckBox();
-
- private Box southBox = Box.createVerticalBox();
- private JCheckBox checkBox = new JCheckBox();
-
- private ServiceInfoListCellRenderer() {
- Font font = nameLabel.getFont();
- font = font.deriveFont(font.getSize() + 6);
- nameLabel.setFont(font);
- panel.setLayout(new BorderLayout());
- panel.add(iconLabel, BorderLayout.WEST);
-
- JPanel centerPanel = new JPanel(new BorderLayout(3, 3));
-
- centerPanel.add(nameLabel, BorderLayout.CENTER);
- centerPanel.add(southBox, BorderLayout.SOUTH);
- panel.add(centerPanel, BorderLayout.CENTER);
-
- southBox.add(detailLabel);
- Box hBox = Box.createHorizontalBox();
- hBox.add(Box.createHorizontalGlue());
- hBox.add(new JLabel("Auto-connect:"));
- hBox.add(checkBox);
-
- southBox.add(hBox);
-
- panel.setBorder(BorderFactory.createEtchedBorder());
- }
-
- public Component getListCellRendererComponent(JList list, Object value,
- int index, boolean isSelected, boolean cellHasFocus) {
- if (isSelected) {
- panel.setBackground(list.getSelectionBackground());
- panel.setForeground(list.getSelectionForeground());
- } else {
- panel.setBackground(list.getBackground());
- panel.setForeground(list.getForeground());
- }
- ServiceInfo info = (ServiceInfo) value;
- nameLabel.setText(info.getName());
- detailLabel.setText(info.getHostAddress() + ":" + info.getPort());
- iconLabel.setIcon(isConnectedTo(info)?ICON:null);
- checkBox.setSelected(preferenceModel.getAutoConnectDevices().contains(info.getName()));
- return panel;
- }
-
- }
+ /**
+ * When the user double clicks on a row, then the device is connected to,
+ * the only exception is when clicking in the check box column for auto connect.
+ */
private class ConnectorMouseListener extends MouseAdapter {
public void mouseClicked(MouseEvent e) {
if (e.getClickCount() == 2) {
- int index = listBox.locationToIndex(e.getPoint());
- ListModel dlm = discoveredDevices;
- ServiceInfo info = (ServiceInfo) dlm.getElementAt(index);
- listBox.ensureIndexIsVisible(index);
+ int row = deviceTable.rowAtPoint(e.getPoint());
+ if(deviceTable.columnAtPoint(e.getPoint())==2) {
+ return;
+ }
+ ServiceInfo info = discoveredDevices.getServiceInfoAtRow(row);
+
if (!isConnectedTo(info)) {
connectTo(info);
} else {
@@ -463,24 +386,24 @@
* This methodh handles when the user clicks the
* auto-connect
*/
- int index = listBox.locationToIndex(e.getPoint());
-
- if (index != -1) {
-// Point p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), )
- Component c = SwingUtilities.getDeepestComponentAt(ZeroConfPlugin.this, e.getX(), e.getY());
- if (c instanceof JCheckBox) {
- ServiceInfo info = (ServiceInfo) listBox.getModel()
- .getElementAt(index);
- String name = info.getName();
- if (preferenceModel.getAutoConnectDevices().contains(name)) {
- preferenceModel.removeAutoConnectDevice(name);
- } else {
- preferenceModel.addAutoConnectDevice(name);
- }
- discoveredDevices.fireContentsChanged();
- repaint();
- }
- }
+// int index = listBox.locationToIndex(e.getPoint());
+//
+// if (index != -1) {
+//// Point p = SwingUtilities.convertPoint(e.getComponent(), e.getPoint(), )
+// Component c = SwingUtilities.getDeepestComponentAt(ZeroConfPlugin.this, e.getX(), e.getY());
+// if (c instanceof JCheckBox) {
+// ServiceInfo info = (ServiceInfo) listBox.getModel()
+// .getElementAt(index);
+// String name = info.getName();
+// if (preferenceModel.getAutoConnectDevices().contains(name)) {
+// preferenceModel.removeAutoConnectDevice(name);
+// } else {
+// preferenceModel.addAutoConnectDevice(name);
+// }
+// discoveredDevices.fireContentsChanged();
+// repaint();
+// }
+// }
}
}
@@ -493,13 +416,19 @@
plugin = (Plugin) serviceInfoToReceiveMap.get(info);
}
((LoggerRepositoryEx)LogManager.getLoggerRepository()).getPluginRegistry().stopPlugin(plugin.getName());
+
+ JMenuItem item = locateMatchingMenuItem(info.getName());
+ if (item!=null) {
+ item.setIcon(null);
+ item.setEnabled(true);
+ }
}
/**
* returns true if the serviceInfo record already has a matching connected receiver
* @param info
* @return
*/
- private boolean isConnectedTo(ServiceInfo info) {
+ boolean isConnectedTo(ServiceInfo info) {
return serviceInfoToReceiveMap.containsKey(info);
}
/**
@@ -532,8 +461,8 @@
item.setIcon(new ImageIcon(ChainsawIcons.ANIM_NET_CONNECT));
item.setEnabled(false);
}
- // now notify the list model has changed, it needs redrawing of the receiver icon now it's connected
- discoveredDevices.fireContentsChanged();
+// // now notify the list model has changed, it needs redrawing of the receiver icon now it's connected
+// discoveredDevices.fireContentsChanged();
}
/**
---------------------------------------------------------------------
To unsubscribe, e-mail: log4j-dev-unsubscribe@logging.apache.org
For additional commands, e-mail: log4j-dev-help@logging.apache.org