source: src/main/java/genius/gui/tree/DomainAndProfileEditorPanel.java@ 86

Last change on this file since 86 was 86, checked in by Wouter Pasman, 6 years ago

#28 improve robustness of xml parser - trim string before trying to parse ints.

File size: 11.0 KB
Line 
1package genius.gui.tree;
2
3import java.awt.BorderLayout;
4import java.awt.Color;
5import java.awt.Dimension;
6import java.awt.event.MouseAdapter;
7import java.awt.event.MouseEvent;
8import java.io.IOException;
9
10import javax.swing.Icon;
11import javax.swing.ImageIcon;
12import javax.swing.JButton;
13import javax.swing.JLabel;
14import javax.swing.JMenu;
15import javax.swing.JMenuBar;
16import javax.swing.JOptionPane;
17import javax.swing.JPanel;
18import javax.swing.JScrollPane;
19import javax.swing.JTextField;
20import javax.swing.ListSelectionModel;
21import javax.swing.table.DefaultTableCellRenderer;
22import javax.swing.table.TableColumnModel;
23
24import genius.core.DomainImpl;
25import genius.core.issue.Issue;
26import genius.core.issue.Objective;
27import genius.core.jtreetable.JTreeTable;
28import genius.core.repository.DomainRepItem;
29import genius.core.utility.AdditiveUtilitySpace;
30import genius.core.utility.UncertainAdditiveUtilitySpace;
31import genius.gui.dialogs.EditIssueDialog;
32import genius.gui.dialogs.NewIssueDialog;
33
34/**
35 * Panel to edit a domain and a profile. It configures itself to domain or
36 * profile editor, depending on whether there are already profiles available for
37 * the domain.
38 */
39public class DomainAndProfileEditorPanel extends JPanel {
40
41 private static final long serialVersionUID = 9072786889017106286L;
42 // Attributes
43 private static final Color UNSELECTED = Color.WHITE;
44 private static final Color HIGHLIGHT = Color.YELLOW;
45 private JTreeTable treeTable;
46 private NegotiatorTreeTableModel model;
47 private JMenuBar menuBar;
48 private JMenu fileMenu;
49 private JMenu editMenu;
50 private DomainRepItem fDomainRepItem;
51 /** true iff no profiles for domain yet and the domain can be edited. */
52 private boolean hasNoProfiles;
53 private JTextField discount;
54 private JTextField reservationValue;
55
56 private UncertaintySettingsModel uncertaintySettings;
57
58 /**
59 * Create new profile
60 *
61 * @param domain
62 * @param hasNoProfiles
63 * if true, then there are no profiles for the domain yet and you
64 * can edit the domain.
65 */
66 public DomainAndProfileEditorPanel(DomainImpl domain,
67 boolean hasNoProfiles) {
68 this(new NegotiatorTreeTableModel(domain), hasNoProfiles);
69 }
70
71 /**
72 * Edit existing profile
73 *
74 * @param domain
75 * the domain of the profile
76 * @param utilitySpace
77 * the profile to edit
78 */
79 public DomainAndProfileEditorPanel(DomainImpl domain,
80 AdditiveUtilitySpace utilitySpace) {
81 this(new NegotiatorTreeTableModel(domain, utilitySpace), false);
82 }
83
84 public DomainAndProfileEditorPanel(NegotiatorTreeTableModel treeModel,
85 boolean hasNoProfiles) {
86 super();
87 this.hasNoProfiles = hasNoProfiles;
88 init(treeModel, null);
89 }
90
91 public void clearTreeTable(DomainImpl domain,
92 AdditiveUtilitySpace utilitySpace) {
93 init(new NegotiatorTreeTableModel(domain, utilitySpace),
94 this.getSize());
95 }
96
97 public boolean isDomain() {
98 return model.getUtilitySpace() == null;
99 }
100
101 public boolean hasNoProfiles() {
102 return hasNoProfiles;
103 }
104
105 public JTreeTable getTreeTable() {
106 return treeTable;
107 }
108
109 public NegotiatorTreeTableModel getNegotiatorTreeTableModel() {
110 return model;
111 }
112
113 public Objective getRoot() {
114 return (Objective) model.getRoot();
115 }
116
117 /*******************************************************/
118 /*********** PRIVATE CODE ******************************/
119 /*******************************************************/
120
121 private void init(NegotiatorTreeTableModel treeModel, Dimension size) {
122 final DomainAndProfileEditorPanel thisFrame = this;
123 model = treeModel;
124 setLayout(new BorderLayout());
125
126 initTable(model);
127 treeTable.addMouseListener(new MouseAdapter() {
128 @Override
129 public void mouseReleased(MouseEvent e) {
130
131 if (e.getClickCount() == 2) {
132 Object selected = treeTable.getTree()
133 .getLastSelectedPathComponent();
134
135 if (selected instanceof Issue) {
136 if (hasNoProfiles || !isDomain()) {
137 new EditIssueDialog(thisFrame, (Issue) selected);
138 } else {
139 showError(
140 "You may only edit the issues when there are no preference profiles.");
141 }
142 }
143 }
144 }
145 });
146 treeTable.setRowHeight(40);
147 // Initialize the Menu
148 initMenus();
149 JPanel bottomArea = new JPanel(new BorderLayout());
150
151 AdditiveUtilitySpace utilspace = model.getUtilitySpace();
152 if (utilspace != null) {
153 uncertaintySettings = new UncertaintySettingsModel(utilspace,
154 utilspace instanceof UncertainAdditiveUtilitySpace);
155 bottomArea.add(new UncertaintySettingsPanel(uncertaintySettings),
156 BorderLayout.CENTER);
157 }
158 bottomArea.add(savePanel(), BorderLayout.SOUTH);
159
160 add(bottomArea, BorderLayout.SOUTH);
161
162 if (size != null)
163 this.setSize(size);
164
165 }
166
167 private void showError(String error) {
168 JOptionPane.showMessageDialog(null, error, "Edit error", 0);
169
170 }
171
172 private JPanel savePanel() {
173 JButton saveButton = new JButton("Save changes");
174 Icon icon = new ImageIcon(getClass().getClassLoader()
175 .getResource("genius/gui/resources/save.png"));
176 saveButton.setPreferredSize(new Dimension(180, 60));
177 saveButton.setIcon(icon);
178 saveButton.setFont(saveButton.getFont().deriveFont(14.0f));
179 saveButton.addActionListener(new java.awt.event.ActionListener() {
180 @Override
181 public void actionPerformed(java.awt.event.ActionEvent evt) {
182 save();
183 }
184
185 });
186
187 JPanel simplePanel = new JPanel();
188 if (hasNoProfiles) {
189 addDomainEditButtons(simplePanel);
190 }
191 simplePanel.add(saveButton);
192
193 if (model.getUtilitySpace() != null) {
194 addProfileEditButtons(simplePanel);
195 }
196 return simplePanel;
197 }
198
199 private void addProfileEditButtons(JPanel simplePanel) {
200 simplePanel.add(new JLabel("Discount: "));
201 discount = new JTextField(
202 model.getUtilitySpace().getDiscountFactor() + "", 5);
203 simplePanel.add(discount);
204
205 simplePanel.add(new JLabel("Reservation value: "));
206 reservationValue = new JTextField(
207 model.getUtilitySpace().getReservationValueUndiscounted() + "",
208 5);
209 simplePanel.add(reservationValue);
210 }
211
212 private void addDomainEditButtons(JPanel simplePanel) {
213 final DomainAndProfileEditorPanel thisFrame = this;
214 JButton addIssue = new JButton("Add issue");
215 Icon icon2 = new ImageIcon(getClass().getClassLoader()
216 .getResource("genius/gui/resources/edit_add-32.png"));
217 addIssue.setPreferredSize(new Dimension(180, 60));
218 addIssue.setIcon(icon2);
219 addIssue.setFont(addIssue.getFont().deriveFont(18.0f));
220 addIssue.addActionListener(new java.awt.event.ActionListener() {
221 @Override
222 public void actionPerformed(java.awt.event.ActionEvent evt) {
223 new NewIssueDialog(thisFrame);
224 }
225 });
226 simplePanel.add(addIssue);
227
228 JButton removeIssue = new JButton("Remove issue");
229 Icon icon3 = new ImageIcon(getClass().getClassLoader()
230 .getResource("genius/gui/resources/edit_remove-32.png"));
231 removeIssue.setPreferredSize(new Dimension(180, 60));
232 removeIssue.setIcon(icon3);
233 removeIssue.setFont(removeIssue.getFont().deriveFont(18.0f));
234 removeIssue.addActionListener(new java.awt.event.ActionListener() {
235 @Override
236 public void actionPerformed(java.awt.event.ActionEvent evt) {
237 Object selected = treeTable.getTree()
238 .getLastSelectedPathComponent();
239
240 if (selected instanceof Issue) {
241 ((Issue) selected).removeFromParent();
242 // correct numbering
243 for (int i = 0; i < model.getDomain().getIssues()
244 .size(); i++) {
245 model.getDomain().getIssues().get(i).setNumber(i + 1); // +
246 // 1
247 // for
248 // root
249 }
250 treeTable.updateUI();
251 }
252 }
253 });
254 simplePanel.add(removeIssue);
255 }
256
257 private void save() {
258 if (model.getUtilitySpace() != null) {
259 saveProfile();
260 } else {
261 model.getDomain().toXML().saveToFile(model.getDomain().getName());
262 }
263 }
264
265 private void saveProfile() {
266 double newDiscount = 1.0;
267 AdditiveUtilitySpace uspace;
268 // create the right new class, depending on uncertainty setting
269 if (uncertaintySettings.getIsEnabled().getValue()) {
270 int comps = ((Double) uncertaintySettings.getComparisons()
271 .getValue()).intValue();
272 int errs = ((Double) uncertaintySettings.getErrors().getValue())
273 .intValue();
274 uspace = new UncertainAdditiveUtilitySpace(model.getUtilitySpace(),
275 comps, errs,
276 uncertaintySettings.getIsExperimental().getValue());
277 } else {
278 uspace = new AdditiveUtilitySpace(model.getUtilitySpace());
279 }
280
281 // FIXME GUI should not allow to set illegal values in first place.
282 try {
283 newDiscount = Double.parseDouble(discount.getText());
284 if (newDiscount < 0 || newDiscount > 1) {
285 showError("The discount value is not valid.");
286 return;
287 }
288 } catch (Exception e) {
289 showError("The discount value is not valid.");
290 return;
291 }
292 double newRV = 1.0;
293 try {
294 newRV = Double.parseDouble(reservationValue.getText());
295 if (newRV < 0 || newRV > 1) {
296 showError("The reservation value is not valid.");
297 return;
298 }
299 } catch (Exception e) {
300 showError("The reservation value is not valid.");
301 return;
302 }
303 uspace.setDiscount(newDiscount);
304 uspace.setReservationValue(newRV);
305 try {
306 uspace.toXML().saveToFile(model.getUtilitySpace().getFileName());
307 } catch (IOException e) {
308 showError("Something went wrong while saving:" + e.getMessage());
309 e.printStackTrace();
310 }
311 }
312
313 private void initTable(NegotiatorTreeTableModel model) {
314 treeTable = new JTreeTable(model);
315 treeTable.setPreferredSize(new Dimension(1024, 800));
316 treeTable.setPreferredScrollableViewportSize(new Dimension(1024, 300));
317 treeTable.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
318 treeTable.setRowSelectionAllowed(true);
319 treeTable.setColumnSelectionAllowed(false);
320 treeTable.setCellSelectionEnabled(true);
321
322 TableColumnModel colModel = treeTable.getColumnModel();
323 if (treeTable.getColumnCount() > 3)
324 colModel.getColumn(3).setMinWidth(220); // Wouter: make it likely
325 // that Weight column is
326 // shown completely.
327
328 DefaultTableCellRenderer labelRenderer = new JLabelCellRenderer();
329 treeTable.setDefaultRenderer(JLabel.class, labelRenderer);
330 treeTable.setDefaultRenderer(JTextField.class, labelRenderer);
331
332 IssueValueCellEditor valueEditor = new IssueValueCellEditor(model);
333 treeTable.setDefaultRenderer(IssueValuePanel.class, valueEditor);
334 treeTable.setDefaultEditor(IssueValuePanel.class, valueEditor);
335
336 WeightSliderCellEditor cellEditor = new WeightSliderCellEditor(model);
337 treeTable.setDefaultRenderer(WeightSlider.class, cellEditor);
338 treeTable.setDefaultEditor(WeightSlider.class, cellEditor);
339 treeTable.setRowHeight(24);
340
341 JScrollPane treePane = new JScrollPane(treeTable);
342 treePane.setBackground(treeTable.getBackground());
343 add(treePane, BorderLayout.CENTER);
344 }
345
346 private void initMenus() {
347 menuBar = new JMenuBar();
348 fileMenu = new JMenu("File");
349 editMenu = new JMenu("Edit");
350 menuBar.add(fileMenu);
351 menuBar.add(editMenu);
352 }
353
354}
Note: See TracBrowser for help on using the repository browser.