source: src/main/java/genius/gui/tree/WeightSlider.java@ 209

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

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 7.0 KB
Line 
1package genius.gui.tree;
2
3import java.awt.*;
4import java.awt.event.*;
5import java.text.*;
6import javax.swing.*;
7import javax.swing.event.*;
8
9import genius.core.issue.*;
10import genius.core.utility.*;
11
12/**
13* @author Richard Noorlandt
14*
15* Wouter: WeightSlider is a GUI component in the Tree,
16* it is always there but may be invisible (if the objective/issue has no weight).
17*/
18
19public class WeightSlider extends JPanel implements ChangeListener, ItemListener {
20
21 private static final long serialVersionUID = 4049454839954128143L;
22 //Attributes
23 static final int MIN_VALUE = 0;
24 static final int MAX_VALUE = 1000;
25
26 static final Color BACKGROUND = Color.white;
27
28 //private Objective objective;
29 //private Evaluator evaluator;
30 private NegotiatorTreeTableModel tableModel;
31 private Objective objective; // for which objective is this the weight slider
32 private JCheckBox lock;
33 private JSlider slider;
34 private JFormattedTextField valueField;
35
36 private double weight = 0; // < Might change, should probably be done from within objective, model or evaluator. Ony the question is: which?
37
38
39
40 //Constructors
41
42 //public WeightSlider(Objective obj) {
43 public WeightSlider(NegotiatorTreeTableModel model, Objective obj) {
44 tableModel = model;
45 objective = obj;
46
47 this.setBackground(BACKGROUND);
48 this.setLayout(new FlowLayout());
49
50 slider = new JSlider(MIN_VALUE, MAX_VALUE);
51 //slider.setBackground(BACKGROUND);
52 slider.setToolTipText("Drag to change the weight");
53 slider.addChangeListener(this);
54 this.add(slider);
55
56 NumberFormat format = NumberFormat.getNumberInstance();
57 format.setMaximumFractionDigits(2);
58 valueField = new JFormattedTextField(format);
59 valueField.setColumns(4);
60 valueField.setToolTipText("Fill in a weight between 0 and 1");
61 valueField.setEditable(false);
62 this.add(valueField);
63
64 lock = new JCheckBox();
65 lock.setBackground(BACKGROUND);
66 lock.setToolTipText("Lock weight");
67 lock.addItemListener(this);
68 this.add(lock);
69
70 // Wouter: new code using the hasWeight field.
71 boolean hasweight=true;
72 AdditiveUtilitySpace us=tableModel.getUtilitySpace();
73 if (us != null)
74 {
75 Evaluator ev=us.getEvaluator(obj.getNumber());
76 //if (ev==null) System.out.println("no evaluator found for "+obj);
77 if (ev instanceof EvaluatorObjective) // should always be the case??
78 hasweight=((EvaluatorObjective)ev).getHasWeight();
79 }
80 setVisible(hasweight);
81
82
83 //Added by Herbert
84 if((tableModel.getUtilitySpace() != null) && tableModel.getUtilitySpace().getEvaluator(obj.getNumber())== null || obj.getName().equals("root")){
85 slider.setVisible(false);
86 valueField.setVisible(false);
87 lock.setVisible(false);
88 }
89
90 updatePreferredSize();
91
92 }
93
94
95 //Methods
96
97 /**
98 * Sets this slider to be visible or invisible, dependent on whether there is an evaluator available. When there is no evaluator, the
99 * slider wil always be invisible.
100 * @param vis True makes the slider visible, false wil hide the slider.
101 */
102 public void setVisible(boolean vis){
103 if(((tableModel.getUtilitySpace() != null) && (tableModel.getUtilitySpace().getEvaluator(objective.getNumber()) == null)) || (objective.getName().equals("root"))){
104 slider.setVisible(false);
105 valueField.setVisible(false);
106 lock.setVisible(false);
107 }else{
108 slider.setVisible(vis);
109 valueField.setVisible(vis);
110 lock.setVisible(vis);
111 }
112 }
113
114 /**
115 * Converts an int between MIN_VALUE and MAX_VALUE to a double between 0 and 1. This method is
116 * necessary because JSlider only works on int, and weights are doubles between 0 and 1.
117 * @param value the value to be converted.
118 * @return the value converted to a double.
119 */
120 private double convertToDouble(int value) {
121 if (value < MIN_VALUE)
122 return 0;
123 if (value > MAX_VALUE)
124 return 1;
125
126 return (double)value / (double)( (MAX_VALUE) - MIN_VALUE);
127 }
128
129 /**
130 * Converts a double between 0 and 1 to an int between MIN_VALUE and MAX_VALUE. This method is
131 * necessary because JSlider only works on int, and weights are in doubles between 0 and 1.
132 * @param value the value to e converted.
133 * @return the value converted to an int between MIN_VALUE and MAX_VALUE.
134 */
135 private int convertToInt(double value) {
136 if (value < 0)
137 return MIN_VALUE;
138 if (value > 1)
139 return MAX_VALUE;
140
141 return (int)(value*((double)MAX_VALUE - (double)MIN_VALUE)) + MIN_VALUE;
142 }
143
144 /**
145 *
146 * @return the weight.
147 */
148 public double getWeight() {
149 return weight;
150 }
151
152 /**
153 *
154 * @param newWeight the new weight.
155 */
156 public void setWeight(double newWeight) {
157 weight = newWeight;
158 valueField.setValue(weight);
159 slider.setValue(convertToInt(weight));
160 // Wouter: try to call explicit treeStructureChanged after change.
161 tableModel.treeNodesChanged(objective, objective.getPath().getPath());
162 }
163
164 public Objective getObjective() {
165 return objective;
166 }
167
168 //public void setObjective(Objective obj) {
169 //
170 //}
171
172 /**
173 * Tries to set the new weight, and signals the NegotiatorTreeTableModel that weights are updated.
174 * @param newWeight the new weight.
175 */
176 public void changeWeight(double newWeight) {
177 weight = tableModel.getUtilitySpace().setWeight(objective, newWeight);
178 tableModel.updateWeights(this, weight);
179 setWeight(weight); //redundant
180
181 }
182
183 public void stateChanged(ChangeEvent e) {
184 if (e.getSource() != slider){
185 return;
186 }
187 double newWeight = convertToDouble(slider.getValue());
188 valueField.setValue(newWeight);
189 changeWeight(newWeight);
190 }
191
192 /**
193 * Implementation of ItemListener, which is registered on the checkbox. If the checkbox state changes,
194 * the slider and textfield will be locked or unlocked. An unchecked checkbox means that the weight
195 * can be changed.
196 * @param e as defined by the ItemListener interface.
197 */
198 public void itemStateChanged(ItemEvent e) {
199 if (e.getStateChange() == ItemEvent.SELECTED) {
200 slider.setEnabled(false);
201 valueField.setEnabled(false);
202 tableModel.getUtilitySpace().lock(objective);
203 }
204 //Otherwise, it is deselected
205 else {
206 slider.setEnabled(true);
207 valueField.setEnabled(true);
208 tableModel.getUtilitySpace().unlock(objective);
209 }
210 }
211
212 /**
213 * Calculates and sets this objects preferred size, based on its subcomponents.
214 *
215 */
216 protected void updatePreferredSize() {
217 int prefHeight = lock.getPreferredSize().height;
218 if (slider.getPreferredSize().height > prefHeight)
219 prefHeight = slider.getPreferredSize().height;
220 if (valueField.getPreferredSize().height > prefHeight)
221 prefHeight = valueField.getPreferredSize().height;
222
223 int prefWidth = lock.getPreferredSize().width + slider.getPreferredSize().width + valueField.getPreferredSize().width;
224
225 this.setPreferredSize(new Dimension(prefWidth, prefHeight));
226 }
227
228 public void forceRedraw(){
229 try{
230 this.changeWeight(this.getWeight());
231 }catch(Exception e){
232 //do nothing, maybe we don't have a weight
233 }
234 this.setVisible(true);
235 this.repaint();
236 }
237}
238
Note: See TracBrowser for help on using the repository browser.