/** Called in order to adjust the route start time and the UI accordingly */ private void adjustStartTime() { // Stop widget listeners boolean wasQuiescent = quiescent; quiescent = true; // Get start time or default now if (!readOnlyRoute) { route.adjustStartTime(); } Date starttime = route.getStarttime(); departurePicker.setDate(starttime); departureSpinner.setValue(starttime); // Attempt to get ETA (only possible if GPS data is available) Date etaStart = route.getEta(starttime); if (etaStart != null) { // GPS data available. arrivalPicker.setDate(etaStart); arrivalSpinner.setValue(etaStart); } else { // No GPS data available. // Find the default ETA. Date defaultEta = route.getEtas().get(route.getEtas().size() - 1); arrivalPicker.setDate(defaultEta); arrivalSpinner.setValue(defaultEta); } // Recalculate and update route fields updateFields(); // Restore the quiescent state quiescent = wasQuiescent; }
/** Called when route values changes and the fields should be refreshed */ private void updateFields() { if (!readOnlyRoute) { route.calcValues(true); route.calcAllWpEta(); } inrouteTxT.setText(Formatter.formatTime(route.getRouteTtg())); distanceTxT.setText(Formatter.formatDistNM(route.getRouteDtg())); routeTableModel.fireTableDataChanged(); }
/** * Constructor * * @param parent the parent window * @param route the route * @param readOnlyRoute whether the route is read-only or not */ public RoutePropertiesDialogCommon( Window parent, ChartPanelCommon chartPanel, Route route, boolean readOnlyRoute) { super(parent, "Route Properties", Dialog.ModalityType.APPLICATION_MODAL); this.parent = parent; this.chartPanel = chartPanel; this.route = route; this.readOnlyRoute = readOnlyRoute; locked = new boolean[route.getWaypoints().size()]; addWindowListener( new WindowAdapter() { @Override public void windowClosed(WindowEvent e) { EPD.getInstance() .getRouteManager() .validateMetoc(RoutePropertiesDialogCommon.this.route); } }); initGui(); initValues(); setBounds(100, 100, 1000, 450); setLocationRelativeTo(parent); }
/** * Called when one of the name, origin or destination text field changes value * * @param field the text field */ protected void textFieldValueChanged(JTextField field) { // Check if we are in a quiescent state if (quiescent) { return; } if (field == nameTxT) { route.setName(nameTxT.getText()); } else if (field == originTxT) { route.setDeparture(originTxT.getText()); } else if (field == destinationTxT) { route.setDestination(destinationTxT.getText()); } routeUpdated(); }
/** Updates the dialog with the value of the current route */ private void initValues() { // Should not trigger listeners quiescent = true; nameTxT.setText(route.getName()); originTxT.setText(route.getDeparture()); destinationTxT.setText(route.getDestination()); etaCalculationTime.setSelectedItem(route.getEtaCalculationType()); // Update the route start time and the start time-related fields adjustStartTime(); cbVisible.setSelected(route.isVisible()); if (route.getWaypoints().size() > 1) { allSpeeds.setText(Formatter.formatSpeed(route.getWaypoints().get(0).getOutLeg().getSpeed())); } updateButtonEnabledState(); // Done quiescent = false; }
/** Test method */ public static final void main(String... args) throws Exception { // ===================== // Create test data // ===================== final Route route = new Route(); route.setName("Test route"); final LinkedList<RouteWaypoint> waypoints = new LinkedList<>(); route.setWaypoints(waypoints); route.setStarttime(new Date()); int len = 10; final boolean[] locked = new boolean[len]; for (int x = 0; x < len; x++) { locked[x] = false; RouteWaypoint wp = new RouteWaypoint(); waypoints.add(wp); // Set leg values if (x > 0) { RouteLeg leg = new RouteLeg(); leg.setSpeed(12.00 + x); leg.setHeading(Heading.RL); leg.setXtdPort(185.0); leg.setXtdStarboard(185.0); wp.setInLeg(leg); waypoints.get(x - 1).setOutLeg(leg); leg.setStartWp(waypoints.get(x - 1)); leg.setEndWp(wp); } wp.setName("WP_00" + x); wp.setPos(Position.create(56.02505 + Math.random() * 2.0, 12.37 + Math.random() * 2.0)); } for (int x = 1; x < len; x++) { waypoints.get(x).setTurnRad(0.5 + x * 0.2); } route.calcValues(true); // Launch the route properties dialog PntTime.init(); RoutePropertiesDialogCommon dialog = new RoutePropertiesDialogCommon(null, null, route, false); dialog.setVisible(true); }
/** Called when Delete is clicked */ private void onDelete() { // Check that there is a selection if (selectedWp < 0) { return; } // If the route has two way points or less, delete the entire route if (route.getWaypoints().size() < 3) { // ... but get confirmation first int result = JOptionPane.showConfirmDialog( parent, "A route must have at least two waypoints.\nDo you want to delete the route?", "Delete Route?", JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE); if (result == JOptionPane.YES_OPTION) { EPD.getInstance() .getRouteManager() .removeRoute(EPD.getInstance().getRouteManager().getRouteIndex(route)); EPD.getInstance().getRouteManager().notifyListeners(RoutesUpdateEvent.ROUTE_REMOVED); dispose(); } } else { // Update the locked list boolean[] newLocked = new boolean[locked.length - 1]; for (int x = 0; x < newLocked.length; x++) { newLocked[x] = locked[x + (x >= selectedWp ? 1 : 0)]; } locked = newLocked; // Delete the selected way point route.deleteWaypoint(selectedWp); adjustStartTime(); routeTableModel.fireTableDataChanged(); EPD.getInstance().getRouteManager().notifyListeners(RoutesUpdateEvent.ROUTE_WAYPOINT_DELETED); } }
/** * Handle action events * * @param evt the action event */ @Override public void actionPerformed(ActionEvent evt) { // Check if we are in a quiescent state if (quiescent) { return; } if (evt.getSource() == btnZoomToRoute && chartPanel != null) { chartPanel.zoomToWaypoints(route.getWaypoints()); } else if (evt.getSource() == btnZoomToWp && chartPanel != null) { chartPanel.goToPosition(route.getWaypoints().get(selectedWp).getPos()); } else if (evt.getSource() == btnDelete) { onDelete(); routeUpdated(); } else if (evt.getSource() == btnActivate) { EPD.getInstance().getRouteManager().changeActiveWp(selectedWp); routeUpdated(); } else if (evt.getSource() == btnClose) { dispose(); } else if (evt.getSource() == cbVisible) { route.setVisible(cbVisible.isSelected()); EPD.getInstance() .getRouteManager() .notifyListeners(RoutesUpdateEvent.ROUTE_VISIBILITY_CHANGED); } else if (evt.getSource() == etaCalculationTime) { route.setEtaCalculationType((EtaCalculationType) etaCalculationTime.getSelectedItem()); adjustStartTime(); routeUpdated(); } else if (evt.getSource() == allSpeedsBtn) { double speed; try { speed = parseDouble(allSpeeds.getText()); allSpeeds.setText(Formatter.formatSpeed(speed)); } catch (FormatException e) { JOptionPane.showMessageDialog( this, "Error in speed", "Input error", JOptionPane.ERROR_MESSAGE); return; } for (int i = 0; i < route.getWaypoints().size(); i++) { RouteWaypoint wp = route.getWaypoints().get(i); if (wp.getOutLeg() != null && !locked[i]) { wp.getOutLeg().setSpeed(speed); } } adjustStartTime(); } EPD.getInstance().getRouteManager().notifyListeners(RoutesUpdateEvent.ROUTE_CHANGED); }
/** * Called when one of the arrival and departure spinners changes value * * @param spinner the spinner */ protected void spinnerValueChanged(JSpinner spinner) { // Check if we are in a quiescent state if (quiescent) { return; } if (spinner == departureSpinner) { Date date = ParseUtils.combineDateTime(departurePicker.getDate(), (Date) departureSpinner.getValue()); route.setStarttime(date); adjustStartTime(); } else if (spinner == arrivalSpinner) { Date date = ParseUtils.combineDateTime(arrivalPicker.getDate(), (Date) arrivalSpinner.getValue()); recalculateSpeeds(date); } else { return; } routeUpdated(); }
/** * Called when one of the arrival and departure pickers changes value * * @param evt the event */ @Override public void propertyChange(PropertyChangeEvent evt) { // Check if we are in a quiescent state if (quiescent) { return; } if (evt.getSource() == departurePicker) { Date date = ParseUtils.combineDateTime(departurePicker.getDate(), (Date) departureSpinner.getValue()); route.setStarttime(date); adjustStartTime(); } else if (evt.getSource() == arrivalPicker) { Date date = ParseUtils.combineDateTime(arrivalPicker.getDate(), (Date) arrivalSpinner.getValue()); recalculateSpeeds(date); } else { return; } routeUpdated(); }
@Override public void doAction() { Route route = EPD.getInstance().getRouteManager().getRoute(routeIndex); route.appendWaypoint(); EPD.getInstance().getRouteManager().notifyListeners(RoutesUpdateEvent.ROUTE_WAYPOINT_APPENDED); }
/** * Given a new arrival date, re-calculate the speed * * @param arrivalDate the new arrival date */ private void recalculateSpeeds(Date arrivalDate) { // Stop widget listeners boolean wasQuiescent = quiescent; quiescent = true; // Special case if the arrival date is before the start time if (route.getStarttime().after(arrivalDate)) { // Reset arrival to a valid time arrivalPicker.setDate(route.getEta()); arrivalSpinner.setValue(route.getEta()); quiescent = wasQuiescent; return; } // Total distance Dist distanceToTravel = new Dist(DistType.NAUTICAL_MILES, route.getRouteDtg()); // And we want to get there in milliseconds: Time timeToTravel = new Time(TimeType.MILLISECONDS, arrivalDate.getTime() - route.getStarttime().getTime()); // Subtract the distance and time from the locked way points for (int i = 0; i < route.getWaypoints().size() - 1; i++) { if (locked[i]) { distanceToTravel = distanceToTravel.subtract(new Dist(DistType.NAUTICAL_MILES, route.getWpRng(i))); timeToTravel = timeToTravel.subtract(new Time(TimeType.MILLISECONDS, route.getWpTtg(i + 1))); } } // Ensure the remaining time is actually positive (say, more than a minute) if (timeToTravel.in(TimeType.MINUTES).doubleValue() < 1.0) { // Reset arrival to a valid time arrivalPicker.setDate(route.getEta()); arrivalSpinner.setValue(route.getEta()); quiescent = wasQuiescent; return; } // So we need to travel how fast? double speed = distanceToTravel.inTime(timeToTravel).in(SpeedType.KNOTS).doubleValue(); for (int i = 0; i < route.getWaypoints().size(); i++) { if (!locked[i]) { route.getWaypoints().get(i).setSpeed(speed); } } // Update fields updateFields(); // Restore the quiescent state quiescent = wasQuiescent; }