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.graphing;
24  
25  import java.awt.Color;
26  import java.awt.Dimension;
27  import java.awt.Font;
28  import java.awt.FontMetrics;
29  import java.awt.Graphics;
30  import java.awt.Graphics2D;
31  import java.awt.event.MouseEvent;
32  import java.awt.event.MouseListener;
33  import java.awt.event.MouseMotionListener;
34  import java.util.ResourceBundle;
35  
36  import javax.swing.JPanel;
37  
38  import org.diyefi.openlogviewer.OpenLogViewer;
39  import org.diyefi.openlogviewer.Text;
40  import org.diyefi.openlogviewer.genericlog.GenericLog;
41  import org.diyefi.openlogviewer.utils.MathUtils;
42  
43  public class InfoPanel extends JPanel implements MouseMotionListener, MouseListener {
44  	private static final long serialVersionUID = 1L;
45  
46  	private static final int LEFT_MARGIN_OFFSET = 10;
47  	private static final int ONE_TEXTUAL_HEIGHT = 20;
48  	private static final int FONT_SIZE = 12;
49  	private static final int INFO_DISPLAY_OFFSET = 4;
50  	private static final Font HOVER_FONT = new Font(Font.MONOSPACED, Font.PLAIN, FONT_SIZE);
51  
52  	private final ResourceBundle labels;
53  	private final Color vertBar = new Color(255, 255, 255, 100);
54  	private final Color textBackground = new Color(0, 0, 0, 170);
55  
56  	private GenericLog genLog;
57  	private int xMouseCoord;
58  	private int yMouseCoord;
59  	private boolean shouldDraw;
60  
61  	public InfoPanel(final ResourceBundle labels) {
62  		this.labels = labels;
63  		setOpaque(false);
64  	}
65  
66  	@Override
67  	public final void paintComponent(final Graphics g) {
68  		super.paintComponent(g);
69  
70  		if (!this.getSize().equals(this.getParent().getSize())) {
71  			this.setSize(this.getParent().getSize());
72  		}
73  
74  		g.setFont(HOVER_FONT); // Required to keep font consistent when using Mac L&F
75  		if (genLog == null) {
76  			g.setColor(Color.RED);
77  			g.drawString(labels.getString(Text.NO_LOG_LOADED), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
78  		} else {
79  			if (genLog.getLogStatus() == GenericLog.LogState.LOG_LOADING) {
80  				g.setColor(Color.red);
81  				g.drawString(labels.getString(Text.LOADING_LOG), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
82  			} else if (genLog.getLogStatus() == GenericLog.LogState.LOG_LOADED) {
83  				if (genLog.getLogStatusMessage() != null) {
84  					g.setColor(Color.RED);
85  					g.drawString(labels.getString(Text.DECODER_CRASHED_PART1), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT);
86  					g.drawString(genLog.getLogStatusMessage(), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT * 2);
87  					g.drawString(labels.getString(Text.DECODER_CRASHED_PART2), LEFT_MARGIN_OFFSET, ONE_TEXTUAL_HEIGHT * 3);
88  				}
89  				if (shouldDraw) {
90  					final int dataWidth = getWidestDataWidth();
91  					final Dimension d = this.getSize();
92  					final Graphics2D g2d = (Graphics2D) g;
93  					final FontMetrics fm = g.getFontMetrics(g.getFont());  // For getting string width
94  					final int fontHeight = fm.getHeight();
95  					final GraphPositionPanel graphPositionPanel = OpenLogViewer.getInstance().getEntireGraphingPanel().getGraphPositionPanel();
96  					final int zoom = OpenLogViewer.getInstance().getEntireGraphingPanel().getZoom();
97  					final boolean zoomedOut = OpenLogViewer.getInstance().getEntireGraphingPanel().isZoomedOutBeyondOneToOne();
98  					int snappedDataPosition = xMouseCoord;
99  					if (!zoomedOut && zoom > 1) {
100 						snappedDataPosition = graphPositionPanel.getBestSnappingPosition(xMouseCoord);
101 					}
102 					g2d.setColor(vertBar);
103 					g2d.drawLine(d.width / 2, 0, d.width / 2, d.height);  // center position line
104 					g2d.drawLine(snappedDataPosition, 0, snappedDataPosition, d.height);  // mouse cursor line
105 
106 					final MultiGraphLayeredPane multigGraph = OpenLogViewer.getInstance().getMultiGraphLayeredPane();
107 					for (int i = 0; i < multigGraph.getComponentCount(); i++) {
108 						if (multigGraph.getComponent(i) instanceof SingleGraphPanel) {
109 							final SingleGraphPanel singleGraph = (SingleGraphPanel) multigGraph.getComponent(i);
110 							g2d.setColor(textBackground);
111 							String mouseData = singleGraph.getMouseInfo(snappedDataPosition, dataWidth);
112 							mouseData = mouseData + "  " + singleGraph.getData().getName();
113 							final int stringWidth = fm.stringWidth(mouseData);
114 							g2d.fillRect(snappedDataPosition - 2 + INFO_DISPLAY_OFFSET,
115 									yMouseCoord + 2 + (fontHeight * i),
116 									stringWidth + 4,
117 									fontHeight);
118 							g2d.setColor(singleGraph.getColor());
119 							g2d.drawString(mouseData,
120 									snappedDataPosition + INFO_DISPLAY_OFFSET,
121 									yMouseCoord + fontHeight + (fontHeight * i));
122 						}
123 					}
124 				}
125 			}
126 		}
127 	}
128 
129 	public final void setLog(final GenericLog log) {
130 		genLog = log;
131 		this.repaint();
132 	}
133 
134 	private int getWidestDataWidth() {
135 		String widestDataToDisplay = "";
136 		final MultiGraphLayeredPane multigGraph = OpenLogViewer.getInstance().getMultiGraphLayeredPane();
137 		for (int i = 0; i < multigGraph.getComponentCount(); i++) {
138 			if (multigGraph.getComponent(i) instanceof SingleGraphPanel) {
139 				final SingleGraphPanel singleGraph = (SingleGraphPanel) multigGraph.getComponent(i);
140 				final String minValue = MathUtils.roundDecimalPlaces(singleGraph.getData().getMinValue(), SingleGraphPanel.DECIMAL_PLACES);
141 				final String maxValue = MathUtils.roundDecimalPlaces(singleGraph.getData().getMaxValue(), SingleGraphPanel.DECIMAL_PLACES);
142 				if (minValue.length() > widestDataToDisplay.length()) {
143 					widestDataToDisplay = minValue;
144 				}
145 				if (maxValue.length() > widestDataToDisplay.length()) {
146 					widestDataToDisplay = maxValue;
147 				}
148 			}
149 		}
150 		return widestDataToDisplay.length();
151 	}
152 
153 	@Override
154 	public final void mouseEntered(final MouseEvent e) {
155 		shouldDraw = true;
156 	}
157 
158 	@Override
159 	public final void mouseExited(final MouseEvent e) {
160 		if (!e.isShiftDown()) {
161 			// Old default behaviour
162 			shouldDraw = false;
163 			repaint();
164 		} // else leave coordinates alone
165 	}
166 
167 	@Override
168 	public final void mouseMoved(final MouseEvent e) {
169 		if (!e.isShiftDown()) {
170 			xMouseCoord = e.getX();
171 			yMouseCoord = e.getY();
172 			repaint();
173 		} // else hold position
174 	}
175 
176 	@Override
177 	public void mouseClicked(final MouseEvent e) {
178 	}
179 
180 	@Override
181 	public void mousePressed(final MouseEvent e) {
182 	}
183 
184 	@Override
185 	public void mouseReleased(final MouseEvent e) {
186 	}
187 
188 	@Override
189 	public void mouseDragged(final MouseEvent e) {
190 
191 	}
192 }