View Javadoc

1   /* OpenLogViewer
2    *
3    * Copyright 2011
4    *
5    * This file is part of the OpenLogViewer project.
6    *
7    * OpenLogViewer software is free software: you can redistribute it and/or modify
8    * it under the terms of the GNU General Public License as published by
9    * the Free Software Foundation, either version 3 of the License, or
10   * (at your option) any later version.
11   *
12   * OpenLogViewer software is distributed in the hope that it will be useful,
13   * but WITHOUT ANY WARRANTY; without even the implied warranty of
14   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   * GNU General Public License for more details.
16   *
17   * You should have received a copy of the GNU General Public License
18   * along with any OpenLogViewer software.  If not, see http://www.gnu.org/licenses/
19   *
20   * I ask that if you make any changes to this file you fork the code on github.com!
21   *
22   */
23  package org.diyefi.openlogviewer.propertypanel;
24  
25  import java.awt.BorderLayout;
26  import java.awt.Color;
27  import java.awt.Dimension;
28  import java.awt.FlowLayout;
29  import java.awt.event.ActionEvent;
30  import java.awt.event.ActionListener;
31  import java.awt.event.MouseEvent;
32  import java.awt.event.MouseListener;
33  import java.io.BufferedWriter;
34  import java.io.File;
35  import java.io.FileNotFoundException;
36  import java.io.FileReader;
37  import java.io.FileWriter;
38  import java.io.IOException;
39  import java.util.ArrayList;
40  import java.util.Collections;
41  import java.util.List;
42  import java.util.Scanner;
43  import javax.swing.BorderFactory;
44  import javax.swing.JButton;
45  import javax.swing.JCheckBox;
46  import javax.swing.JColorChooser;
47  import javax.swing.JComboBox;
48  import javax.swing.JFrame;
49  import javax.swing.JLabel;
50  import javax.swing.JMenu;
51  import javax.swing.JMenuBar;
52  import javax.swing.JMenuItem;
53  import javax.swing.JOptionPane;
54  import javax.swing.JPanel;
55  import javax.swing.JScrollPane;
56  import javax.swing.JTextField;
57  import org.diyefi.openlogviewer.OpenLogViewer;
58  
59  public class PropertiesPane extends JFrame {
60  	private static final long serialVersionUID = 1L;
61  
62  	private File OLVProperties;
63  	private List<SingleProperty> properties;
64  	private List<SingleProperty> removeProperties;
65  	private JPanel propertyPanel;
66  	private JPanel propertyView;
67  
68  	public PropertiesPane(final String title) {
69  		super(title);
70  		this.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);
71  		this.setPreferredSize(new Dimension(350, 500));
72  		this.setSize(new Dimension(550, 500));
73  		this.setJMenuBar(createMenuBar());
74  
75  		propertyPanel = new JPanel();
76  		propertyPanel.setLayout(new BorderLayout());
77  		propertyView = new JPanel();
78  		propertyView.setPreferredSize(new Dimension(400, 0));
79  		propertyView.setLayout(new FlowLayout(FlowLayout.LEFT));
80  
81  		final JScrollPane jsp = new JScrollPane(propertyView);
82  		propertyPanel.add(jsp, BorderLayout.CENTER);
83  		propertyPanel.add(createAcceptPanel(), BorderLayout.SOUTH);
84  		this.add(propertyPanel);
85  	}
86  
87  	public final void setProperties(final List<SingleProperty> p) {
88  		removeProperties = new ArrayList<SingleProperty>();
89  		properties = p;
90  		setupForLoad();
91  	}
92  
93  	private void setupForLoad() {
94  		try {
95  			final String systemDelim = File.separator;
96  			final File homeDir = new File(System.getProperty("user.home"));
97  
98  			if (!homeDir.exists() || !homeDir.canRead() || !homeDir.canWrite()) {
99  				System.out.println("Iether you dont have a home director, or it isnt read/writeable... fix it");
100 
101 			} else {
102 				OLVProperties = new File(homeDir.getAbsolutePath() + systemDelim + ".OpenLogViewer");
103 			}
104 
105 			if (!OLVProperties.exists()) {
106 				try {
107 					if (OLVProperties.mkdir()) {
108 						OLVProperties = new File(homeDir.getAbsolutePath() + systemDelim + ".OpenLogViewer" + systemDelim + "OLVProperties.olv");
109 						if (OLVProperties.createNewFile()) {
110 							loadProperties();
111 						}
112 					} else {
113 						throw new RuntimeException("Couldn't create directory for props..."); // find somewhere else
114 					}
115 				} catch (IOException IOE) {
116 					System.out.print(IOE.getMessage());
117 				}
118 			} else {
119 				OLVProperties = new File(homeDir.getAbsolutePath() + systemDelim + ".OpenLogViewer" + systemDelim + "OLVProperties.olv");
120 				loadProperties();
121 			}
122 		} catch (Exception E) {
123 			System.out.print(E.getMessage());
124 		}
125 	}
126 
127 	private JMenuBar createMenuBar() {
128 		final JMenuBar propMenuBar = new JMenuBar();
129 		final JMenu optionMenu = new JMenu("Options");
130 		final JMenuItem addProp = new JMenuItem("Add New Property");
131 		final JMenuItem remProp = new JMenuItem("Remove Selected Propertys");
132 
133 		propMenuBar.add(optionMenu);
134 		addProp.addActionListener(new ActionListener() {
135 
136 			@Override
137 			public void actionPerformed(final ActionEvent evt) {
138 				final String s = (String) JOptionPane.showInputDialog(rootPane, "Enter the header for a new property");
139 				if ((s != null) && !"".equals(s) ) { // TODO Bad need of stringUtils here...
140 					SingleProperty newprop = new SingleProperty();
141 					newprop.setHeader(s);
142 					addProperty(newprop);
143 				}
144 			}
145 		});
146 
147 		remProp.addActionListener(new ActionListener() {
148 
149 			@Override
150 			public void actionPerformed(ActionEvent evt) {
151 				removePropertyPanels();
152 			}
153 		});
154 
155 		optionMenu.add(addProp);
156 		optionMenu.add(remProp);
157 
158 		return propMenuBar;
159 	}
160 
161 	private JPanel createAcceptPanel() {
162 		final JPanel aPanel = new JPanel();
163 		aPanel.setPreferredSize(new Dimension(500, 32));
164 		aPanel.setLayout(new FlowLayout(FlowLayout.RIGHT, 2, 2));
165 
166 		final JButton okButton = new JButton("OK");
167 		final JButton cancel = new JButton("Cancel");
168 
169 		okButton.addActionListener(new ActionListener() {
170 
171 			@Override
172 			public void actionPerformed(final ActionEvent e) {
173 				OpenLogViewer.getInstance().getPropertyPane().save();
174 				OpenLogViewer.getInstance().getPropertyPane().setVisible(false);
175 			}
176 		});
177 
178 		cancel.addActionListener(new ActionListener() {
179 
180 			@Override
181 			public void actionPerformed(final ActionEvent e) {
182 
183 				OpenLogViewer.getInstance().getPropertyPane().resetProperties();
184 				OpenLogViewer.getInstance().getPropertyPane().setVisible(false);
185 			}
186 		});
187 
188 		aPanel.add(cancel);
189 		aPanel.add(okButton);
190 
191 		return aPanel;
192 	}
193 
194 	private void loadProperties() {
195 		try {
196 			final Scanner scan = new Scanner(new FileReader(OLVProperties));
197 
198 			while (scan.hasNext()) {
199 				final String[] propLine = scan.nextLine().split("=");
200 				final SingleProperty sp = new SingleProperty();
201 				final String[] prop = propLine[1].split(",");
202 				sp.setHeader(propLine[0]);
203 				sp.setColor(new Color(
204 						Integer.parseInt(prop[0]),
205 						Integer.parseInt(prop[1]),
206 						Integer.parseInt(prop[2])));
207 				sp.setMin(Double.parseDouble(prop[3]));
208 				sp.setMax(Double.parseDouble(prop[4]));
209 				sp.setSplit(Integer.parseInt(prop[5]));
210 				sp.setActive(Boolean.parseBoolean(prop[6]));
211 				addProperty(sp);
212 			}
213 
214 			scan.close();
215 		} catch (FileNotFoundException FNF) {
216 			System.out.print(FNF.toString());
217 			throw new RuntimeException(FNF);
218 		}
219 	}
220 
221 	public final void save() {
222 		try {
223 			removeProperties.clear();
224 			updateProperties();
225 			final FileWriter fstream = new FileWriter(OLVProperties);
226 			final BufferedWriter out = new BufferedWriter(fstream);
227 
228 			for (int i = 0; i < properties.size(); i++) {
229 				out.write(properties.get(i).toString());
230 				out.newLine();
231 			}
232 
233 			out.close();
234 		} catch (Exception e) { // Catch exception if any
235 			System.err.println("Error: " + e.getMessage());
236 			throw new RuntimeException("Catchall of type Exception is evil!", e);
237 		}
238 	}
239 
240 	private void updateProperties() {
241 		for (int i = 0; i < propertyView.getComponentCount(); i++) {
242 			final PropertyPanel pp = (PropertyPanel) propertyView.getComponent(i);
243 			pp.updateSP();
244 		}
245 	}
246 
247 	public final void resetProperties() {
248 		for (int i = 0; i < propertyView.getComponentCount(); i++) {
249 			final PropertyPanel pp = (PropertyPanel) propertyView.getComponent(i);
250 			pp.reset();
251 		}
252 		if (removeProperties.size() > 0) {
253 			for (int i = 0; i < removeProperties.size(); i++) {
254 				addProperty(removeProperties.get(i));
255 			}
256 			removeProperties.clear();
257 		}
258 	}
259 
260 	private PropertyPanel exists(final SingleProperty sp) {
261 
262 		for (int i = 0; i < propertyView.getComponentCount(); i++) {
263 			final PropertyPanel pp = (PropertyPanel) propertyView.getComponent(i);
264 			if (pp.getSp().getHeader().equalsIgnoreCase(sp.getHeader())) {
265 				return pp;
266 			}
267 		}
268 		return null;
269 	}
270 
271 	public final void addProperty(final SingleProperty sp) {
272 		final PropertyPanel pp = exists(sp);
273 		if (pp == null) {
274 			properties.add(sp);
275 			Collections.sort(properties);
276 			propertyView.add(new PropertyPanel(sp), properties.indexOf(sp));
277 			propertyView.setPreferredSize(new Dimension(propertyView.getPreferredSize().width, propertyView.getPreferredSize().height + 60));
278 			propertyView.revalidate();
279 		} else {
280 			for (int i = 0; i < properties.size(); i++) {
281 				if (properties.get(i).getHeader().equalsIgnoreCase(sp.getHeader())) {
282 					properties.set(i, sp);
283 				}
284 			}
285 			pp.setSp(sp);
286 			pp.reset();
287 		}
288 	}
289 
290 	public final void addPropertyAndSave(final SingleProperty sp) {
291 		addProperty(sp);
292 		save();
293 	}
294 
295 	private void removeProperty(final SingleProperty sp) {
296 		if (properties.contains(sp)) {
297 			properties.remove(sp);
298 		}
299 	}
300 
301 	private void removePropertyPanels() {
302 		for (int i = 0; i < propertyView.getComponentCount();) {
303 			final PropertyPanel pp = (PropertyPanel) propertyView.getComponent(i);
304 			if (pp.getCheck().isSelected()) {
305 				if (!removeProperties.contains(pp.getSp())) {
306 					removeProperties.add(pp.getSp());
307 				}
308 
309 				removeProperty(pp.getSp()); // Move this to add to a queue of things to remove, incase of cancel
310 				propertyView.remove(propertyView.getComponent(i));
311 				propertyView.setPreferredSize(new Dimension(propertyView.getPreferredSize().width, propertyView.getPreferredSize().height - 60));
312 				propertyView.revalidate();
313 			} else {
314 				i++;
315 			}
316 		}
317 		propertyView.repaint();
318 	}
319 
320 	private final class PropertyPanel extends JPanel implements Comparable<PropertyPanel> {
321 		private static final long serialVersionUID = 1L;
322 		private SingleProperty sp;
323 		private JCheckBox check;
324 		private JPanel colorBox;
325 		private JTextField minBox;
326 		private JTextField maxBox;
327 		private JTextField splitBox;
328 		private JComboBox activeBox;
329 
330 		public PropertyPanel(final SingleProperty sp) {
331 			super();
332 			this.sp = sp;
333 			this.setLayout(new FlowLayout(FlowLayout.LEFT, 10, 2));
334 			this.setBorder(BorderFactory.createTitledBorder(sp.getHeader()));
335 			setPreferredSize(new Dimension(500, 50));
336 			final JLabel minLabel = new JLabel("Min:");
337 			final JLabel maxLabel = new JLabel("Max:");
338 			final JLabel colorLabel = new JLabel("Color:");
339 			final JLabel splitLabel = new JLabel("Split:");
340 			final JLabel activeLabel = new JLabel("Active:");
341 			splitBox = new JTextField();
342 			splitBox.setPreferredSize(new Dimension(15, 20));
343 			splitBox.setText(Integer.toString(sp.getSplit()));
344 			minBox = new JTextField();
345 			minBox.setPreferredSize(new Dimension(50, 20));
346 			minBox.setText(Double.toString(sp.getMin()));
347 			maxBox = new JTextField();
348 			maxBox.setPreferredSize(new Dimension(50, 20));
349 			maxBox.setText(Double.toString(sp.getMax()));
350 			colorBox = new JPanel();
351 			colorBox.setBackground(sp.getColor());
352 			colorBox.setPreferredSize(new Dimension(30, 20));
353 			final String[] tf = {"False", "True"};
354 			activeBox = new JComboBox(tf);
355 
356 			if (sp.isActive()) {
357 				activeBox.setSelectedIndex(1);
358 			}
359 
360 			activeBox.setPreferredSize(new Dimension(60, 20));
361 			check = new JCheckBox();
362 
363 			colorBox.addMouseListener(new MouseListener() {
364 
365 				@Override
366 				public void mouseReleased(final MouseEvent e) {
367 					final Color newColor = JColorChooser.showDialog(
368 							OpenLogViewer.getInstance().getOptionFrame(),
369 							"Choose New Color", colorBox.getBackground());
370 					if (newColor != null) {
371 						colorBox.setBackground(newColor);
372 
373 					}
374 				}
375 
376 				@Override
377 				public void mouseClicked(final MouseEvent e) {
378 				}
379 
380 				@Override
381 				public void mouseEntered(final MouseEvent e) {
382 				}
383 
384 				@Override
385 				public void mouseExited(final MouseEvent e) {
386 				}
387 
388 				@Override
389 				public void mousePressed(final MouseEvent e) {
390 				}
391 			});
392 
393 			add(colorLabel);
394 			add(colorBox);
395 			add(minLabel);
396 			add(minBox);
397 			add(maxLabel);
398 			add(maxBox);
399 			add(splitLabel);
400 			add(splitBox);
401 			add(activeLabel);
402 			add(activeBox);
403 			add(check);
404 		}
405 
406 		public JCheckBox getCheck() {
407 			return check;
408 		}
409 
410 		public SingleProperty getSp() {
411 			return sp;
412 		}
413 
414 		public void setSp(final SingleProperty sp) {
415 			this.sp = sp;
416 		}
417 
418 		public void updateSP() {
419 			sp.setMin(Double.parseDouble(minBox.getText()));
420 			sp.setMax(Double.parseDouble(maxBox.getText()));
421 			sp.setColor(colorBox.getBackground());
422 			sp.setSplit(Integer.parseInt(splitBox.getText()));
423 			final String active = (String) activeBox.getSelectedItem();
424 			sp.setActive(Boolean.parseBoolean(active));
425 		}
426 
427 		public void reset() {
428 			minBox.setText(Double.toString(sp.getMin()));
429 			maxBox.setText(Double.toString(sp.getMax()));
430 			colorBox.setBackground(sp.getColor());
431 			splitBox.setText(Integer.toString(sp.getSplit()));
432 			activeBox.setSelectedItem(Boolean.toString(sp.isActive()));
433 		}
434 
435 		@Override
436 		public int compareTo(final PropertyPanel pp) {
437 			return this.sp.getHeader().compareToIgnoreCase(pp.getSp().getHeader());
438 		}
439 	}
440 }