Found while fixing #12, and the last surviving instance of the pattern that issue was about.
What
clearObsFileButtonActionPerformed clears the observable dialog by walking a panel and matching on type:
5323: for (Component c : jPanel7.getComponents()) {
5324: if (c instanceof JTextField) {
5325: ((JTextField) c).setText("");
...
5327: } else if (c instanceof JComboBox) {
5328: ((JComboBox) c).removeAllItems();
...
5330: } else if (c instanceof JCheckBox) {
5331: ((JCheckBox) c).setSelected(false);
It works today. Measured against the current tree:
jPanel7 direct children: 31
JButton: 10 JLabel: 5 Box.Filler: 1
JTextField: 5 JComboBox: 5 JCheckBox: 5
>>> matched by the clear loop: 15
All fifteen are reached: the five *ObsField fields, the five *ObsList combos, and the five all*CheckBox boxes.
Why file it anyway
jPanel7 is the one panel layoutObservablesTab deliberately leaves alone. It adds jPanel7 to jPanel4's CENTER and never touches its children, so the panel keeps the generated GridBagLayout that puts every control directly on it.
That is precisely the arrangement jPanel2 and jPanel4 had before applyModernChrome(), and #12 is what happened next: the controls moved one level down, Container.getComponents() is not recursive, and both handlers silently matched 0 of 24. No dialog, no exception, no log line.
jPanel7 is now the last GridBagLayout island in a window that is otherwise BorderLayout with ActionBar rows, so it is the most likely next thing to be relaid out. When that happens, Clear stops clearing, just as silently, and the next run writes a customObs.txt from five lists the user believes they emptied.
Two smaller faults in the same loop:
- It matches by type, not by identity. Any
JTextField, JComboBox or JCheckBox added to jPanel7 later is cleared by Clear whether or not that was intended, and nothing at the point of adding it says so.
- It re-enables as it goes (
setEnabled(true) on the fields and combos) for reasons no comment records, which is state the loop is restoring on top of state it is clearing.
The handler already carries a comment about a related bug: the three runtime observable rows are not in jPanel7, so they had to be cleared by name above the loop, and clearing row one alone used to leave rows two and three still naming equipment.
Fix
Name the fifteen controls, the way my.stepss.config.ScenarioBinding names the twenty-three the .cfg carries. There is a natural home for that set: #12 deliberately left the picker lists out of the scenario file, and if they are ever added, the named set the format needs is the same set this loop needs.
Acceptance
- Clear empties all fifteen controls with
jPanel7's children reparented one or more levels deep.
- The check runs against the reparented tree, so it cannot pass by accident if the layout changes.
- Adding an unrelated control to the observable dialog does not silently make it something Clear resets.
Found while fixing #12, and the last surviving instance of the pattern that issue was about.
What
clearObsFileButtonActionPerformedclears the observable dialog by walking a panel and matching on type:It works today. Measured against the current tree:
All fifteen are reached: the five
*ObsFieldfields, the five*ObsListcombos, and the fiveall*CheckBoxboxes.Why file it anyway
jPanel7is the one panellayoutObservablesTabdeliberately leaves alone. It addsjPanel7tojPanel4's CENTER and never touches its children, so the panel keeps the generatedGridBagLayoutthat puts every control directly on it.That is precisely the arrangement
jPanel2andjPanel4had beforeapplyModernChrome(), and #12 is what happened next: the controls moved one level down,Container.getComponents()is not recursive, and both handlers silently matched 0 of 24. No dialog, no exception, no log line.jPanel7is now the lastGridBagLayoutisland in a window that is otherwise BorderLayout withActionBarrows, so it is the most likely next thing to be relaid out. When that happens, Clear stops clearing, just as silently, and the next run writes acustomObs.txtfrom five lists the user believes they emptied.Two smaller faults in the same loop:
JTextField,JComboBoxorJCheckBoxadded tojPanel7later is cleared by Clear whether or not that was intended, and nothing at the point of adding it says so.setEnabled(true)on the fields and combos) for reasons no comment records, which is state the loop is restoring on top of state it is clearing.The handler already carries a comment about a related bug: the three runtime observable rows are not in
jPanel7, so they had to be cleared by name above the loop, and clearing row one alone used to leave rows two and three still naming equipment.Fix
Name the fifteen controls, the way
my.stepss.config.ScenarioBindingnames the twenty-three the.cfgcarries. There is a natural home for that set: #12 deliberately left the picker lists out of the scenario file, and if they are ever added, the named set the format needs is the same set this loop needs.Acceptance
jPanel7's children reparented one or more levels deep.