Update graphics.
This commit is contained in:
		| @@ -53,7 +53,6 @@ import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm; | ||||
| import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsData; | ||||
| import org.insa.graph.Graph; | ||||
| import org.insa.graph.Path; | ||||
| import org.insa.graph.io.BinaryGraphReaderInsa2016; | ||||
| import org.insa.graph.io.BinaryGraphReaderInsa2018; | ||||
| import org.insa.graph.io.BinaryPathReader; | ||||
| import org.insa.graph.io.GraphReader; | ||||
| @@ -144,19 +143,17 @@ public class MainWindow extends JFrame { | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 StartActionEvent evt = (StartActionEvent) e; | ||||
|                 ShortestPathData data = new ShortestPathData(graph, evt.getOrigin(), | ||||
|                         evt.getDestination(), evt.getMode()); | ||||
|                 ShortestPathData data = new ShortestPathData(graph, evt.getOrigin(), evt.getDestination(), | ||||
|                         evt.getMode()); | ||||
|  | ||||
|                 ShortestPathAlgorithm spAlgorithm = null; | ||||
|                 try { | ||||
|                     spAlgorithm = ShortestPathAlgorithmFactory | ||||
|                             .createAlgorithm(evt.getAlgorithmClass(), data); | ||||
|                     spAlgorithm = ShortestPathAlgorithmFactory.createAlgorithm(evt.getAlgorithmClass(), data); | ||||
|                 } | ||||
|                 catch (Exception e1) { | ||||
|                     JOptionPane.showMessageDialog(MainWindow.this, | ||||
|                             "An error occurred while creating the specified algorithm.", | ||||
|                             "Internal error: Algorithm instantiation failure", | ||||
|                             JOptionPane.ERROR_MESSAGE); | ||||
|                             "Internal error: Algorithm instantiation failure", JOptionPane.ERROR_MESSAGE); | ||||
|                     e1.printStackTrace(); | ||||
|                     return; | ||||
|                 } | ||||
| @@ -341,14 +338,12 @@ public class MainWindow extends JFrame { | ||||
|         // We need to draw MapView, we have to check if the file exists. | ||||
|         File mfile = null; | ||||
|         if (isMapView) { | ||||
|             String mfpath = graphFilePath.substring(0, graphFilePath.lastIndexOf(".map")) | ||||
|                     + ".mapfg"; | ||||
|             String mfpath = graphFilePath.substring(0, graphFilePath.lastIndexOf(".map")) + ".mapfg"; | ||||
|             mfile = new File(mfpath); | ||||
|             if (!mfile.exists()) { | ||||
|                 if (JOptionPane.showConfirmDialog(this, | ||||
|                         "The associated mapsforge (.mapfg) file has not been found, do you want to specify it manually?", | ||||
|                         "File not found", | ||||
|                         JOptionPane.YES_NO_CANCEL_OPTION) == JOptionPane.YES_OPTION) { | ||||
|                         "File not found", JOptionPane.YES_NO_CANCEL_OPTION) == JOptionPane.YES_OPTION) { | ||||
|                     JFileChooser chooser = new JFileChooser(mfile.getParentFile()); | ||||
|                     if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { | ||||
|                         mfile = chooser.getSelectedFile(); | ||||
| @@ -418,16 +413,15 @@ public class MainWindow extends JFrame { | ||||
|                 reader.addObserver(progressBar); | ||||
|                 try { | ||||
|                     graph = reader.read(); | ||||
|                     System.out.flush(); | ||||
|                 } | ||||
|                 catch (Exception exception) { | ||||
|                     progressBar.setVisible(false); | ||||
|                     progressBar = null; | ||||
|                     JOptionPane.showMessageDialog(MainWindow.this, | ||||
|                             "Unable to read graph from the selected file."); | ||||
|                     JOptionPane.showMessageDialog(MainWindow.this, "Unable to read graph from the selected file."); | ||||
|                     exception.printStackTrace(System.out); | ||||
|                     return; | ||||
|                 } | ||||
|                 notifyNewGraphLoaded(); | ||||
|  | ||||
|                 String info = graph.getMapId(); | ||||
|                 if (graph.getMapName() != null && !graph.getMapName().isEmpty()) { | ||||
| @@ -435,8 +429,11 @@ public class MainWindow extends JFrame { | ||||
|                 } | ||||
|                 info += ", " + graph.getNodes().size() + " nodes"; | ||||
|                 graphInfoPanel.setText(info); | ||||
|  | ||||
|                 drawGraph(); | ||||
|  | ||||
|                 notifyNewGraphLoaded(); | ||||
|  | ||||
|                 for (JMenuItem item: graphLockItems) { | ||||
|                     item.setEnabled(true); | ||||
|                 } | ||||
| @@ -453,8 +450,7 @@ public class MainWindow extends JFrame { | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 JFileChooser chooser = new JFileChooser(); | ||||
|                 FileNameExtensionFilter filter = new FileNameExtensionFilter("Graph files", | ||||
|                         "mapgr"); | ||||
|                 FileNameExtensionFilter filter = new FileNameExtensionFilter("Graph files", "mapgr"); | ||||
|                 chooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); | ||||
|                 chooser.setFileFilter(filter); | ||||
|                 if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { | ||||
| @@ -462,12 +458,11 @@ public class MainWindow extends JFrame { | ||||
|  | ||||
|                     DataInputStream stream; | ||||
|                     try { | ||||
|                         stream = new DataInputStream(new BufferedInputStream( | ||||
|                                 new FileInputStream(chooser.getSelectedFile()))); | ||||
|                         stream = new DataInputStream( | ||||
|                                 new BufferedInputStream(new FileInputStream(chooser.getSelectedFile()))); | ||||
|                     } | ||||
|                     catch (IOException e1) { | ||||
|                         JOptionPane.showMessageDialog(MainWindow.this, | ||||
|                                 "Cannot open the selected file."); | ||||
|                         JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file."); | ||||
|                         return; | ||||
|                     } | ||||
|                     loadGraph(new BinaryGraphReaderInsa2018(stream)); | ||||
| @@ -475,33 +470,6 @@ public class MainWindow extends JFrame { | ||||
|             } | ||||
|         })); | ||||
|  | ||||
|         JMenuItem openOldMapItem = new JMenuItem("Open Map (Old version)... "); | ||||
|         openOldMapItem.addActionListener(baf.createBlockingAction(new ActionListener() { | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 JFileChooser chooser = new JFileChooser(); | ||||
|                 FileNameExtensionFilter filter = new FileNameExtensionFilter( | ||||
|                         "Map & compressed map files", "map"); | ||||
|                 chooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); | ||||
|                 chooser.setFileFilter(filter); | ||||
|                 if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { | ||||
|                     graphFilePath = chooser.getSelectedFile().getAbsolutePath(); | ||||
|  | ||||
|                     DataInputStream stream; | ||||
|                     try { | ||||
|                         stream = new DataInputStream(new BufferedInputStream( | ||||
|                                 new FileInputStream(chooser.getSelectedFile()))); | ||||
|                     } | ||||
|                     catch (IOException e1) { | ||||
|                         JOptionPane.showMessageDialog(MainWindow.this, | ||||
|                                 "Cannot open the selected file."); | ||||
|                         return; | ||||
|                     } | ||||
|                     loadGraph(new BinaryGraphReaderInsa2016(stream)); | ||||
|                 } | ||||
|             } | ||||
|         })); | ||||
|  | ||||
|         // Open Path item... | ||||
|         JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P); | ||||
|         openPathItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.ALT_MASK)); | ||||
| @@ -510,19 +478,18 @@ public class MainWindow extends JFrame { | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 JFileChooser chooser = new JFileChooser(); | ||||
|                 FileNameExtensionFilter filter = new FileNameExtensionFilter( | ||||
|                         "Path & compressed path files", "path", "path.gz"); | ||||
|                 FileNameExtensionFilter filter = new FileNameExtensionFilter("Path & compressed path files", "path", | ||||
|                         "path.gz"); | ||||
|                 chooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); | ||||
|                 chooser.setFileFilter(filter); | ||||
|                 if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { | ||||
|                     BinaryPathReader reader; | ||||
|                     try { | ||||
|                         reader = new BinaryPathReader(new DataInputStream(new BufferedInputStream( | ||||
|                                 new FileInputStream(chooser.getSelectedFile())))); | ||||
|                         reader = new BinaryPathReader(new DataInputStream( | ||||
|                                 new BufferedInputStream(new FileInputStream(chooser.getSelectedFile())))); | ||||
|                     } | ||||
|                     catch (IOException e1) { | ||||
|                         JOptionPane.showMessageDialog(MainWindow.this, | ||||
|                                 "Cannot open the selected file."); | ||||
|                         JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file."); | ||||
|                         return; | ||||
|                     } | ||||
|                     try { | ||||
| @@ -535,8 +502,7 @@ public class MainWindow extends JFrame { | ||||
|                         return; | ||||
|                     } | ||||
|                     catch (Exception exception) { | ||||
|                         JOptionPane.showMessageDialog(MainWindow.this, | ||||
|                                 "Unable to read path from the selected file."); | ||||
|                         JOptionPane.showMessageDialog(MainWindow.this, "Unable to read path from the selected file."); | ||||
|                         return; | ||||
|                     } | ||||
|                 } | ||||
| @@ -550,15 +516,13 @@ public class MainWindow extends JFrame { | ||||
|         closeItem.addActionListener(new ActionListener() { | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 MainWindow.this.dispatchEvent( | ||||
|                         new WindowEvent(MainWindow.this, WindowEvent.WINDOW_CLOSING)); | ||||
|                 MainWindow.this.dispatchEvent(new WindowEvent(MainWindow.this, WindowEvent.WINDOW_CLOSING)); | ||||
|             } | ||||
|         }); | ||||
|  | ||||
|         // Build the first menu. | ||||
|         JMenu fileMenu = new JMenu("File"); | ||||
|         fileMenu.add(openMapItem); | ||||
|         fileMenu.add(openOldMapItem); // TODO: Remove this for Students. | ||||
|         fileMenu.add(openPathItem); | ||||
|         fileMenu.addSeparator(); | ||||
|         fileMenu.add(closeItem); | ||||
| @@ -593,8 +557,7 @@ public class MainWindow extends JFrame { | ||||
|         })); | ||||
|         graphLockItems.add(drawGraphBWItem); | ||||
|         JMenuItem drawGraphMapsforgeItem = new JMenuItem("Redraw (Map)", KeyEvent.VK_M); | ||||
|         drawGraphMapsforgeItem | ||||
|                 .setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.ALT_MASK)); | ||||
|         drawGraphMapsforgeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.ALT_MASK)); | ||||
|         drawGraphMapsforgeItem.addActionListener(baf.createBlockingAction(new ActionListener() { | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
| @@ -669,9 +632,8 @@ public class MainWindow extends JFrame { | ||||
|     private JPanel createStatusBar() { | ||||
|         // create the status bar panel and shove it down the bottom of the frame | ||||
|         JPanel statusPanel = new JPanel(); | ||||
|         statusPanel.setBorder( | ||||
|                 new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY), | ||||
|                         new EmptyBorder(0, 15, 0, 15))); | ||||
|         statusPanel.setBorder(new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY), | ||||
|                 new EmptyBorder(0, 15, 0, 15))); | ||||
|         statusPanel.setPreferredSize(new Dimension(getWidth(), 38)); | ||||
|         statusPanel.setLayout(new BorderLayout()); | ||||
|  | ||||
| @@ -688,8 +650,8 @@ public class MainWindow extends JFrame { | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 if (currentThread.isRunning()) { | ||||
|                     int confirmed = JOptionPane.showConfirmDialog(MainWindow.this, | ||||
|                             "Are you sure you want to kill the running thread?", | ||||
|                             "Kill Confirmation", JOptionPane.YES_NO_OPTION); | ||||
|                             "Are you sure you want to kill the running thread?", "Kill Confirmation", | ||||
|                             JOptionPane.YES_NO_OPTION); | ||||
|                     if (confirmed == JOptionPane.YES_OPTION) { | ||||
|                         currentThread.interrupt(); | ||||
|                     } | ||||
| @@ -701,8 +663,8 @@ public class MainWindow extends JFrame { | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 long seconds = currentThread.getDuration().getSeconds(); | ||||
|                 threadTimerLabel.setText(String.format("%02d:%02d:%02d", seconds / 3600, | ||||
|                         seconds / 60 % 60, seconds % 60)); | ||||
|                 threadTimerLabel | ||||
|                         .setText(String.format("%02d:%02d:%02d", seconds / 3600, seconds / 60 % 60, seconds % 60)); | ||||
|             } | ||||
|         }); | ||||
|         threadTimer.setInitialDelay(0); | ||||
|   | ||||
| @@ -34,10 +34,54 @@ public class NodesInputPanel extends JPanel | ||||
|     /** | ||||
|      *  | ||||
|      */ | ||||
|     private static final long serialVersionUID = -1638302070013027690L; | ||||
|     private static final long serialVersionUID = 1L; | ||||
|  | ||||
|     private static final Color DEFAULT_MARKER_COLOR = Color.BLUE; | ||||
|  | ||||
|     /** | ||||
|      * Utility class that can be used to find a node from coordinates in a "fast" | ||||
|      * way. | ||||
|      * | ||||
|      */ | ||||
|     private static class NodeFinder { | ||||
|  | ||||
|         // Graph associated with this node finder. | ||||
|         private Graph graph; | ||||
|  | ||||
|         /** | ||||
|          * @param graph | ||||
|          */ | ||||
|         public NodeFinder(Graph graph) { | ||||
|             this.graph = graph; | ||||
|         } | ||||
|  | ||||
|         /** | ||||
|          * @param point | ||||
|          *  | ||||
|          * @return the closest node to the given point, or null if no node is "close | ||||
|          *         enough". | ||||
|          */ | ||||
|         public Node findClosestNode(Point point) { | ||||
|             Node minNode = null; | ||||
|             double minDis = Double.POSITIVE_INFINITY; | ||||
|             for (Node node: graph.getNodes()) { | ||||
|                 double dlon = point.getLongitude() - node.getPoint().getLongitude(); | ||||
|                 double dlat = point.getLatitude() - node.getPoint().getLatitude(); | ||||
|                 double dis = dlon * dlon + dlat * dlat; // No need to square | ||||
|                 if (dis < minDis) { | ||||
|                     minNode = node; | ||||
|                     minDis = dis; | ||||
|                 } | ||||
|             } | ||||
|             return minNode; | ||||
|         } | ||||
|  | ||||
|     } | ||||
|  | ||||
|     /** | ||||
|      * Event data send when a node input has changed. | ||||
|      * | ||||
|      */ | ||||
|     public class InputChangedEvent extends ActionEvent { | ||||
|  | ||||
|         /** | ||||
| @@ -77,6 +121,7 @@ public class NodesInputPanel extends JPanel | ||||
|     // Drawing and graph | ||||
|     private Drawing drawing; | ||||
|     private Graph graph; | ||||
|     private NodeFinder nodeFinder; | ||||
|  | ||||
|     /** | ||||
|      * @param drawing Original drawing used (see {@link:newDrawingLoaded}). | ||||
| @@ -316,7 +361,7 @@ public class NodesInputPanel extends JPanel | ||||
|     public void mouseClicked(Point point) { | ||||
|         JTextField input = getInputToFill(); | ||||
|         if (input != null) { | ||||
|             Node node = graph.findClosestNode(point); | ||||
|             Node node = nodeFinder.findClosestNode(point); | ||||
|             input.setText(String.valueOf(node.getId())); | ||||
|             nextInputToFill(); | ||||
|         } | ||||
| @@ -328,6 +373,8 @@ public class NodesInputPanel extends JPanel | ||||
|             this.clear(); | ||||
|             this.graph = graph; | ||||
|  | ||||
|             nodeFinder = new NodeFinder(graph); | ||||
|  | ||||
|             // Disable if previously disabled... | ||||
|             setEnabled(this.isEnabled()); | ||||
|         } | ||||
|   | ||||
| @@ -32,8 +32,7 @@ import org.insa.graph.io.BinaryPathWriter; | ||||
| import org.insa.graphics.drawing.Drawing; | ||||
| import org.insa.graphics.drawing.overlays.PathOverlay; | ||||
|  | ||||
| public class ShortestPathSolutionPanel extends JPanel | ||||
|         implements DrawingChangeListener, GraphChangeListener { | ||||
| public class ShortestPathSolutionPanel extends JPanel implements DrawingChangeListener, GraphChangeListener { | ||||
|  | ||||
|     /** | ||||
|      *  | ||||
| @@ -98,12 +97,13 @@ public class ShortestPathSolutionPanel extends JPanel | ||||
|  | ||||
|         /* | ||||
|          * (non-Javadoc) | ||||
|          *  | ||||
|          * @see java.lang.Object#toString() | ||||
|          */ | ||||
|         public String toString() { | ||||
|             return "Shortest-path from #" + this.getData().getOrigin().getId() + " to #" | ||||
|                     + this.getData().getDestination().getId() + " [" | ||||
|                     + this.getData().getMode().toString().toLowerCase() + "]"; | ||||
|                     + this.getData().getDestination().getId() + " [" + this.getData().getMode().toString().toLowerCase() | ||||
|                     + "]"; | ||||
|         } | ||||
|     } | ||||
|  | ||||
| @@ -167,10 +167,9 @@ public class ShortestPathSolutionPanel extends JPanel | ||||
|             @Override | ||||
|             public void actionPerformed(ActionEvent e) { | ||||
|                 String filepath = System.getProperty("user.dir"); | ||||
|                 filepath += File.separator + String.format("path_%#x_%d_%d.path", | ||||
|                         currentBundle.getData().getGraph().getMapId(), | ||||
|                         currentBundle.getData().getOrigin().getId(), | ||||
|                         currentBundle.getData().getDestination().getId()); | ||||
|                 filepath += File.separator + String.format("path_%s_%d_%d.path", | ||||
|                         currentBundle.getData().getGraph().getMapId().toLowerCase().replaceAll("[^a-z0-9_]", "_"), | ||||
|                         currentBundle.getData().getOrigin().getId(), currentBundle.getData().getDestination().getId()); | ||||
|                 JFileChooser fileChooser = new JFileChooser(); | ||||
|                 fileChooser.setSelectedFile(new File(filepath)); | ||||
|                 fileChooser.setApproveButtonText("Save"); | ||||
| @@ -178,13 +177,12 @@ public class ShortestPathSolutionPanel extends JPanel | ||||
|                 if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) { | ||||
|                     File file = fileChooser.getSelectedFile(); | ||||
|                     try { | ||||
|                         BinaryPathWriter writer = new BinaryPathWriter(new DataOutputStream( | ||||
|                                 new BufferedOutputStream(new FileOutputStream(file)))); | ||||
|                         BinaryPathWriter writer = new BinaryPathWriter( | ||||
|                                 new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)))); | ||||
|                         writer.writePath(currentBundle.getSolution().getPath()); | ||||
|                     } | ||||
|                     catch (IOException e1) { | ||||
|                         JOptionPane.showMessageDialog(parent, | ||||
|                                 "Unable to write path to the selected file."); | ||||
|                         JOptionPane.showMessageDialog(parent, "Unable to write path to the selected file."); | ||||
|                         e1.printStackTrace(); | ||||
|                     } | ||||
|                 } | ||||
| @@ -237,8 +235,8 @@ public class ShortestPathSolutionPanel extends JPanel | ||||
|         ShortestPathData data = bundle.getData(); | ||||
|         String info = null; | ||||
|         if (!bundle.getSolution().isFeasible()) { | ||||
|             info = String.format("No path found from node #%d to node #%d.", | ||||
|                     data.getOrigin().getId(), data.getDestination().getId()); | ||||
|             info = String.format("No path found from node #%d to node #%d.", data.getOrigin().getId(), | ||||
|                     data.getDestination().getId()); | ||||
|         } | ||||
|         else { | ||||
|             info = String.format("Found a path from node #%d to node #%d", data.getOrigin().getId(), | ||||
| @@ -275,6 +273,12 @@ public class ShortestPathSolutionPanel extends JPanel | ||||
|  | ||||
|     @Override | ||||
|     public void newGraphLoaded(Graph graph) { | ||||
|         for (int i = 0; i < this.solutionSelect.getItemCount(); ++i) { | ||||
|             PathOverlay overlay = this.solutionSelect.getItemAt(i).getOverlay(); | ||||
|             if (overlay != null) { | ||||
|                 overlay.delete(); | ||||
|             } | ||||
|         } | ||||
|         this.solutionSelect.removeAllItems(); | ||||
|         this.currentBundle = null; | ||||
|         this.setVisible(false); | ||||
|   | ||||
| @@ -8,7 +8,6 @@ import java.awt.Image; | ||||
| import java.awt.event.MouseAdapter; | ||||
| import java.awt.event.MouseEvent; | ||||
| import java.awt.event.MouseListener; | ||||
| import java.awt.geom.AffineTransform; | ||||
| import java.awt.geom.NoninvertibleTransformException; | ||||
| import java.awt.geom.Point2D; | ||||
| import java.awt.image.BufferedImage; | ||||
| @@ -129,8 +128,7 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|             double scale = DEFAULT_MARKER_WIDTH / (double) img.getHeight(); | ||||
|             gr.scale(scale, scale); | ||||
|  | ||||
|             graphics.drawImage(img, px - img.getWidth() / 2, py - img.getHeight(), | ||||
|                     BasicDrawing.this); | ||||
|             graphics.drawImage(img, px - img.getWidth() / 2, py - img.getHeight(), BasicDrawing.this); | ||||
|         } | ||||
|  | ||||
|     }; | ||||
| @@ -279,8 +277,7 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|     private Graphics2D graphGraphics = null; | ||||
|  | ||||
|     // List of image for markers | ||||
|     private List<BasicOverlay> overlays = Collections | ||||
|             .synchronizedList(new ArrayList<BasicOverlay>()); | ||||
|     private List<BasicOverlay> overlays = Collections.synchronizedList(new ArrayList<BasicOverlay>()); | ||||
|  | ||||
|     // Mapping DrawingClickListener -> MouseEventListener | ||||
|     private Map<DrawingClickListener, MouseListener> listenerMapping = new IdentityHashMap<>(); | ||||
| @@ -290,14 +287,7 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|      *  | ||||
|      */ | ||||
|     public BasicDrawing() { | ||||
|         this.zoomAndPanListener = new ZoomAndPanListener(this, | ||||
|                 ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2); | ||||
|         this.addMouseListener(zoomAndPanListener); | ||||
|         this.addMouseMotionListener(zoomAndPanListener); | ||||
|         this.addMouseWheelListener(zoomAndPanListener); | ||||
|  | ||||
|         // Avoid bunch of NullPointerException | ||||
|         this.zoomAndPanListener.setCoordTransform(new AffineTransform()); | ||||
|         this.zoomAndPanListener = new ZoomAndPanListener(this, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
| @@ -347,8 +337,7 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|         // Get the point using the inverse transform of the Zoom/Pan object, this gives | ||||
|         // us | ||||
|         // a point within the drawing box (between [0, 0] and [width, height]). | ||||
|         Point2D ptDst = this.zoomAndPanListener.getCoordTransform() | ||||
|                 .inverseTransform(event.getPoint(), null); | ||||
|         Point2D ptDst = this.zoomAndPanListener.getCoordTransform().inverseTransform(event.getPoint(), null); | ||||
|  | ||||
|         // Inverse the "projection" on x/y to get longitude and latitude. | ||||
|         double lon = ptDst.getX(); | ||||
| @@ -427,9 +416,9 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|      *  | ||||
|      * @param arc Arc to draw. | ||||
|      * @param palette Palette to use to retrieve color and width for arc, or null to | ||||
|      * use current settings. | ||||
|      *        use current settings. | ||||
|      */ | ||||
|     protected void drawArc(Arc arc, GraphPalette palette) { | ||||
|     protected void drawArc(Arc arc, GraphPalette palette, boolean repaint) { | ||||
|         List<Point> pts = arc.getPoints(); | ||||
|         if (!pts.isEmpty()) { | ||||
|             if (palette != null) { | ||||
| @@ -450,7 +439,9 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|                 prev = curr; | ||||
|             } | ||||
|         } | ||||
|         this.repaint(); | ||||
|         if (repaint) { | ||||
|             this.repaint(); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     /** | ||||
| @@ -464,8 +455,8 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|         this.clear(); | ||||
|  | ||||
|         // Find minimum/maximum longitude and latitude. | ||||
|         double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY, | ||||
|                 maxLon = Double.NEGATIVE_INFINITY, maxLat = Double.NEGATIVE_INFINITY; | ||||
|         double minLon = Double.POSITIVE_INFINITY, minLat = Double.POSITIVE_INFINITY, maxLon = Double.NEGATIVE_INFINITY, | ||||
|                 maxLat = Double.NEGATIVE_INFINITY; | ||||
|         for (Node node: graph.getNodes()) { | ||||
|             Point pt = node.getPoint(); | ||||
|             if (pt.getLatitude() < minLat) { | ||||
| @@ -503,8 +494,7 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|         } | ||||
|  | ||||
|         // Create the image | ||||
|         BufferedImage img = new BufferedImage(this.width, this.height, | ||||
|                 BufferedImage.TYPE_3BYTE_BGR); | ||||
|         BufferedImage img = new BufferedImage(this.width, this.height, BufferedImage.TYPE_3BYTE_BGR); | ||||
|         this.graphImage = img; | ||||
|         this.graphGraphics = img.createGraphics(); | ||||
|         this.graphGraphics.setBackground(Color.WHITE); | ||||
| @@ -512,12 +502,10 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|  | ||||
|         // Set the zoom and pan listener | ||||
|  | ||||
|         double scale = 1 / Math.max(this.width / (double) this.getWidth(), | ||||
|                 this.height / (double) this.getHeight()); | ||||
|         double scale = 1 / Math.max(this.width / (double) this.getWidth(), this.height / (double) this.getHeight()); | ||||
|  | ||||
|         this.zoomAndPanListener.setCoordTransform(this.graphGraphics.getTransform()); | ||||
|         this.zoomAndPanListener.getCoordTransform().translate( | ||||
|                 (this.getWidth() - this.width * scale) / 2, | ||||
|         this.zoomAndPanListener.getCoordTransform().translate((this.getWidth() - this.width * scale) / 2, | ||||
|                 (this.getHeight() - this.height * scale) / 2); | ||||
|         this.zoomAndPanListener.getCoordTransform().scale(scale, scale); | ||||
|         this.zoomAndPanListener.setZoomLevel(0); | ||||
| @@ -528,15 +516,33 @@ public class BasicDrawing extends JPanel implements Drawing { | ||||
|  | ||||
|     @Override | ||||
|     public void drawGraph(Graph graph, GraphPalette palette) { | ||||
|         int repaintModulo = graph.getNodes().size() / 100; | ||||
|  | ||||
|         // Initialize the buffered image | ||||
|  | ||||
|         this.initialize(graph); | ||||
|  | ||||
|         // Remove zoom and pan listener | ||||
|         this.removeMouseListener(zoomAndPanListener); | ||||
|         this.removeMouseMotionListener(zoomAndPanListener); | ||||
|         this.removeMouseWheelListener(zoomAndPanListener); | ||||
|  | ||||
|         for (Node node: graph.getNodes()) { | ||||
|             for (Arc arc: node.getSuccessors()) { | ||||
|                 if (arc.getRoadInformation().isOneWay() | ||||
|                         || arc.getOrigin().compareTo(arc.getDestination()) < 0) { | ||||
|                     drawArc(arc, palette); | ||||
|                 if (arc.getRoadInformation().isOneWay() || arc.getOrigin().compareTo(arc.getDestination()) < 0) { | ||||
|                     drawArc(arc, palette, false); | ||||
|                 } | ||||
|             } | ||||
|             if (node.getId() % repaintModulo == 0) { | ||||
|                 this.repaint(); | ||||
|             } | ||||
|         } | ||||
|         this.repaint(); | ||||
|  | ||||
|         // Re-add zoom and pan listener | ||||
|         this.addMouseListener(zoomAndPanListener); | ||||
|         this.addMouseMotionListener(zoomAndPanListener); | ||||
|         this.addMouseWheelListener(zoomAndPanListener); | ||||
|     } | ||||
|  | ||||
|     @Override | ||||
|   | ||||
		Reference in New Issue
	
	Block a user