package net.sf.dz.setup.core; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.Map; import java.util.Set; import java.util.SortedSet; import java.util.StringTokenizer; import java.util.Vector; import javax.swing.JButton; import javax.swing.JList; import javax.swing.JOptionPane; import javax.swing.ListSelectionModel; import org.freehold.jukebox.logger.Logger; import net.sf.dz.pnp.MulticastClient; import net.sf.dz.pnp.MulticastEvent; import net.sf.dz.pnp.MulticastEventListener; import net.sf.dz.util.wizard.DoubleListPanel; import net.sf.dz.util.wizard.Wizard; import net.sf.dz.util.wizard.WizardPage; class PnpTemperatureSensorPage extends WizardPage implements MulticastEventListener { private JButton createZoneButton; private JButton deleteZoneButton; private JButton assignButton; private JButton detachButton; private JList sensorList; private JList zoneList; private DoubleListPanel dlp; private Map eventBySource = new HashMap(); public PnpTemperatureSensorPage(Logger logger, Wizard owner) { super(logger, owner, "PnP Temperature Sensor Discovery"); List buttonNames = new LinkedList(); buttonNames.add("Create Zone"); buttonNames.add("Delete Zone"); buttonNames.add(""); buttonNames.add("Assign >>"); buttonNames.add(" dlp = new DoubleListPanel(getContentPane(), this, "Temperature Sensors", "Temperature Zones", buttonNames); createZoneButton = dlp.getButton(0); deleteZoneButton = dlp.getButton(1); assignButton = dlp.getButton(2); detachButton = dlp.getButton(3); sensorList = dlp.leftList; zoneList = dlp.rightList; sensorList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); zoneList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); deleteZoneButton.setEnabled(false); assignButton.setEnabled(false); detachButton.setEnabled(false); } public void activate() { Set sensorSet = getSortedContextValues("sensor.temp"); Object selected = null; if ( sensorList.getSelectedIndex() != -1 ) { selected = sensorList.getSelectedValue(); } sensorList.setListData(new Vector(sensorSet)); if ( selected != null ) { sensorList.setSelectedValue(selected, true); } else if ( !sensorSet.isEmpty() ) { // We get here if there was no selection, but there were some // sensors - in other words, the first time sensorList.setSelectedIndex(0); } Set zoneSet = getSortedContextValues("zone."); selected = null; if ( zoneList.getSelectedIndex() != -1 ) { selected = zoneList.getSelectedValue(); } zoneList.setListData(new Vector(zoneSet)); if ( selected != null ) { zoneList.setSelectedValue(selected, true); } else if ( !zoneSet.isEmpty() ) { // We get here if there was no selection, but there were // some zones - in other words, the first time zoneList.setSelectedIndex(0); } } public String getHelpURL() { return "FIXME"; } public String validate() { // Validation succeeds if there is at least one zone. Since it // is theoretically possible that the sensor for this zone has // not been [yet] discovered, having a sensor assigned is not // mandatory. if ( getContextValues("zone.").isEmpty() ) { return "At least one zone must be defined"; } if ( !isVisible() ) { // There's no point in setting the button state if nobody // can see it return ""; } // Button state: // // - "Create Zone" is enabled unconditionally; // // - "Delete Zone" is enabled if the zone list is non-empty, and // has a zone selected; // // - "Assign" is enabled if the device list is non-empty, // current device is unassigned, and the zone list is // non-empty and has a zone selected; // // - "Detach" is enabled if the zone list is non-empty, has a // zone selected, and the selected zone has the sensor // assigned deleteZoneButton.setEnabled(canDelete()); assignButton.setEnabled(canAssign()); detachButton.setEnabled(canDetach()); return ""; } private boolean canDelete() { return zoneList.getSelectedValue() != null; } private boolean canAssign() { SensorDescriptor sd = (SensorDescriptor)sensorList.getSelectedValue(); ZoneDescriptor zd = (ZoneDescriptor)zoneList.getSelectedValue(); return (sd != null && sd.zone == null && zd != null && zd.sensor == null); } private boolean canDetach() { ZoneDescriptor zd = (ZoneDescriptor)zoneList.getSelectedValue(); return (zd != null && zd.sensor != null); } public void actionPerformed2(ActionEvent e) { Object source = e.getSource(); if ( createZoneButton == source ) { String name = (String)JOptionPane.showInputDialog( getContentPane(), "Enter a zone name", "Create New Temperature Zone", JOptionPane.QUESTION_MESSAGE); complain(LOG_DEBUG, CH_WP, "New zone: " + name); if ( name != null && !"".equals(name) ) { // See if it is a dupe if ( getOwner().getContext().get("zone." + name) != null ) { complain(LOG_DEBUG, CH_WP, "Duplicate name: " + name); return; } // All right, let's create it ZoneDescriptor zd = new ZoneDescriptor(name); getOwner().getContext().put("zone." + name, zd); parseZones(); zoneList.setSelectedValue(zd, true); } } else if ( deleteZoneButton == source ) { // Remove the selected zone ZoneDescriptor zd = (ZoneDescriptor)zoneList.getSelectedValue(); String key = "zone." + zd.name; getOwner().getContext().remove(key); // Don't forget to detach the sensor and the servo if ( zd.sensor != null ) { zd.sensor.zone = null; zd.sensor = null; } if ( zd.servo != null ) { zd.servo.zone = null; zd.servo = null; } parseZones(); return; } else if ( assignButton == source ) { SensorDescriptor sd = (SensorDescriptor)sensorList.getSelectedValue(); ZoneDescriptor zd = (ZoneDescriptor)zoneList.getSelectedValue(); sd.zone = zd; zd.sensor = sd; parseEvents(); parseZones(); sensorList.validate(); sensorList.repaint(); return; } else if ( detachButton == source ) { ZoneDescriptor zd = (ZoneDescriptor)zoneList.getSelectedValue(); zd.sensor.zone = null; zd.sensor = null; parseEvents(); parseZones(); sensorList.validate(); sensorList.repaint(); return; } else { throw new IllegalStateException("Unknown source: " + e); } } public void multicastEventReceived(MulticastClient source, MulticastEvent e) { //complain(LOG_INFO, CH_WP, "PnP: " + e); eventBySource.put(e.getSource(), e); parseEvents(); } /** * Parse {@link #eventBySource event map} into objects * displayable in a list. */ private synchronized void parseEvents() { boolean modified = false; for ( Iterator i = eventBySource.keySet().iterator(); i.hasNext(); ) { Object key = i.next(); MulticastEvent e = (MulticastEvent)eventBySource.get(key); for ( StringTokenizer st = new StringTokenizer(e.getMessage(), " "); st.hasMoreTokens(); ) { String address = st.nextToken(); if ( getOwner().getContext().get("sensor.temp." + address) == null ) { // All right, we haven't seen this before SensorDescriptor sd = new SensorDescriptor(address); getOwner().getContext().put("sensor.temp." + address, sd); modified = true; } } } // If we're not modified, there's nothing to update if ( !modified ) { return; } SortedSet deviceSet = getSortedContextValues("sensor.temp."); // Take care to preserve existing selection, if any Object selected = sensorList.getSelectedValue(); sensorList.setListData(new Vector(deviceSet)); if ( selected != null ) { sensorList.setSelectedValue(selected, true); } } private void parseZones() { SortedSet zoneSet = getSortedContextValues("zone."); Object selected = zoneList.getSelectedValue(); zoneList.setListData(new Vector(zoneSet)); if ( selected != null ) { zoneList.setSelectedValue(selected, true); } } public boolean isEnabled() { return true; } }