Skip to content
This repository was archived by the owner on Jun 18, 2026. It is now read-only.

Commit bdf1165

Browse files
refactor(RandomGraphDialog): consolidate listeners; extract spinner row helper
RandomGraphDialog had two ActionListeners attached to the model combo (one for visibility, one for description) and seven nearly-identical (label, spinner) layout blocks in the constructor. Consolidate into a single onModelChanged() listener and an addSpinnerRow helper, and replace magic model-name strings with package-private constants. Also expose narrow package-private accessors for tests. No behavioural change.
1 parent 2b14a52 commit bdf1165

1 file changed

Lines changed: 124 additions & 90 deletions

File tree

Gvisual/src/gvisual/RandomGraphDialog.java

Lines changed: 124 additions & 90 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,13 @@ public class RandomGraphDialog extends JDialog {
3030

3131
private static final long serialVersionUID = 1L;
3232

33+
// ── Model name constants (avoid magic strings) ────────────────────────
34+
static final String MODEL_ERDOS_RENYI = "erdos-renyi";
35+
static final String MODEL_BARABASI = "barabasi-albert";
36+
static final String MODEL_WATTS_STROGATZ = "watts-strogatz";
37+
static final String MODEL_RANDOM_REGULAR = "random-regular";
38+
static final String MODEL_GRID = "grid";
39+
3340
private Graph<String, Edge> generatedGraph = null;
3441

3542
private final JComboBox<String> modelCombo;
@@ -41,7 +48,8 @@ public class RandomGraphDialog extends JDialog {
4148
private final JSpinner rowsSpinner;
4249
private final JSpinner colsSpinner;
4350

44-
private final JLabel pLabel, mLabel, kLabel, betaLabel, rowsLabel, colsLabel;
51+
private final JLabel nLabel, pLabel, mLabel, kLabel, betaLabel, rowsLabel, colsLabel;
52+
private final JLabel descLabel;
4553

4654
public RandomGraphDialog(Frame owner) {
4755
super(owner, "Random Graph Generator", true);
@@ -60,63 +68,24 @@ public RandomGraphDialog(Frame owner) {
6068
c.gridx = 1;
6169
String[] models = RandomGraphGenerator.catalog().keySet().toArray(new String[0]);
6270
modelCombo = new JComboBox<>(models);
63-
modelCombo.addActionListener(e -> updateVisibility());
6471
form.add(modelCombo, c);
6572

66-
// n (vertices)
67-
c.gridx = 0; c.gridy = 1;
68-
form.add(new JLabel("Vertices (n):"), c);
69-
c.gridx = 1;
70-
nSpinner = new JSpinner(new SpinnerNumberModel(20, 2, 500, 1));
71-
form.add(nSpinner, c);
72-
73-
// p (edge probability)
74-
c.gridx = 0; c.gridy = 2;
75-
pLabel = new JLabel("Edge prob (p):");
76-
form.add(pLabel, c);
77-
c.gridx = 1;
78-
pSpinner = new JSpinner(new SpinnerNumberModel(0.15, 0.01, 1.0, 0.01));
79-
form.add(pSpinner, c);
80-
81-
// m (edges per new vertex)
82-
c.gridx = 0; c.gridy = 3;
83-
mLabel = new JLabel("Edges/vertex (m):");
84-
form.add(mLabel, c);
85-
c.gridx = 1;
86-
mSpinner = new JSpinner(new SpinnerNumberModel(2, 1, 50, 1));
87-
form.add(mSpinner, c);
88-
89-
// k (degree / neighbors)
90-
c.gridx = 0; c.gridy = 4;
91-
kLabel = new JLabel("Degree (k):");
92-
form.add(kLabel, c);
93-
c.gridx = 1;
94-
kSpinner = new JSpinner(new SpinnerNumberModel(4, 2, 50, 1));
95-
form.add(kSpinner, c);
96-
97-
// beta (rewiring)
98-
c.gridx = 0; c.gridy = 5;
99-
betaLabel = new JLabel("Rewire (β):");
100-
form.add(betaLabel, c);
101-
c.gridx = 1;
102-
betaSpinner = new JSpinner(new SpinnerNumberModel(0.3, 0.0, 1.0, 0.05));
103-
form.add(betaSpinner, c);
104-
105-
// rows
106-
c.gridx = 0; c.gridy = 6;
107-
rowsLabel = new JLabel("Rows:");
108-
form.add(rowsLabel, c);
109-
c.gridx = 1;
110-
rowsSpinner = new JSpinner(new SpinnerNumberModel(5, 1, 50, 1));
111-
form.add(rowsSpinner, c);
112-
113-
// cols
114-
c.gridx = 0; c.gridy = 7;
115-
colsLabel = new JLabel("Columns:");
116-
form.add(colsLabel, c);
117-
c.gridx = 1;
118-
colsSpinner = new JSpinner(new SpinnerNumberModel(5, 1, 50, 1));
119-
form.add(colsSpinner, c);
73+
// Parameter rows — each builds (label, spinner) pair and returns them.
74+
nSpinner = new JSpinner(new SpinnerNumberModel(20, 2, 500, 1));
75+
pSpinner = new JSpinner(new SpinnerNumberModel(0.15, 0.01, 1.0, 0.01));
76+
mSpinner = new JSpinner(new SpinnerNumberModel(2, 1, 50, 1));
77+
kSpinner = new JSpinner(new SpinnerNumberModel(4, 2, 50, 1));
78+
betaSpinner = new JSpinner(new SpinnerNumberModel(0.3, 0.0, 1.0, 0.05));
79+
rowsSpinner = new JSpinner(new SpinnerNumberModel(5, 1, 50, 1));
80+
colsSpinner = new JSpinner(new SpinnerNumberModel(5, 1, 50, 1));
81+
82+
nLabel = addSpinnerRow(form, c, 1, "Vertices (n):", nSpinner);
83+
pLabel = addSpinnerRow(form, c, 2, "Edge prob (p):", pSpinner);
84+
mLabel = addSpinnerRow(form, c, 3, "Edges/vertex (m):", mSpinner);
85+
kLabel = addSpinnerRow(form, c, 4, "Neighbors (k):", kSpinner);
86+
betaLabel = addSpinnerRow(form, c, 5, "Rewire (\u03B2):", betaSpinner);
87+
rowsLabel = addSpinnerRow(form, c, 6, "Rows:", rowsSpinner);
88+
colsLabel = addSpinnerRow(form, c, 7, "Columns:", colsSpinner);
12089

12190
add(form, BorderLayout.CENTER);
12291

@@ -139,46 +108,80 @@ public RandomGraphDialog(Frame owner) {
139108
btnPanel.add(cancelBtn);
140109
add(btnPanel, BorderLayout.SOUTH);
141110

142-
// Description label
143-
JLabel desc = new JLabel();
144-
desc.setBorder(BorderFactory.createEmptyBorder(8, 12, 4, 12));
145-
desc.setFont(desc.getFont().deriveFont(Font.ITALIC, 11f));
146-
Map<String, String> catalog = RandomGraphGenerator.catalog();
147-
modelCombo.addActionListener(e -> {
148-
String sel = (String) modelCombo.getSelectedItem();
149-
desc.setText("<html>" + catalog.getOrDefault(sel, "") + "</html>");
150-
});
151-
desc.setText("<html>" + catalog.getOrDefault(models[0], "") + "</html>");
152-
add(desc, BorderLayout.NORTH);
111+
// Description label (driven by the same listener as visibility)
112+
descLabel = new JLabel();
113+
descLabel.setBorder(BorderFactory.createEmptyBorder(8, 12, 4, 12));
114+
descLabel.setFont(descLabel.getFont().deriveFont(Font.ITALIC, 11f));
115+
add(descLabel, BorderLayout.NORTH);
116+
117+
// Single listener: previously the dialog registered two separate
118+
// ActionListeners on modelCombo (one for visibility, one for the
119+
// description label). Consolidated into one to keep update logic
120+
// atomic and avoid ordering surprises if either ever throws.
121+
modelCombo.addActionListener(e -> onModelChanged());
153122

154-
updateVisibility();
123+
onModelChanged(); // initial sync
155124
pack();
156125
setLocationRelativeTo(owner);
157126
}
158127

159-
private void updateVisibility() {
128+
/**
129+
* Adds a (label, spinner) row to {@code form} at the given grid row and
130+
* returns the created label so callers can toggle its visibility.
131+
*
132+
* <p>Extracted to remove the seven nearly-identical
133+
* "set gridx/y, new JLabel(text), set gridx, add(spinner)" blocks in
134+
* the original constructor.</p>
135+
*/
136+
private static JLabel addSpinnerRow(JPanel form, GridBagConstraints c,
137+
int gridY, String text, JSpinner spinner) {
138+
JLabel label = new JLabel(text);
139+
c.gridx = 0; c.gridy = gridY;
140+
form.add(label, c);
141+
c.gridx = 1;
142+
form.add(spinner, c);
143+
return label;
144+
}
145+
146+
/**
147+
* Reacts to a model-selection change: updates which parameter rows are
148+
* visible and refreshes the description text. Package-private so unit
149+
* tests can drive it directly without firing Swing events.
150+
*/
151+
void onModelChanged() {
160152
String model = (String) modelCombo.getSelectedItem();
161-
boolean showP = "erdos-renyi".equals(model);
162-
boolean showM = "barabasi-albert".equals(model);
163-
boolean showK = "watts-strogatz".equals(model) || "random-regular".equals(model);
164-
boolean showBeta = "watts-strogatz".equals(model);
165-
boolean showGrid = "grid".equals(model);
166-
boolean showN = !showGrid;
167-
168-
pLabel.setVisible(showP); pSpinner.setVisible(showP);
169-
mLabel.setVisible(showM); mSpinner.setVisible(showM);
170-
kLabel.setVisible(showK); kSpinner.setVisible(showK);
171-
betaLabel.setVisible(showBeta); betaSpinner.setVisible(showBeta);
172-
rowsLabel.setVisible(showGrid); rowsSpinner.setVisible(showGrid);
173-
colsLabel.setVisible(showGrid); colsSpinner.setVisible(showGrid);
174-
nSpinner.setVisible(showN);
175-
176-
// Update k label text
177-
if ("random-regular".equals(model)) {
178-
kLabel.setText("Degree (k):");
179-
} else {
180-
kLabel.setText("Neighbors (k):");
181-
}
153+
applyVisibility(model);
154+
applyDescription(model);
155+
}
156+
157+
private void applyVisibility(String model) {
158+
boolean showP = MODEL_ERDOS_RENYI.equals(model);
159+
boolean showM = MODEL_BARABASI.equals(model);
160+
boolean showK = MODEL_WATTS_STROGATZ.equals(model) || MODEL_RANDOM_REGULAR.equals(model);
161+
boolean showBeta = MODEL_WATTS_STROGATZ.equals(model);
162+
boolean showGrid = MODEL_GRID.equals(model);
163+
boolean showN = !showGrid;
164+
165+
setRowVisible(nLabel, nSpinner, showN);
166+
setRowVisible(pLabel, pSpinner, showP);
167+
setRowVisible(mLabel, mSpinner, showM);
168+
setRowVisible(kLabel, kSpinner, showK);
169+
setRowVisible(betaLabel, betaSpinner, showBeta);
170+
setRowVisible(rowsLabel, rowsSpinner, showGrid);
171+
setRowVisible(colsLabel, colsSpinner, showGrid);
172+
173+
// k-row label depends on which model is showing it
174+
kLabel.setText(MODEL_RANDOM_REGULAR.equals(model) ? "Degree (k):" : "Neighbors (k):");
175+
}
176+
177+
private static void setRowVisible(JLabel label, JSpinner spinner, boolean visible) {
178+
label.setVisible(visible);
179+
spinner.setVisible(visible);
180+
}
181+
182+
private void applyDescription(String model) {
183+
String desc = RandomGraphGenerator.catalog().getOrDefault(model, "");
184+
descLabel.setText("<html>" + desc + "</html>");
182185
}
183186

184187
private Graph<String, Edge> buildGraph() {
@@ -198,4 +201,35 @@ private Graph<String, Edge> buildGraph() {
198201
public Graph<String, Edge> getGeneratedGraph() {
199202
return generatedGraph;
200203
}
204+
205+
// ── Package-private hooks for tests ───────────────────────────────────
206+
207+
/** @return the currently selected model name */
208+
String getSelectedModel() {
209+
return (String) modelCombo.getSelectedItem();
210+
}
211+
212+
/** Selects a model by name; intended for tests. */
213+
void setSelectedModel(String model) {
214+
modelCombo.setSelectedItem(model);
215+
}
216+
217+
/** @return the parameter spinner for grid rows (test-only access). */
218+
JSpinner getRowsSpinner() { return rowsSpinner; }
219+
/** @return the parameter spinner for grid columns (test-only access). */
220+
JSpinner getColsSpinner() { return colsSpinner; }
221+
/** @return the n (vertex count) label (test-only access). */
222+
JLabel getNLabel() { return nLabel; }
223+
/** @return the p (edge probability) label (test-only access). */
224+
JLabel getPLabel() { return pLabel; }
225+
/** @return the m (edges per vertex) label (test-only access). */
226+
JLabel getMLabel() { return mLabel; }
227+
/** @return the k (degree / neighbors) label (test-only access). */
228+
JLabel getKLabel() { return kLabel; }
229+
/** @return the beta (rewiring probability) label (test-only access). */
230+
JLabel getBetaLabel() { return betaLabel; }
231+
/** @return the rows label (test-only access). */
232+
JLabel getRowsLabel() { return rowsLabel; }
233+
/** @return the cols label (test-only access). */
234+
JLabel getColsLabel() { return colsLabel; }
201235
}

0 commit comments

Comments
 (0)