1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 package org.diyefi.openlogviewer.optionpanel;
24
25 import java.awt.Color;
26 import java.awt.Component;
27 import java.awt.Dimension;
28 import java.awt.Point;
29 import java.awt.event.ActionEvent;
30 import java.awt.event.ActionListener;
31 import java.awt.event.ContainerEvent;
32 import java.awt.event.ContainerListener;
33 import java.awt.event.MouseEvent;
34 import java.awt.event.MouseListener;
35 import java.awt.event.MouseMotionAdapter;
36
37 import java.util.ArrayList;
38 import java.util.Collections;
39 import java.util.Iterator;
40
41 import javax.swing.JFrame;
42 import javax.swing.JPanel;
43 import javax.swing.JButton;
44 import javax.swing.JLayeredPane;
45 import javax.swing.JScrollPane;
46 import javax.swing.JLabel;
47 import javax.swing.JInternalFrame;
48 import javax.swing.JTextField;
49 import javax.swing.JColorChooser;
50 import javax.swing.BorderFactory;
51
52 import org.diyefi.openlogviewer.OpenLogViewerApp;
53 import org.diyefi.openlogviewer.genericlog.GenericDataElement;
54 import org.diyefi.openlogviewer.genericlog.GenericLog;
55 import org.diyefi.openlogviewer.propertypanel.SingleProperty;
56
57
58
59
60
61 @SuppressWarnings("serial")
62 public class OptionFrameV2 extends JFrame {
63
64 private JFrame thisRef;
65 private JPanel inactiveHeaders;
66 private ModifyGraphPane infoPanel;
67 private JButton addDivisionButton;
68
69 private JLayeredPane layeredPane;
70 private ArrayList<JPanel> activePanelList;
71
72 private static final int WIDTH_OF_BOXES = 6;
73 private static final int HEIGHT_OF_BOXES = 2;
74 private static final int MAX_NUMBER_OF_BOXES = WIDTH_OF_BOXES * HEIGHT_OF_BOXES;
75
76 private static final int NUMBER_OF_COLS_OF_FREEEMS_FIELDS = 7;
77 private static final int HEIGHT_IN_FIELDS = 12;
78 private static final int NUMBER_OF_ADD_BUTTONS = 1;
79
80 private static final int WTF = 4;
81 private static final int WTF2 = 3;
82 private static final int COMP_HEIGHT = 20;
83 private static final int COMP_WIDTH = 200;
84 private static final int PANEL_WIDTH = 140;
85 private static final int PANEL_HEIGHT = 120;
86 private static final int SCROLL_BAR_SIZE = 16;
87
88
89 private static final int WIDTH_OF_WINDOW = (NUMBER_OF_COLS_OF_FREEEMS_FIELDS * PANEL_WIDTH);
90 private static final int HEIGHT_OF_WINDOW = ((PANEL_HEIGHT * HEIGHT_OF_BOXES) + (COMP_HEIGHT * (HEIGHT_IN_FIELDS + NUMBER_OF_ADD_BUTTONS)));
91
92 public OptionFrameV2() {
93
94 super("Graphing Option Pane");
95 this.setSize(WIDTH_OF_WINDOW + WTF2, HEIGHT_OF_WINDOW + COMP_HEIGHT + SCROLL_BAR_SIZE + WTF);
96 this.setPreferredSize(this.getSize());
97
98 this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
99 thisRef = this;
100 activePanelList = new ArrayList<JPanel>();
101 layeredPane = new JLayeredPane();
102 layeredPane.setPreferredSize(new Dimension(WIDTH_OF_WINDOW, HEIGHT_OF_WINDOW));
103
104
105 JScrollPane scroll = new JScrollPane(layeredPane);
106
107 inactiveHeaders = initHeaderPanel();
108 layeredPane.add(inactiveHeaders);
109 infoPanel = new ModifyGraphPane();
110 this.add(infoPanel);
111
112 this.add(scroll);
113 addActiveHeaderPanel();
114
115 }
116
117 private JPanel initHeaderPanel() {
118 JPanel ih = new JPanel();
119 ih.setLayout(null);
120 ih.setName("Drop InactiveHeaderPanel");
121 this.addDivisionButton = new JButton("Add Division");
122 addDivisionButton.setBounds(0, 0, PANEL_WIDTH, COMP_HEIGHT);
123 addDivisionButton.addActionListener(addDivisionListener);
124 ih.add(addDivisionButton);
125 ih.setBounds(0, 0, 1280, (COMP_HEIGHT * (HEIGHT_IN_FIELDS + NUMBER_OF_ADD_BUTTONS)));
126 return ih;
127 }
128 private ActionListener addDivisionListener = new ActionListener() {
129
130 @Override
131 public void actionPerformed(ActionEvent e) {
132 addActiveHeaderPanel();
133 }
134 };
135 private ActionListener remDivisionListener = new ActionListener() {
136
137 @Override
138 public void actionPerformed(ActionEvent e) {
139 remActiveHeaderPanel(e);
140 }
141 };
142 private ContainerListener addRemoveListener = new ContainerListener() {
143
144 @Override
145 public void componentAdded(ContainerEvent e) {
146
147 if (e.getChild() != null) {
148 if (e.getChild() instanceof ActiveHeaderLabel) {
149 ((ActiveHeaderLabel) e.getChild()).setEnabled(true);
150 ((ActiveHeaderLabel) e.getChild()).setSelected(true);
151 ((ActiveHeaderLabel) e.getChild()).getGDE().setSplitNumber(
152 activePanelList.indexOf(
153 e.getChild().getParent()) + 1);
154 }
155 }
156 }
157
158 @Override
159 public void componentRemoved(ContainerEvent e) {
160 if (e.getChild() != null) {
161 if (e.getChild() instanceof ActiveHeaderLabel) {
162 ((ActiveHeaderLabel) e.getChild()).setEnabled(false);
163 ((ActiveHeaderLabel) e.getChild()).setSelected(false);
164 }
165 for (int i = 0; i < e.getContainer().getComponentCount(); i++) {
166 if (e.getContainer().getComponent(i) instanceof ActiveHeaderLabel) {
167 e.getContainer().getComponent(i).setLocation(0, i * COMP_HEIGHT);
168 }
169 }
170 }
171 }
172 };
173
174 private void addActiveHeaderPanel() {
175
176 if (activePanelList.size() < MAX_NUMBER_OF_BOXES) {
177
178 int row = activePanelList.size() / WIDTH_OF_BOXES;
179 int col = activePanelList.size() % WIDTH_OF_BOXES;
180 JPanel activePanel = new JPanel();
181 activePanelList.add(activePanel);
182 if (OpenLogViewerApp.getInstance() != null) {
183 OpenLogViewerApp.getInstance().getMultiGraphLayeredPane().setTotalSplits(activePanelList.size());
184 }
185 activePanel.setLayout(null);
186 activePanel.setName("Drop ActivePanel " + (activePanelList.indexOf(activePanel) + 1));
187 activePanel.addContainerListener(addRemoveListener);
188
189 activePanel.setBounds((col * PANEL_WIDTH), inactiveHeaders.getHeight() + PANEL_HEIGHT * row, PANEL_WIDTH, PANEL_HEIGHT);
190 activePanel.setBackground(Color.DARK_GRAY);
191 JButton removeButton = new JButton("Remove");
192 removeButton.setToolTipText("Click Here to remove this division and associated Graphs");
193 removeButton.setBounds(0, 0, PANEL_WIDTH, COMP_HEIGHT);
194 removeButton.addActionListener(remDivisionListener);
195 activePanel.add(removeButton);
196 layeredPane.add(activePanel);
197 if (activePanelList.size() == MAX_NUMBER_OF_BOXES) {
198 addDivisionButton.setEnabled(false);
199 }
200 }
201 }
202
203 private void remActiveHeaderPanel(ActionEvent e) {
204 JPanel panel = (JPanel) ((JButton) e.getSource()).getParent();
205 activePanelList.remove(panel);
206 OpenLogViewerApp.getInstance().getMultiGraphLayeredPane().setTotalSplits(activePanelList.size());
207 for (int i = 0; i < panel.getComponentCount();) {
208 if (panel.getComponent(i) instanceof ActiveHeaderLabel) {
209 ActiveHeaderLabel GCB = (ActiveHeaderLabel) panel.getComponent(i);
210 GCB.getInactivePanel().add(GCB);
211 GCB.setLocation(GCB.getInactiveLocation());
212 GCB.setSelected(false);
213 } else if (panel.getComponent(i) instanceof JButton) {
214 panel.remove(panel.getComponent(i));
215 } else {
216 i++;
217 }
218 }
219
220 panel.getParent().remove(panel);
221 for (int i = 0; i < activePanelList.size(); i++) {
222 int row = i / WIDTH_OF_BOXES;
223 int col = i % WIDTH_OF_BOXES;
224 activePanelList.get(i).setLocation((col * PANEL_WIDTH), inactiveHeaders.getHeight() + PANEL_HEIGHT * row);
225 }
226 if (!addDivisionButton.isEnabled()) {
227 addDivisionButton.setEnabled(true);
228 }
229
230 if (activePanelList.size() > 1) {
231 for (int i = 0; i < activePanelList.size(); i++) {
232 JPanel active = activePanelList.get(i);
233 if (active.getComponentCount() > 1) {
234 for (int j = 0; j < active.getComponentCount(); j++) {
235 if (active.getComponent(j) instanceof ActiveHeaderLabel) {
236 ((ActiveHeaderLabel) active.getComponent(j)).getGDE().setSplitNumber(i + 1);
237 }
238 }
239 }
240 }
241 }
242 if(activePanelList.isEmpty()) addActiveHeaderPanel();
243 this.repaint();
244 }
245 private MouseMotionAdapter labelAdapter = new MouseMotionAdapter() {
246
247 @Override
248 public void mouseDragged(MouseEvent e) {
249 Component c = e.getComponent();
250 ActiveHeaderLabel GCB = (ActiveHeaderLabel) c;
251 GCB.setDragging(true);
252 if (c.getParent() != null && layeredPane.getMousePosition() != null && (e.getModifiers() == 16)) {
253 if (!c.getParent().contains(layeredPane.getMousePosition().x - c.getParent().getX(), layeredPane.getMousePosition().y - c.getParent().getY())) {
254 Component cn = c.getParent().getParent().getComponentAt(layeredPane.getMousePosition());
255 if (cn instanceof JPanel) {
256 JPanel j = (JPanel) cn;
257 if (j.getName().contains("Drop")) {
258 j.add(c);
259 c.setLocation(
260
261 layeredPane.getMousePosition().x - c.getParent().getX() - (c.getWidth() / 2),
262 layeredPane.getMousePosition().y - c.getParent().getY() - (c.getHeight() / 2));
263 }
264 }
265 } else {
266 c.setLocation(c.getX() + e.getX() - (c.getWidth() / 2), c.getY() + e.getY() - (c.getHeight() / 2));
267 }
268 thisRef.repaint();
269 }
270 }
271 };
272
273 private boolean place(ActiveHeaderLabel GCB) {
274 int x = 0;
275 int y = COMP_HEIGHT;
276 while (y < GCB.getParent().getHeight()) {
277 if (GCB.getParent().getComponentAt(x, y) == GCB.getParent() || GCB.getParent().getComponentAt(x, y) == GCB) {
278 GCB.setLocation(x, y);
279 return true;
280 }
281 y = y + COMP_HEIGHT;
282 }
283 return false;
284 }
285
286 public void updateFromLog(GenericLog gl) {
287
288 while (activePanelList.size() > 0) {
289 activePanelList.get(0).removeAll();
290 layeredPane.remove(activePanelList.get(0));
291 activePanelList.remove(activePanelList.get(0));
292 }
293
294 addDivisionButton.setEnabled(true);
295
296 if (inactiveHeaders.getComponentCount() > 1) {
297 inactiveHeaders.removeAll();
298 inactiveHeaders.add(this.addDivisionButton);
299 }
300 this.addActiveHeaderPanel();
301
302
303 ArrayList<ActiveHeaderLabel> tmpList = new ArrayList<ActiveHeaderLabel>();
304 Iterator<String> i = gl.keySet().iterator();
305 String head = "";
306 ActiveHeaderLabel toBeAdded = null;
307
308 while (i.hasNext()) {
309 head = (String) i.next();
310 GenericDataElement GDE = gl.get(head);
311 toBeAdded = new ActiveHeaderLabel();
312
313 toBeAdded.setName(head);
314 toBeAdded.setText(head);
315 toBeAdded.setRef(GDE);
316 toBeAdded.setEnabled(false);
317 toBeAdded.addMouseMotionListener(labelAdapter);
318 if (checkForProperties(toBeAdded, GDE)) {
319 toBeAdded.setBackground(GDE.getColor());
320 }
321 tmpList.add(toBeAdded);
322
323 }
324 Collections.sort(tmpList);
325 int j = 0;
326 int leftSide = 0;
327 for (int it = 0; it < tmpList.size(); it++) {
328 if (COMP_HEIGHT + (COMP_HEIGHT * (j + 1)) > inactiveHeaders.getHeight()) {
329 j = 0;
330 leftSide += PANEL_WIDTH;
331 }
332 tmpList.get(it).setBounds(leftSide, (COMP_HEIGHT + (COMP_HEIGHT * j)), PANEL_WIDTH, COMP_HEIGHT);
333 inactiveHeaders.add(tmpList.get(it));
334
335 j++;
336
337 }
338
339 this.repaint();
340 this.setDefaultCloseOperation(JFrame.ICONIFIED);
341 this.setVisible(true);
342 }
343
344 private boolean checkForProperties(ActiveHeaderLabel GCB, GenericDataElement GDE) {
345 for (int i = 0; i < OpenLogViewerApp.getInstance().getProperties().size(); i++) {
346 if (OpenLogViewerApp.getInstance().getProperties().get(i).getHeader().equals(GDE.getName())) {
347 GDE.setColor(OpenLogViewerApp.getInstance().getProperties().get(i).getColor());
348 GDE.setMaxValue(OpenLogViewerApp.getInstance().getProperties().get(i).getMax());
349 GDE.setMinValue(OpenLogViewerApp.getInstance().getProperties().get(i).getMin());
350 GDE.setSplitNumber(OpenLogViewerApp.getInstance().getProperties().get(i).getSplit());
351 if (OpenLogViewerApp.getInstance().getProperties().get(i).isActive()) {
352
353 return true;
354 }
355 }
356 }
357 return false;
358 }
359
360 private class ModifyGraphPane extends JInternalFrame {
361
362 GenericDataElement GDE;
363 ActiveHeaderLabel AHL;
364 private JLabel minLabel;
365 private JLabel maxLabel;
366 private JTextField minField;
367 private JTextField maxField;
368 private JButton resetButton;
369 private JButton applyButton;
370 private JButton saveButton;
371 private JButton colorButton;
372 private ActionListener resetButtonListener = new ActionListener() {
373
374 @Override
375 public void actionPerformed(ActionEvent e) {
376 if (GDE != null) {
377 GDE.reset();
378 minField.setText(Double.toString(GDE.getMinValue()));
379 maxField.setText(Double.toString(GDE.getMaxValue()));
380 }
381 }
382 };
383 private ActionListener applyButtonListener = new ActionListener() {
384
385 @Override
386 public void actionPerformed(ActionEvent e) {
387 if (GDE != null) {
388 changeGDEValues();
389 }
390 }
391 };
392 private ActionListener saveButtonListener = new ActionListener() {
393
394 @Override
395 public void actionPerformed(ActionEvent e) {
396 if (GDE != null) {
397 changeGDEValues();
398 OpenLogViewerApp.getInstance().getPropertyPane().addPropertyAndSave(new SingleProperty(GDE));
399 }
400 }
401 };
402 private ActionListener colorButtonListener = new ActionListener() {
403
404 @Override
405 public void actionPerformed(ActionEvent e) {
406 Color c = JColorChooser.showDialog(
407 new JFrame(),
408 "Choose Background Color",
409 colorButton.getForeground());
410 if (c != null) {
411 colorButton.setForeground(c);
412 }
413 }
414 };
415
416 public ModifyGraphPane() {
417 this.setName("InfoPanel");
418 minLabel = new JLabel("Min:");
419 maxLabel = new JLabel("Max:");
420 minField = new JTextField(10);
421 maxField = new JTextField(10);
422 resetButton = new JButton("Reset Min/Max");
423 resetButton.addActionListener(resetButtonListener);
424
425 applyButton = new JButton("Apply");
426 applyButton.addActionListener(applyButtonListener);
427
428 saveButton = new JButton("Save");
429 saveButton.addActionListener(saveButtonListener);
430
431 colorButton = new JButton("Color");
432 colorButton.addActionListener(colorButtonListener);
433
434
435
436 minLabel.setBounds(0, 0, COMP_WIDTH / 2, COMP_HEIGHT);
437 minField.setBounds(100, 0, COMP_WIDTH / 2, COMP_HEIGHT);
438 maxLabel.setBounds(0, 20, COMP_WIDTH / 2, COMP_HEIGHT);
439 maxField.setBounds(100, 20, COMP_WIDTH / 2, COMP_HEIGHT);
440 colorButton.setBounds(0, 40, COMP_WIDTH, COMP_HEIGHT);
441 applyButton.setBounds(0, 60, COMP_WIDTH / 2, COMP_HEIGHT);
442 saveButton.setBounds(100, 60, COMP_WIDTH / 2, COMP_HEIGHT);
443 resetButton.setBounds(0, 80, COMP_WIDTH, COMP_HEIGHT);
444
445 this.setLayout(null);
446
447
448 this.add(minLabel);
449 this.add(minField);
450 this.add(maxLabel);
451 this.add(maxField);
452 this.add(colorButton);
453 this.add(applyButton);
454 this.add(saveButton);
455 this.add(resetButton);
456 this.setBounds(500, 180, 210, 133);
457 this.setMaximizable(false);
458 this.setDefaultCloseOperation(JInternalFrame.HIDE_ON_CLOSE);
459 this.setClosable(true);
460 }
461
462 public void setGDE(GenericDataElement gde, ActiveHeaderLabel ahl) {
463 this.GDE = gde;
464 this.AHL = ahl;
465 this.setTitle(GDE.getName());
466 minField.setText(GDE.getMinValue().toString());
467 maxField.setText(GDE.getMaxValue().toString());
468 colorButton.setForeground(GDE.getColor());
469 }
470
471 private void changeGDEValues() {
472 try {
473 GDE.setMaxValue(Double.parseDouble(maxField.getText()));
474 } catch (Exception ex) {
475
476 }
477 try {
478 GDE.setMinValue(Double.parseDouble(minField.getText()));
479 } catch (Exception ex) {
480
481 }
482 if (!GDE.getColor().equals(colorButton.getForeground())) {
483 GDE.setColor(colorButton.getForeground());
484 AHL.setForeground(colorButton.getForeground());
485 }
486 }
487 }
488
489 private class ActiveHeaderLabel extends JLabel implements Comparable<Object> {
490
491 private GenericDataElement GDE;
492 private Point inactiveLocation;
493 private JPanel previousPanel;
494 private JPanel inactivePanel;
495 private boolean dragging;
496 private boolean selected;
497 private MouseListener selectedListener = new MouseListener() {
498
499 @Override
500 public void mouseClicked(MouseEvent e) {
501 if (e.getModifiers() == 16) {
502 setSelected(!selected);
503 } else if (e.getModifiers() == 18) {
504 infoPanel.setGDE(GDE, (ActiveHeaderLabel) e.getSource());
505 if (!infoPanel.isVisible()) {
506 infoPanel.setVisible(true);
507
508 }
509 }
510
511 }
512
513 @Override
514 public void mouseEntered(MouseEvent e) {
515 }
516
517 @Override
518 public void mouseExited(MouseEvent e) {
519 }
520
521 @Override
522 public void mousePressed(MouseEvent e) {
523 ActiveHeaderLabel GCB = (ActiveHeaderLabel) e.getSource();
524 GCB.setPreviousPanel((JPanel) GCB.getParent());
525 }
526
527 @Override
528 public void mouseReleased(MouseEvent e) {
529 ActiveHeaderLabel GCB = (ActiveHeaderLabel) e.getSource();
530 if (GCB.isDragging()) {
531 if (GCB.getParent() == inactiveHeaders) {
532 GCB.setLocation(GCB.getInactiveLocation());
533 GCB.setSelected(false);
534 GCB.setEnabled(false);
535 } else {
536
537 if (!place(GCB)) {
538 if (GCB.getPreviousPanel() != GCB.getParent()) {
539 GCB.getPreviousPanel().add(GCB);
540 place(GCB);
541 }
542 if (GCB.getPreviousPanel() == GCB.getInactivePanel()) {
543 GCB.setLocation(GCB.getInactiveLocation());
544 GCB.setEnabled(false);
545 GCB.setSelected(false);
546 } else {
547 place(GCB);
548 }
549 thisRef.repaint();
550 }
551 }
552 GCB.setDragging(false);
553 }
554 }
555 };
556
557 public ActiveHeaderLabel() {
558 super();
559 addMouseListener(selectedListener);
560 super.setOpaque(false);
561 inactivePanel = inactiveHeaders;
562 dragging = false;
563 selected = false;
564 super.setBorder(BorderFactory.createEtchedBorder(Color.lightGray, Color.white));
565
566
567 }
568
569 @Override
570 public void setBounds(int x, int y, int widht, int height) {
571 super.setBounds(x, y, widht, height);
572 if (inactiveLocation == null) {
573 inactiveLocation = new Point(x, y);
574 }
575 }
576
577 public void setRef(GenericDataElement GDE) {
578 this.GDE = GDE;
579
580
581 this.setToolTipText();
582 }
583
584 @Override
585 public String getToolTipText(MouseEvent e) {
586 this.setToolTipText();
587 return getToolTipText();
588 }
589
590 public void setToolTipText() {
591 this.setToolTipText("<HTML> Data Stream: </b>" + GDE.getName()
592 + "</b><br>Min Value: <b>" + GDE.getMinValue()
593 + "</b><br>Max Value: <b>" + GDE.getMaxValue()
594 + "</b><br>Total Length: <b>" + GDE.size() + "</b> data points"
595 + "<br>To modify Min and Max values for scaling purposes Ctrl+LeftClick</HTML>");
596 }
597
598 public GenericDataElement getGDE() {
599 return GDE;
600 }
601
602 public JPanel getPreviousPanel() {
603 return previousPanel;
604 }
605
606 public void setPreviousPanel(JPanel previousPanel) {
607 this.previousPanel = previousPanel;
608 }
609
610 public Point getInactiveLocation() {
611 return inactiveLocation;
612 }
613
614 public JPanel getInactivePanel() {
615 return inactivePanel;
616 }
617
618 public boolean isDragging() {
619 return dragging;
620 }
621
622 public void setDragging(boolean dragging) {
623 this.dragging = dragging;
624 }
625
626 public void setSelected(boolean selected) {
627 if (this.isEnabled()) {
628 this.selected = selected;
629 } else {
630 this.selected = false;
631 }
632 addRemGraph();
633 }
634
635 private void addRemGraph() {
636 if (selected) {
637 this.setForeground(GDE.getColor());
638 this.repaint();
639 OpenLogViewerApp.getInstance().getMultiGraphLayeredPane().addGraph(this.getName());
640 } else {
641 this.setForeground(GDE.getColor().darker().darker());
642 if (OpenLogViewerApp.getInstance().getMultiGraphLayeredPane().removeGraph(this.getName())) {
643 OpenLogViewerApp.getInstance().getMultiGraphLayeredPane().repaint();
644 }
645 }
646 }
647
648 @Override
649 public int compareTo(Object o) {
650 if (o instanceof ActiveHeaderLabel) {
651 ActiveHeaderLabel GCB = (ActiveHeaderLabel) o;
652 return this.GDE.compareTo(GCB.getGDE());
653 } else {
654 return -1;
655 }
656 }
657 }
658 }