From 316e9297babfab5b4cbd121ca875a281893461ed Mon Sep 17 00:00:00 2001 From: rfuegen Date: Mon, 1 Mar 2021 00:12:13 +0100 Subject: [PATCH 1/2] Main toolbar: lat/lon seeker functionality moved to new class LatLonPanel GPXPanel: cursor handling centralised & fixed partial code cleanup --- GpsMaster/src/org/gpsmaster/GpsMaster.java | 176 ++-------- .../org/gpsmaster/dialogs/LatLonPanel.java | 300 ++++++++++++++++++ .../src/org/gpsmaster/gpxpanel/GPXPanel.java | 37 +++ 3 files changed, 372 insertions(+), 141 deletions(-) create mode 100644 GpsMaster/src/org/gpsmaster/dialogs/LatLonPanel.java diff --git a/GpsMaster/src/org/gpsmaster/GpsMaster.java b/GpsMaster/src/org/gpsmaster/GpsMaster.java index 90baf52..819fd19 100644 --- a/GpsMaster/src/org/gpsmaster/GpsMaster.java +++ b/GpsMaster/src/org/gpsmaster/GpsMaster.java @@ -1,6 +1,5 @@ package org.gpsmaster; -import java.awt.AWTEvent; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; @@ -12,16 +11,13 @@ import java.awt.HeadlessException; import java.awt.Point; import java.awt.Toolkit; -import java.awt.event.AWTEventListener; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ItemEvent; import java.awt.event.ItemListener; -import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; -import java.awt.event.InputEvent; import java.awt.event.MouseMotionAdapter; import java.awt.event.MouseWheelEvent; import java.awt.event.MouseWheelListener; @@ -44,8 +40,6 @@ import java.util.Date; import java.util.List; import java.util.Enumeration; -import java.util.regex.Pattern; -import java.util.regex.Matcher; import javax.imageio.ImageIO; import javax.swing.AbstractAction; @@ -146,6 +140,7 @@ import org.gpsmaster.dialogs.GpxPropertiesPanel; import org.gpsmaster.dialogs.ImageViewer; import org.gpsmaster.dialogs.InfoDialog; +import org.gpsmaster.dialogs.LatLonPanel; import org.gpsmaster.dialogs.NameSearchPanel; import org.gpsmaster.dialogs.TimeshiftDialog; import org.gpsmaster.dialogs.TransferStatusDialog; @@ -235,11 +230,6 @@ public class GpsMaster extends JComponent { private JToggleButton tglToolbar; private JButton btnInfo; private JComboBox comboBoxTileSource; - private JLabel lblLat; - private JTextField textFieldLat; - private JLabel lblLon; - private JTextField textFieldLon; - private JToggleButton tglLatLonFocus; private JToggleButton tglAutoFit; private JToolBar toolBarSide; private JButton btnCleaning; @@ -279,8 +269,6 @@ public class GpsMaster extends JComponent { private ChartWindow chartWindow; private Container contentPane; - private Cursor mapCursor; - private boolean mouseOverLink; private DistanceWidget distanceWidget = null; private final double mapToChartRatio = 0.85f; // distribution of space between map and chart on the mapPanel @@ -361,79 +349,6 @@ public GpsMaster() { initialize(); } - /** - * Utility to parse GPS typ-ish strings into a double - */ - private static double parseLatOrLon(String latOrLon, - String coordStr) throws NumberFormatException { - boolean debug = false; - - if (debug) System.out.println("tglLatLonFocus parseLatOrLon " + latOrLon + "=" + coordStr); - { - /* 51° 28′ 38″ N*/ - /* This parser is a little bit relaxed: - a sign ('+' or '-') - followed by digits (degree) - followed by non-digits, e.g. ' ', '°' - followed by digits (minute) - followed by non-digits, e.g. ' ', '"' - followed by digits or a dot (second) - may followed by none of 'E' 'W' 'N' 'S' - may followed by one of 'E' 'W' 'N' 'S', the direction - */ - String hoursMinSecRegex = "([-+]?\\d+)\\D+(\\d+)\\D+([0-9.]+)([^0-9a-zA-Z.]*)([EWNS]?)"; - Pattern hoursMinSecPattern = Pattern.compile(hoursMinSecRegex); - Matcher hoursMinSecMatcher = hoursMinSecPattern.matcher(coordStr); - if (hoursMinSecMatcher.find()) { - String degreeStr = hoursMinSecMatcher.group(1); - String minuteStr = hoursMinSecMatcher.group(2); - String secondStr = hoursMinSecMatcher.group(3); - String eastStr = hoursMinSecMatcher.group(5); - - if (debug) System.out.println("tglLatLonFocus parseLatOrLon (hoursMinutesSecMatcher)" + - " degreeStr=" + degreeStr + - " minuteStr=" + minuteStr + - " secondStr=" + secondStr + - " eastStr=" + eastStr); - /* Simple case: a double */ - int sign = 1; - Double degree = Double.parseDouble(degreeStr); - if (degree < 0) { - /* The sign is for all digits; not only the degrees */ - degree = 0 - degree; - sign = 0 -sign; - } - Double minute = Double.parseDouble(minuteStr); - Double second = Double.parseDouble(secondStr); - Double retDouble = degree + minute / 60 + second / 3600; - if (eastStr.equals("W") || eastStr.equals("S")) { - sign = 0 -sign; - } - retDouble = retDouble * sign; - if (debug) System.out.println("tglLatLonFocus parseLatOrLon (hoursMinutesSecMatcher)" + - " degree=" + degree + - " minute=" + minute + - " second=" + second + - " retDouble=" + retDouble); - return retDouble; - } - } - { - String hoursMinutesRegex = "^([-+]?\\d+[.]?\\d*)$"; - Pattern hoursMinutesPattern = Pattern.compile(hoursMinutesRegex); - Matcher hoursMinutesMatcher = hoursMinutesPattern.matcher(coordStr); - if (hoursMinutesMatcher.find()) { - String degreeStr = hoursMinutesMatcher.group(1); - Double retDouble = Double.parseDouble(degreeStr); - if (debug) System.out.println("tglLatLonFocus parseLatOrLon retDouble(hoursMinutesMatcher)=" - + retDouble); - return retDouble; - } - } - /* If we come here: The format is not understood - (or one of the Strings is emoty) */ - throw new NumberFormatException(coordStr); - } /** * Initialize the contents of the parentFrame. */ @@ -747,6 +662,7 @@ public void mouseClicked(MouseEvent e) { } }); + /* cursor handling moved to mapPanel mapCursor = DEFAULT_CURSOR; mapPanel.setCursor(mapCursor); mapPanel.addMouseMotionListener(new MouseAdapter() { @@ -762,7 +678,8 @@ public void mouseMoved(MouseEvent e) { } } }); - + */ + // up/+ and down/- keys will also zoom the map in and out String zoomIn = "zoom in"; mapPanel.getInputMap(JComponent.WHEN_FOCUSED).put( @@ -1208,19 +1125,11 @@ public void actionPerformed(ActionEvent e) { // goal: move as many globally defined members/variables into specific classes // as possible - - private void setupCombo() { - - - } - /** * */ private void setupMenuBar() { - // javax.swing.JCheckBoxMenuItem; - final String iconPath = Const.ICONPATH_MENUBAR; /* MAIN TOOLBAR @@ -1462,7 +1371,7 @@ public void actionPerformed(ActionEvent e) { mapPanel.addMouseListener(new MouseAdapter() { @Override public void mouseClicked(MouseEvent e) { - if (pathFinder != null && active.getGpxObject() != null && !mouseOverLink) { + if (pathFinder != null && active.getGpxObject() != null && !mapPanel.isMouseOverLink()) { findPath(e); } } @@ -1502,7 +1411,7 @@ public void itemStateChanged(ItemEvent e) { public void mouseClicked(MouseEvent e) { Waypoint wpt = null; GPXObject activeGPXObject = active.getGpxObject(); - if (active.getGpxObject() != null && !mouseOverLink) { + if (active.getGpxObject() != null && !mapPanel.isMouseOverLink()) { int zoom = mapPanel.getZoom(); int x = e.getX(); int y = e.getY(); @@ -1559,7 +1468,7 @@ public void mouseClicked(MouseEvent e) { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { deselectAllToggles(tglAddRoutepoint); - mapCursor = CROSSHAIR_CURSOR; + mapPanel.setCursor(CROSSHAIR_CURSOR); GPXObject gpxObject = active.getGpxObject(); if (gpxObject.isGPXFileWithNoRoutes()) { Route route = ((GPXFile) gpxObject).addRoute(); @@ -1568,7 +1477,7 @@ public void itemStateChanged(ItemEvent e) { updateButtonVisibility(); } } else { - mapCursor = DEFAULT_CURSOR; + mapPanel.setCursor(DEFAULT_CURSOR); } } }); @@ -1590,9 +1499,9 @@ public void itemStateChanged(ItemEvent e) { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { deselectAllToggles(tglDelPoints); - mapCursor = CROSSHAIR_CURSOR; + mapPanel.setCursor(CROSSHAIR_CURSOR); } else { - mapCursor = DEFAULT_CURSOR; + mapPanel.setCursor(DEFAULT_CURSOR); } } }); @@ -1632,7 +1541,7 @@ public void itemStateChanged(ItemEvent e) { @Override public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { - mapCursor = CROSSHAIR_CURSOR; + mapPanel.setCursor(CROSSHAIR_CURSOR); distanceWidget = new DistanceWidget(); mapPanel.add(distanceWidget); measure = new MeasureThings(distanceWidget, uc, mapPanel.getMarkerList()); @@ -1640,12 +1549,12 @@ public void itemStateChanged(ItemEvent e) { mapPanel.addPropertyChangeListener(measure.getPropertyChangeListener()); addPropertyChangeListener(measure.getPropertyChangeListener()); mapPanel.addPainter(directPainter); - // measure.setActiveGpxObject(activeGPXObject); + // } else { mapPanel.removePropertyChangeListener(measure.getPropertyChangeListener()); mapPanel.remove(distanceWidget); removePropertyChangeListener(measure.getPropertyChangeListener()); - mapCursor = DEFAULT_CURSOR; + mapPanel.setCursor(DEFAULT_CURSOR); measure.dispose(); measure = null; distanceWidget = null; @@ -1655,8 +1564,6 @@ public void itemStateChanged(ItemEvent e) { }); toolBarMain.add(tglMeasure); - // toggles.add(tglMeasure); - /* SHOW PROGRESS LABELS BUTTON * --------------------------------------------------------------------------------------------------------- */ tglProgress = new JToggleButton(""); @@ -1765,7 +1672,7 @@ public void mouseExited(MouseEvent e) { @Override public void mouseClicked(MouseEvent e) { Waypoint activeWpt = active.getTrackpoint(); - if ((activeWpt != null) && (mouseOverLink == false)) { + if ((activeWpt != null) && (mapPanel.isMouseOverLink() == false)) { GPXFile gpxFile = active.getGpxFile(); // notify listeners of the newly selected Waypoint @@ -1874,10 +1781,13 @@ public void actionPerformed(ActionEvent e) { toolBarMain.add(comboBoxTileSource); comboBoxTileSource.setMaximumSize(comboBoxTileSource.getPreferredSize()); - - /* LAT/LON INPUT/SEEKER + + /* LAT/LON INPUT/SEEKER * --------------------------------------------------------------------------------------------------------- */ toolBarMain.addSeparator(); + + /* + toolBarMain.addSeparator(); lblLat = new JLabel(" Lat "); lblLat.setFont(new Font("Tahoma", Font.PLAIN, 11)); @@ -2003,15 +1913,18 @@ public void itemStateChanged(ItemEvent e) { } } }); - + */ + Component horizontalGlue = Box.createHorizontalGlue(); horizontalGlue.setMaximumSize(new Dimension(2, 0)); horizontalGlue.setMinimumSize(new Dimension(2, 0)); horizontalGlue.setPreferredSize(new Dimension(2, 0)); toolBarMain.add(horizontalGlue); - toolBarMain.add(tglLatLonFocus); - toggles.add(tglLatLonFocus); - + + // toolBarMain.add(tglLatLonFocus); + // toggles.add(tglLatLonFocus); + toolBarMain.add(new LatLonPanel(mapPanel)); + /* AUTOFIT BUTTON * --------------------------------------------------------------------------------------------------------- */ tglAutoFit = new JToggleButton(); @@ -2050,27 +1963,6 @@ public void actionPerformed(ActionEvent e) { // EndRegion - mapPanel.addMouseListener(new MouseAdapter() { - @Override - public void mouseClicked(MouseEvent e) { - if (tglLatLonFocus.isSelected() && !mouseOverLink) { - int zoom = mapPanel.getZoom(); - int x = e.getX(); - int y = e.getY(); - Point mapCenter = mapPanel.getCenter(); - int xStart = mapCenter.x - mapPanel.getWidth() / 2; - int yStart = mapCenter.y - mapPanel.getHeight() / 2; - double lat = OsmMercator.MERCATOR_256.yToLat(yStart + y, zoom); - double lon = OsmMercator.MERCATOR_256.xToLon(xStart + x, zoom); - textFieldLat.setText(String.format("%.6f", lat).replace(',','.')); - textFieldLon.setText(String.format("%.6f", lon).replace(',','.')); - mapPanel.setShowCrosshair(true); - mapPanel.setCrosshairLat(lat); - mapPanel.setCrosshairLon(lon); - mapPanel.repaint(); - } - } - }); /* * save config on exit @@ -2145,9 +2037,9 @@ private void setupToolbar() { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { deselectAllToggles(tglSplitTrackseg); - mapCursor = CROSSHAIR_CURSOR; + mapPanel.setCursor(CROSSHAIR_CURSOR); } else { - mapCursor = DEFAULT_CURSOR; + mapPanel.setCursor(DEFAULT_CURSOR); } } }); @@ -2170,9 +2062,9 @@ public void itemStateChanged(ItemEvent e) { public void itemStateChanged(ItemEvent e) { if (e.getStateChange() == ItemEvent.SELECTED) { deselectAllToggles(tglAddWaypoint); - mapCursor = CROSSHAIR_CURSOR; + mapPanel.setCursor(CROSSHAIR_CURSOR); } else { - mapCursor = DEFAULT_CURSOR; + mapPanel.setCursor(DEFAULT_CURSOR); } } }); @@ -2197,6 +2089,7 @@ public void actionPerformed(ActionEvent e) { }); toolBarSide.add(btnCorrectEle); + /* CLEAN NARROW WAYPOINTS * --------------------------------------------------------------------------------------------------------- */ btnCleaning = new JButton(""); @@ -3002,7 +2895,7 @@ private void pathFinderOn() { searchPanel.setRoutepointEnabled(true); mapPanel.add(pathFinderWidget); - mapCursor = CROSSHAIR_CURSOR; // does not work + mapPanel.setCursor(CROSSHAIR_CURSOR); routeInfoPanel = msg.infoOn("Click on map to add points along the planned route"); } @@ -3012,7 +2905,7 @@ private void pathFinderOn() { private void pathFinderOff() { msg.infoOff(routeInfoPanel); - mapCursor = DEFAULT_CURSOR; + mapPanel.setCursor(DEFAULT_CURSOR); searchPanel.setRoutepointEnabled(false); if (pathFinderWidget != null) { mapPanel.remove(pathFinderWidget); @@ -3099,7 +2992,8 @@ protected Void doInBackground() throws Exception { /** * Displays the edit properties dialog and saves the user-selected values to the active {@link GPXObject}. - * TODO rewrite + * TODO allow in-place editing in properties panel + * */ private void editProperties() { GPXObject activeGPXObject = active.getGpxObject(); diff --git a/GpsMaster/src/org/gpsmaster/dialogs/LatLonPanel.java b/GpsMaster/src/org/gpsmaster/dialogs/LatLonPanel.java new file mode 100644 index 0000000..2960ee8 --- /dev/null +++ b/GpsMaster/src/org/gpsmaster/dialogs/LatLonPanel.java @@ -0,0 +1,300 @@ +package org.gpsmaster.dialogs; + +import java.awt.AWTEvent; +import java.awt.Cursor; +import java.awt.Dimension; +import java.awt.Font; +import java.awt.Point; +import java.awt.Toolkit; +import java.awt.event.AWTEventListener; +import java.awt.event.ItemEvent; +import java.awt.event.ItemListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.awt.event.MouseAdapter; +import java.awt.event.MouseEvent; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +import javax.swing.ImageIcon; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.JToggleButton; + +import org.gpsmaster.Const; +import org.gpsmaster.GpsMaster; +import org.gpsmaster.gpxpanel.GPXPanel; +import org.openstreetmap.gui.jmapviewer.Coordinate; +import org.openstreetmap.gui.jmapviewer.OsmMercator; + +/** + * panel encapsulating lat/lon input seeker located in main toolbar + * + * @author rfu + * @author tboegi + * + */ +@SuppressWarnings("serial") +public class LatLonPanel extends JPanel { + + private GPXPanel mapPanel = null; + + private JTextField textFieldLat = null; + private JTextField textFieldLon = null; + + private JToggleButton tglLatLonFocus = null; + + private final boolean debug = true; + + + + /** + * Constructor + * + * @param mapViewer + */ + public LatLonPanel(GPXPanel gpxPanel) { + + mapPanel = gpxPanel; + + setupSeeker(); + setupToggle(); + } + + /** + * + */ + private void setupSeeker() { + JLabel lblLat = new JLabel(" Lat "); + lblLat.setFont(new Font("Tahoma", Font.PLAIN, 11)); + add(lblLat); + + textFieldLat = new JTextField(); + textFieldLat.setPreferredSize(new Dimension(80, 24)); + textFieldLat.setMinimumSize(new Dimension(25, 24)); + textFieldLat.setMaximumSize(new Dimension(80, 24)); + textFieldLat.setColumns(9); + textFieldLat.setFocusable(false); + textFieldLat.setFocusTraversalKeysEnabled(false); + textFieldLat.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_TAB) { + textFieldLat.setFocusable(false); + textFieldLon.setFocusable(true); + textFieldLon.requestFocusInWindow(); + } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { + tglLatLonFocus.setSelected(false); + tglLatLonFocus.setSelected(true); + } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + tglLatLonFocus.setSelected(false); + } + } + @Override + public void keyReleased(KeyEvent e) { + if (tglLatLonFocus.isSelected()) { + tglLatLonFocus.setSelected(false); + tglLatLonFocus.setSelected(true); + } + } + }); + add(textFieldLat); + + JLabel lblLon = new JLabel(" Lon "); + lblLon.setFont(new Font("Tahoma", Font.PLAIN, 11)); + add(lblLon); + + textFieldLon = new JTextField(); + textFieldLon.setPreferredSize(new Dimension(80, 24)); + textFieldLon.setMinimumSize(new Dimension(25, 24)); + textFieldLon.setMaximumSize(new Dimension(80, 24)); + textFieldLon.setColumns(9); + textFieldLon.setFocusable(false); + textFieldLon.setFocusTraversalKeysEnabled(false); + textFieldLon.addKeyListener(new KeyAdapter() { + @Override + public void keyPressed(KeyEvent e) { + if (e.getKeyCode() == KeyEvent.VK_TAB) { + textFieldLat.setFocusable(true); + textFieldLon.setFocusable(false); + textFieldLat.requestFocusInWindow(); + } else if (e.getKeyCode() == KeyEvent.VK_ENTER) { + tglLatLonFocus.setSelected(false); + tglLatLonFocus.setSelected(true); + } else if (e.getKeyCode() == KeyEvent.VK_ESCAPE) { + tglLatLonFocus.setSelected(false); + } + } + @Override + public void keyReleased(KeyEvent e) { + if (tglLatLonFocus.isSelected()) { + tglLatLonFocus.setSelected(false); + tglLatLonFocus.setSelected(true); + } + } + }); + add(textFieldLon); + + long eventMask = AWTEvent.MOUSE_EVENT_MASK; + Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() { + public void eventDispatched(AWTEvent e) { + if (e.getID() == MouseEvent.MOUSE_PRESSED) { + if (e.getSource() == (Object) textFieldLat) { + textFieldLat.setFocusable(true); + } else { + textFieldLat.setFocusable(false); + } + if (e.getSource() == (Object) textFieldLon) { + textFieldLon.setFocusable(true); + } else { + textFieldLon.setFocusable(false); + } + } + } + }, eventMask); + + + } + + private void setupToggle() { + + tglLatLonFocus = new JToggleButton(""); + tglLatLonFocus.setToolTipText("Focus on latitude/longitude"); + + ImageIcon icon = new ImageIcon(GpsMaster.class.getResource(Const.ICONPATH_MENUBAR + "crosshair.png")); + + tglLatLonFocus.setIcon(icon); + tglLatLonFocus.setFocusable(false); + tglLatLonFocus.addItemListener(new ItemListener() { + @Override + public void itemStateChanged(ItemEvent e) { + if (e.getStateChange() == ItemEvent.SELECTED) { + // deselectAllToggles(tglLatLonFocus); // TODO re-enable + mapPanel.setCursor(Cursor.CROSSHAIR_CURSOR); + String latString = textFieldLat.getText(); + String lonString = textFieldLon.getText(); + try { + double latDouble = parseCoordinate("lat", latString); + double lonDouble = parseCoordinate("lon", lonString); + mapPanel.setShowCrosshair(true); + mapPanel.setCrosshairLat(latDouble); + mapPanel.setCrosshairLon(lonDouble); + Point p = new Point(mapPanel.getWidth() / 2, mapPanel.getHeight() / 2); + mapPanel.setDisplayPosition(p, new Coordinate(latDouble, lonDouble), mapPanel.getZoom()); + } catch (Exception ex) { + // TODO show as warning in MsgCenter + if (debug) { + System.err.println("Failed latStringe=" + latString + + " lonString=" + lonString + + " : " + ex.getMessage()); + } + } + mapPanel.repaint(); + } else if (e.getStateChange() == ItemEvent.DESELECTED) { + mapPanel.setCursor(Cursor.DEFAULT_CURSOR); + mapPanel.setShowCrosshair(false); + mapPanel.repaint(); + } + } + }); + add(tglLatLonFocus); + + mapPanel.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + if (tglLatLonFocus.isSelected() && !mapPanel.isMouseOverLink()) { + int zoom = mapPanel.getZoom(); + int x = e.getX(); + int y = e.getY(); + Point mapCenter = mapPanel.getCenter(); + int xStart = mapCenter.x - mapPanel.getWidth() / 2; + int yStart = mapCenter.y - mapPanel.getHeight() / 2; + double lat = OsmMercator.MERCATOR_256.yToLat(yStart + y, zoom); + double lon = OsmMercator.MERCATOR_256.xToLon(xStart + x, zoom); + textFieldLat.setText(String.format("%.6f", lat).replace(',','.')); + textFieldLon.setText(String.format("%.6f", lon).replace(',','.')); + mapPanel.setShowCrosshair(true); + mapPanel.setCrosshairLat(lat); + mapPanel.setCrosshairLon(lon); + mapPanel.repaint(); + } + } + }); + + } + + /** + * Utility to parse GPS typ-ish strings into a double + */ + private double parseCoordinate(String latOrLon, + String coordStr) throws NumberFormatException { + boolean debug = false; + + if (debug) System.out.println("tglLatLonFocus parseLatOrLon " + latOrLon + "=" + coordStr); + + /* 51° 28′ 38″ N*/ + /* This parser is a little bit relaxed: + a sign ('+' or '-') + followed by digits (degree) + followed by non-digits, e.g. ' ', '°' + followed by digits (minute) + followed by non-digits, e.g. ' ', '"' + followed by digits or a dot (second) + may followed by none of 'E' 'W' 'N' 'S' + may followed by one of 'E' 'W' 'N' 'S', the direction + */ + String hoursMinSecRegex = "([-+]?\\d+)\\D+(\\d+)\\D+([0-9.]+)([^0-9a-zA-Z.]*)([EWNS]?)"; + Pattern hoursMinSecPattern = Pattern.compile(hoursMinSecRegex); + Matcher hoursMinSecMatcher = hoursMinSecPattern.matcher(coordStr); + if (hoursMinSecMatcher.find()) { + String degreeStr = hoursMinSecMatcher.group(1); + String minuteStr = hoursMinSecMatcher.group(2); + String secondStr = hoursMinSecMatcher.group(3); + String eastStr = hoursMinSecMatcher.group(5); + + if (debug) System.out.println("tglLatLonFocus parseLatOrLon (hoursMinutesSecMatcher)" + + " degreeStr=" + degreeStr + + " minuteStr=" + minuteStr + + " secondStr=" + secondStr + + " eastStr=" + eastStr); + /* Simple case: a double */ + int sign = 1; + Double degree = Double.parseDouble(degreeStr); + if (degree < 0) { + /* The sign is for all digits; not only the degrees */ + degree = 0 - degree; + sign = 0 -sign; + } + Double minute = Double.parseDouble(minuteStr); + Double second = Double.parseDouble(secondStr); + Double retDouble = degree + minute / 60 + second / 3600; + if (eastStr.equals("W") || eastStr.equals("S")) { + sign = 0 -sign; + } + retDouble = retDouble * sign; + if (debug) System.out.println("tglLatLonFocus parseLatOrLon (hoursMinutesSecMatcher)" + + " degree=" + degree + + " minute=" + minute + + " second=" + second + + " retDouble=" + retDouble); + return retDouble; + } + + String hoursMinutesRegex = "^([-+]?\\d+[.]?\\d*)$"; + Pattern hoursMinutesPattern = Pattern.compile(hoursMinutesRegex); + Matcher hoursMinutesMatcher = hoursMinutesPattern.matcher(coordStr); + if (hoursMinutesMatcher.find()) { + String degreeStr = hoursMinutesMatcher.group(1); + Double retDouble = Double.parseDouble(degreeStr); + if (debug) System.out.println("tglLatLonFocus parseLatOrLon retDouble(hoursMinutesMatcher)=" + + retDouble); + return retDouble; + + } + /* If we end up here: The format is not understood + (or one of the Strings is empty) */ + throw new NumberFormatException(coordStr); + } + +} diff --git a/GpsMaster/src/org/gpsmaster/gpxpanel/GPXPanel.java b/GpsMaster/src/org/gpsmaster/gpxpanel/GPXPanel.java index 79b5a61..e98aecf 100644 --- a/GpsMaster/src/org/gpsmaster/gpxpanel/GPXPanel.java +++ b/GpsMaster/src/org/gpsmaster/gpxpanel/GPXPanel.java @@ -3,6 +3,7 @@ import java.awt.AlphaComposite; import java.awt.Color; +import java.awt.Cursor; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.Image; @@ -54,6 +55,8 @@ public class GPXPanel extends JMapViewer { private boolean showCrosshair = false; private boolean autoCenter = true; // TODO getter/setter + private boolean mouseOverLink = false; + private Point shownPoint; private Color activeColor = Color.WHITE; // TODO quick fix, better fix activeWpt&Grp handling @@ -62,6 +65,9 @@ public class GPXPanel extends JMapViewer { private List painterList; private PaintCoordinator coordinator = new PaintCoordinator(); + private Cursor activeCursor = null; + private final Cursor handCursor = new Cursor(Cursor.HAND_CURSOR); + /** * Constructs a new {@link GPXPanel} instance. */ @@ -97,8 +103,34 @@ public void propertyChange(PropertyChangeEvent evt) { } }; GpsMaster.active.addPropertyChangeListener(changeListener); + + // + addMouseMotionListener(new MouseAdapter() { + @Override + public void mouseMoved(MouseEvent e) { + boolean cursorHand = getAttribution().handleAttributionCursor(e.getPoint()); + if (cursorHand) { + setCursor(handCursor); + mouseOverLink = true; + } else { + setCursor(activeCursor); + mouseOverLink = false; + } + } + }); + } + /** + * + * @param cursorType + */ + public void setCursor(int cursorType) { + System.out.println("set cursor " + cursorType); + activeCursor = new Cursor(cursorType); + setCursor(activeCursor); + } + /** * * @param gpxFiles @@ -180,6 +212,11 @@ private void setShownWaypoint(Waypoint wpt, boolean center) { // --- REDESIGN end --- + public boolean isMouseOverLink() { + + return (mouseOverLink); + } + public Color getActiveColor() { return activeColor; } From 9c8f2aa581c50b6e5b38cc850433e94a274dfa4a Mon Sep 17 00:00:00 2001 From: rfuegen Date: Thu, 15 Apr 2021 23:50:53 +0200 Subject: [PATCH 2/2] arguments passed on the commandline are treated as filenames and loaded on startup. --- GpsMaster/src/org/gpsmaster/GpsMaster.java | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/GpsMaster/src/org/gpsmaster/GpsMaster.java b/GpsMaster/src/org/gpsmaster/GpsMaster.java index 819fd19..22b4138 100644 --- a/GpsMaster/src/org/gpsmaster/GpsMaster.java +++ b/GpsMaster/src/org/gpsmaster/GpsMaster.java @@ -148,6 +148,7 @@ import org.gpsmaster.elevation.ElevationProvider; import org.gpsmaster.elevation.MapQuestProvider; import org.gpsmaster.filehub.FileHub; +import org.gpsmaster.filehub.FileItem; import org.gpsmaster.filehub.FileSource; import org.gpsmaster.filehub.FileTarget; import org.gpsmaster.filehub.IItemTarget; @@ -322,7 +323,7 @@ public class GpsMaster extends JComponent { /** * Launch the application. */ - public static void main(String[] args) { + public static void main(final String[] args) { try { lookAndFeel = UIManager.getSystemLookAndFeelClassName(); UIManager.setLookAndFeel(lookAndFeel); @@ -335,6 +336,7 @@ public void run() { GpsMaster window = new GpsMaster(); window.frame.setVisible(true); window.frame.requestFocusInWindow(); + window.handleArgs(args); } catch (Exception e) { e.printStackTrace(); } @@ -3605,6 +3607,19 @@ public void propertyChange(PropertyChangeEvent evt) { } + /** + * load files passed as arguments on commandline + * @param args + */ + public void handleArgs(String[] args) { + + for (String filename : args) { + centralFileHub.addItem(new FileItem(new File(filename))); + } + centralFileHub.run(); + + } + /** * retrieve GPS data from a connected device. */