1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package p3j.gui.dialogs;
17
18 import java.awt.BorderLayout;
19 import java.awt.Component;
20 import java.awt.Dimension;
21 import java.awt.event.ActionEvent;
22 import java.awt.event.ActionListener;
23 import java.util.List;
24
25 import javax.swing.BoxLayout;
26 import javax.swing.ButtonGroup;
27 import javax.swing.JButton;
28 import javax.swing.JCheckBox;
29 import javax.swing.JLabel;
30 import javax.swing.JPanel;
31 import javax.swing.JRadioButton;
32 import javax.swing.JScrollPane;
33 import javax.swing.JTextField;
34
35 import org.jamesii.gui.utils.BasicUtilities;
36
37 import p3j.misc.gui.GUI;
38 import p3j.pppm.SubPopulation;
39 import p3j.pppm.SubPopulationModel;
40
41 import com.jgoodies.forms.builder.ButtonBarBuilder2;
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70 public class SubPopulationModelEditDialog extends ProjectionDialog {
71
72
73 private static final long serialVersionUID = -3979733245241552349L;
74
75
76 private final SubPopulationModel subPopulationModel;
77
78
79 private final JPanel subPopListPanel = new JPanel();
80 {
81 subPopListPanel.setLayout(new BoxLayout(subPopListPanel, BoxLayout.Y_AXIS));
82 }
83
84
85 private final JScrollPane listScroll = new JScrollPane(subPopListPanel);
86
87
88 private final boolean editingAllowed;
89
90
91
92
93
94 private boolean confirmed = false;
95
96
97
98
99
100
101
102
103
104 public SubPopulationModelEditDialog(SubPopulationModel subPopModel,
105 boolean editingAllowed) {
106 this.editingAllowed = editingAllowed;
107 subPopulationModel = new SubPopulationModel(subPopModel.getSubPopulations());
108
109 setModal(true);
110 setTitle((editingAllowed ? "Edit" : "Show") + " Sub-Populations");
111 setSize(DIALOG_WIDTH, 2 * DIALOG_HEIGHT);
112 GUI.centerOnScreen(this);
113 initialize();
114 }
115
116 @Override
117 protected void okAction() {
118 this.confirmed = true;
119 setVisible(false);
120 }
121
122 public SubPopulationModel getSubPopulationModel() {
123 return subPopulationModel;
124 }
125
126 public boolean isConfirmed() {
127 return confirmed;
128 }
129
130 private void addSubPopulation(SubPopulation subPopulation,
131 Component subPopPanel, int index) {
132 subPopulationModel.getSubPopulations().add(index, subPopulation);
133 subPopListPanel.add(subPopPanel, index);
134 }
135
136 private Component removeSubPopulation(int indexToDelete) {
137 Component deleted = subPopListPanel.getComponent(indexToDelete);
138 subPopListPanel.remove(indexToDelete);
139 subPopulationModel.getSubPopulations().remove(indexToDelete);
140 return deleted;
141 }
142
143 private void refreshSubPopList() {
144 BasicUtilities.revalidateOnEDT(subPopListPanel);
145 listScroll.validate();
146 }
147
148
149
150
151
152
153
154
155
156
157
158
159 private synchronized void addSubPopulation(SubPopulation subPopulation) {
160 for (SubPopulation subPop : subPopulationModel.getSubPopulations())
161 if (subPop.getSimplifiedName().equals(subPopulation.getSimplifiedName())) {
162 GUI.printMessage(
163 this,
164 "Adding sub-population failed",
165 "Sub-population names must be unique (when converted to lower case, ignoring special characters like '/' and '\\'). \nThere already is a sub-population called '"
166 + subPopulation.getName() + "'.");
167 return;
168 }
169 int index = subPopulationModel.getSubPopulations().size();
170 addSubPopulation(subPopulation,
171 createSubPopulationDisplayPanel(subPopulation, index), index);
172 refreshSubPopList();
173 }
174
175 private synchronized void removeSubPopulation(SubPopulation subPopulation) {
176 if (subPopulationModel.getSubPopulations().size() == 1) {
177 GUI.printMessage(this, "Deletion failed",
178 "At least one sub-population has to be defined.");
179 return;
180 }
181 int indexToDelete = subPopulationModel.getSubPopulations().indexOf(
182 subPopulation);
183 if (indexToDelete >= 0) {
184 removeSubPopulation(indexToDelete);
185
186 }
187 refreshSubPopList();
188 }
189
190 private synchronized void moveSubPopulationUp(SubPopulation subPop) {
191 int currentIndex = subPopulationModel.getSubPopulations().indexOf(subPop);
192 if (currentIndex <= 0)
193 return;
194 Component componentToMove = removeSubPopulation(currentIndex);
195 addSubPopulation(subPop, componentToMove, currentIndex - 1);
196 refreshSubPopList();
197 }
198
199 private synchronized void moveSubPopulationDown(SubPopulation subPop) {
200 int currentIndex = subPopulationModel.getSubPopulations().indexOf(subPop);
201 if (currentIndex == subPopulationModel.getSubPopulations().size() - 1
202 || currentIndex < 0)
203 return;
204 Component componentToMove = removeSubPopulation(currentIndex);
205 addSubPopulation(subPop, componentToMove, currentIndex + 1);
206 refreshSubPopList();
207 }
208
209
210
211
212 private void initialize() {
213
214 JPanel overall = new JPanel(GUI.getStdBorderLayout());
215 getContentPane().add(overall);
216
217 JPanel content = new JPanel(GUI.getStdBorderLayout());
218 content.add(initializeSubPopListPanel(), BorderLayout.CENTER);
219 content.add(editingAllowed ? createAddSubPopPanel() : new JPanel(),
220 BorderLayout.SOUTH);
221
222 overall.add(new JPanel(), BorderLayout.NORTH);
223 overall.add(new JPanel(), BorderLayout.WEST);
224 overall.add(new JPanel(), BorderLayout.EAST);
225 overall.add(content, BorderLayout.CENTER);
226 overall.add(createButtonPanel(), BorderLayout.SOUTH);
227 }
228
229 private JPanel initializeSubPopListPanel() {
230 List<SubPopulation> subPops = subPopulationModel.getSubPopulations();
231 for (int i = 0; i < subPops.size(); i++)
232 subPopListPanel.add(createSubPopulationDisplayPanel(subPops.get(i), i));
233 JPanel surroundingPanel = new JPanel(GUI.getStdBorderLayout());
234 surroundingPanel.add(listScroll, BorderLayout.CENTER);
235 return surroundingPanel;
236 }
237
238 private JPanel createButtonPanel() {
239 JPanel buttonPanel = new JPanel(GUI.getStdBorderLayout());
240 buttonPanel.add(createButtonSubPanel(), BorderLayout.EAST);
241 return buttonPanel;
242 }
243
244 private JPanel createButtonSubPanel() {
245 ButtonBarBuilder2 bbBuilder = new ButtonBarBuilder2();
246 if (editingAllowed) {
247 bbBuilder.addButton(getCancelButton());
248 bbBuilder.addUnrelatedGap();
249 }
250 bbBuilder.addButton(getOkButton());
251 JPanel subPanel = new JPanel();
252 subPanel.add(bbBuilder.getPanel());
253 return subPanel;
254 }
255
256 private JPanel createAddSubPopPanel() {
257 final JRadioButton additiveButton = new JRadioButton("+");
258 additiveButton.setFont(GUI.getDefaultFontBold());
259 additiveButton.setSelected(true);
260 final JRadioButton subtractiveButton = new JRadioButton("-");
261 subtractiveButton.setFont(GUI.getDefaultFontBold());
262 final ButtonGroup buttonGroup = new ButtonGroup();
263 buttonGroup.add(additiveButton);
264 buttonGroup.add(subtractiveButton);
265 JPanel radioGroupPanel = new JPanel(GUI.getStdBorderLayout());
266 radioGroupPanel.add(additiveButton, BorderLayout.CENTER);
267 radioGroupPanel.add(subtractiveButton, BorderLayout.EAST);
268
269 final JTextField subPopName = new JTextField("Sub-Population Name");
270 final JCheckBox hasDescendantGenerations = new JCheckBox(
271 "Distinct Descendant Generations");
272 final JCheckBox jumpOffPop = new JCheckBox("Jump-Off Population");
273 final JButton addButton = new JButton("Add");
274 addButton.addActionListener(new ActionListener() {
275 @Override
276 public void actionPerformed(ActionEvent e) {
277 addSubPopulation(new SubPopulation(subPopName.getText(), jumpOffPop
278 .isSelected(), additiveButton.isSelected(),
279 hasDescendantGenerations.isSelected()));
280 }
281 });
282
283 return createAddSubPopPanelLayout(radioGroupPanel, subPopName,
284 hasDescendantGenerations, jumpOffPop, addButton);
285 }
286
287 private JPanel createAddSubPopPanelLayout(JPanel radioGroupPanel,
288 final JTextField subPopName, final JCheckBox hasDescendantGenerations,
289 JCheckBox jumpOffPop, final JButton addButton) {
290 JPanel generalPanel = new JPanel(GUI.getStdBorderLayout());
291 JPanel addButtonPanel = new JPanel(GUI.getStdBorderLayout());
292
293 JPanel optionPanel = new JPanel();
294 optionPanel.add(hasDescendantGenerations);
295 optionPanel.add(jumpOffPop);
296
297 addButtonPanel.add(radioGroupPanel, BorderLayout.WEST);
298 addButtonPanel.add(subPopName, BorderLayout.CENTER);
299 addButtonPanel.add(optionPanel, BorderLayout.EAST);
300
301 generalPanel.add(addButtonPanel, BorderLayout.CENTER);
302 generalPanel.add(addButton, BorderLayout.EAST);
303 return generalPanel;
304 }
305
306 private JPanel createSubPopulationDisplayPanel(SubPopulation subPop, int index) {
307 JPanel subPopDisplayPanel = new JPanel(GUI.getStdBorderLayout());
308 subPopDisplayPanel.add(new JPanel(), BorderLayout.NORTH);
309
310 subPopDisplayPanel.add(createAdditiveButton(subPop, index),
311 BorderLayout.WEST);
312 subPopDisplayPanel.add(createSubPopulationDescription(subPop),
313 BorderLayout.CENTER);
314 subPopDisplayPanel
315 .add(editingAllowed ? createControlButtonPanel(subPop, index)
316 : new JPanel(), BorderLayout.EAST);
317 subPopDisplayPanel.add(new JPanel(), BorderLayout.SOUTH);
318 subPopDisplayPanel.setMaximumSize(new Dimension(
319 (int) (0.8 * SubPopulationModelEditDialog.DIALOG_WIDTH), 60));
320 return subPopDisplayPanel;
321 }
322
323 private JLabel createSubPopulationDescription(SubPopulation subPop) {
324 JLabel subPopDesc = new JLabel(subPop.getName()
325 + (subPop.isJumpOffPopulation() ? " [Jump-Off]" : "")
326 + (subPop.isConsistingOfDescendantGenerations() ? " (& descendants)"
327 : ""));
328 subPopDesc.setFont(GUI.getDefaultFontBold());
329 return subPopDesc;
330 }
331
332 private JPanel createControlButtonPanel(final SubPopulation subPop,
333 final int index) {
334 JPanel buttonPanel = new JPanel();
335 buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
336 JButton deleteButton = GUI.createIconButton("delete_obj.gif", "Delete");
337 deleteButton.addActionListener(new ActionListener() {
338 @Override
339 public void actionPerformed(ActionEvent e) {
340 removeSubPopulation(subPop);
341 }
342 });
343 JButton upButton = GUI.createIconButton("step_current_up.gif", "up");
344 upButton.addActionListener(new ActionListener() {
345 @Override
346 public void actionPerformed(ActionEvent e) {
347 moveSubPopulationUp(subPop);
348 }
349 });
350 JButton downButton = GUI.createIconButton("step_current_down.gif", "down");
351 downButton.addActionListener(new ActionListener() {
352 @Override
353 public void actionPerformed(ActionEvent e) {
354 moveSubPopulationDown(subPop);
355 }
356 });
357
358 buttonPanel.add(upButton);
359 buttonPanel.add(new JPanel());
360 buttonPanel.add(downButton);
361 buttonPanel.add(new JPanel());
362 buttonPanel.add(deleteButton);
363 return buttonPanel;
364 }
365
366 private JButton createAdditiveButton(final SubPopulation subPopulation,
367 final int subPopIndex) {
368 final JButton additivityButton = new JButton();
369 additivityButton.setEnabled(editingAllowed);
370 setButtonIcon(additivityButton, subPopulation.isAdditive());
371 additivityButton.addActionListener(new ActionListener() {
372 @Override
373 public void actionPerformed(ActionEvent e) {
374 subPopulation.setAdditive(!subPopulation.isAdditive());
375 setButtonIcon(additivityButton, subPopulation.isAdditive());
376 }
377 });
378 return additivityButton;
379 }
380
381 private static void setButtonIcon(JButton additivityButton, boolean isAdditive) {
382 GUI.decorateButtonWithIconOrText(additivityButton, GUI
383 .retrieveIcon(isAdditive ? "add_correction.png"
384 : "remove_correction.png"), isAdditive ? "+" : "-");
385 additivityButton.setToolTipText(isAdditive ? "Adds to overall population"
386 : "Subtracts from overall population");
387 }
388 }