diff --git a/src/org/openlcb/cdi/CdiRep.java b/src/org/openlcb/cdi/CdiRep.java index fcc9deff..f7e487ca 100644 --- a/src/org/openlcb/cdi/CdiRep.java +++ b/src/org/openlcb/cdi/CdiRep.java @@ -119,6 +119,8 @@ public static interface IntegerRep extends Item { public boolean isSliderShowValue(); // Did the CDI content hint that this value should be presented as a radio button? public boolean isRadioButtonHint(); + // Did the CDI content hint that this value should be presented as a checkbox? + public boolean isCheckboxHint(); } public static interface FloatRep extends Item { diff --git a/src/org/openlcb/cdi/impl/DemoReadWriteAccess.java b/src/org/openlcb/cdi/impl/DemoReadWriteAccess.java index 7239baf3..507d36b9 100644 --- a/src/org/openlcb/cdi/impl/DemoReadWriteAccess.java +++ b/src/org/openlcb/cdi/impl/DemoReadWriteAccess.java @@ -4,6 +4,7 @@ import java.io.File; import java.io.FileInputStream; import java.io.IOException; +import java.util.HashMap; import java.util.logging.Level; import java.util.logging.Logger; import org.jdom2.Document; @@ -20,20 +21,32 @@ public class DemoReadWriteAccess extends ReadWriteAccess { private final static Logger logger = Logger.getLogger(DemoReadWriteAccess.class.getName()); + // store written values for later reading + private long getAddressHash(long address, int space, int length) { + return address+1000000*space+1000000000*length; + } + + private final static HashMap contents = new HashMap<>(); + @Override public void doWrite(long address, int space, byte[] data, MemoryConfigurationService.McsWriteHandler handler) { - logger.log(Level.INFO, "Wrote {0} bytes", data.length); - logger.log(Level.INFO, "write {0} {1}: {2}", new Object[]{address, space, org.openlcb.Utilities.toHexDotsString(data)}); + logger.log(Level.INFO, "write {0} {1} with {2} bytes: {3}", new Object[]{address, space, data.length, org.openlcb.Utilities.toHexDotsString(data)}); + + contents.put(getAddressHash(address, space, data.length), data); } @Override public void doRead(long address, int space, int length, MemoryConfigurationService.McsReadHandler handler) { - byte[] resp = new byte[length]; - for (int i = 0; i < resp.length; ++i) { - resp[i] = (byte)(((address + i) % 91) + 32); + byte[] resp = contents.get(getAddressHash(address, space, length)); + if (resp == null) { + // no prior write, load with ascii letters + resp = new byte[length]; + for (int i = 0; i < resp.length; ++i) { + resp[i] = (byte)(((address + i) % 91) + 32); + } } handler.handleReadData(null, space, address, resp); - logger.log(Level.INFO, "read {0} {1}", new Object[]{address, space}); + logger.log(Level.INFO, "read {0} {1} with {2} bytes: {3}", new Object[]{address, space, resp.length, org.openlcb.Utilities.toHexDotsString(resp)}); } static public ConfigRepresentation demoRepFromSample(Element root) { diff --git a/src/org/openlcb/cdi/jdom/JdomCdiRep.java b/src/org/openlcb/cdi/jdom/JdomCdiRep.java index 86f8569f..0cc8c560 100644 --- a/src/org/openlcb/cdi/jdom/JdomCdiRep.java +++ b/src/org/openlcb/cdi/jdom/JdomCdiRep.java @@ -596,6 +596,15 @@ public boolean isRadioButtonHint() { return true; } + @Override + public boolean isCheckboxHint() { + Element hints = e.getChild("hints"); + if (hints == null) return false; + Element checkbox = hints.getChild("checkbox"); + if (checkbox == null) return false; + return true; + } + } diff --git a/src/org/openlcb/cdi/swing/CdiPanel.java b/src/org/openlcb/cdi/swing/CdiPanel.java index 54202327..48593582 100644 --- a/src/org/openlcb/cdi/swing/CdiPanel.java +++ b/src/org/openlcb/cdi/swing/CdiPanel.java @@ -74,6 +74,7 @@ import javax.swing.ComboBoxModel; import javax.swing.InputVerifier; import javax.swing.JButton; +import javax.swing.JCheckBox; import javax.swing.JComboBox; import javax.swing.JComponent; import javax.swing.JFileChooser; @@ -2644,11 +2645,63 @@ String getDisplayText() { } + // represents a checkbox + private class CheckboxPane extends JPanel { + + final int SELECTED_CHOICE = 1; + final int UNSELECTED_CHOICE = 0; + + CdiRep.Map map; // keys are numeric contents, values are string names + JCheckBox checkbox; + + CheckboxPane(CdiRep.Map map, ActionListener action) { + this.map = map; + + setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); + // create the pane and fill with labelled checkbox + String label = map.getValues().get(SELECTED_CHOICE); + checkbox = new JCheckBox(label); + add(checkbox); + checkbox.addActionListener(action); + } + + long getCurrentValue() { + return Long.parseLong(getCurrentValueString()); + } + + // value is a name string + void setCurrentValue(String value) { + if (value.equals(map.getValues().get(SELECTED_CHOICE))) { + checkbox.setSelected(true); + } else { + checkbox.setSelected(false); + } + } + + String getCurrentValueString() { // returns the numeric value of current selection as a string + if (checkbox.isSelected()) { + return map.getKeys().get(SELECTED_CHOICE); + } else { + return map.getKeys().get(UNSELECTED_CHOICE); + } + } + + String getDisplayText() { + if (checkbox.isSelected()) { + return map.getValues().get(SELECTED_CHOICE); + } else { + return map.getValues().get(UNSELECTED_CHOICE); + } + } + + } + private class IntPane extends EntryPane { JTextField textField = null; JComboBox box = null; SliderWithView sliderView = null; RadioButtonPane radiobuttons = null; + CheckboxPane checkbox = null; CdiRep.Map map = null; private final ConfigRepresentation.IntegerEntry entry; boolean suppressExternal = false; // used to suppress slider output when changed from read @@ -2673,6 +2726,15 @@ public void actionPerformed(ActionEvent actionEvent) { }; radiobuttons = new RadioButtonPane(map, action); textComponent = radiobuttons; + } else if (entry.rep.isCheckboxHint()) { + ActionListener action = new ActionListener() { + @Override + public void actionPerformed(ActionEvent actionEvent) { + updateColor(); + } + }; + checkbox = new CheckboxPane(map, action); + textComponent = checkbox; } else { box = new JComboBox(map.getValues().toArray(new String[]{""})) { public java.awt.Dimension getMaximumSize() { @@ -2776,6 +2838,8 @@ protected void writeDisplayTextToNode() { value = sliderView.slider.getValue(); } else if (radiobuttons != null) { value = radiobuttons.getCurrentValue(); + } else if (checkbox != null) { + value = checkbox.getCurrentValue(); } else { // have to get key from stored map value String entry = (String) box.getSelectedItem(); @@ -2797,6 +2861,8 @@ protected void updateDisplayText(@NonNull String value) { sliderView.slider.setValue(Integer.parseInt(value)); } else if (radiobuttons != null) { radiobuttons.setCurrentValue(value); + } else if (checkbox != null) { + checkbox.setCurrentValue(value); } if (box != null) { // check to see if item exists @@ -2834,6 +2900,8 @@ protected String getDisplayText() { return ""+sliderView.slider.getValue(); } else if (radiobuttons != null) { return radiobuttons.getDisplayText(); + } else if (checkbox != null) { + return checkbox.getDisplayText(); } String s = (box == null) ? (String) textField.getText() : (String) box.getSelectedItem(); @@ -2853,6 +2921,8 @@ protected String getCurrentValue() { return ""+sliderView.slider.getValue(); } else if (radiobuttons != null) { return radiobuttons.getCurrentValueString(); + } else if (checkbox != null) { + return checkbox.getCurrentValueString(); } String s; diff --git a/test/org/openlcb/cdi/swing/CdiPanelDemo.java b/test/org/openlcb/cdi/swing/CdiPanelDemo.java index 4310e09e..e34c6954 100644 --- a/test/org/openlcb/cdi/swing/CdiPanelDemo.java +++ b/test/org/openlcb/cdi/swing/CdiPanelDemo.java @@ -34,8 +34,10 @@ public void displayFile(String fileName) { // find file & load file fci.setDialogTitle("Find desired CDI file"); fci.rescanCurrentDirectory(); - - int retVal = fci.showOpenDialog(null); + + f.pack(); + f.setVisible(true); + int retVal = fci.showOpenDialog(f); // handle selection or cancel if (retVal != JFileChooser.APPROVE_OPTION) { // Run the script from it's filename