Add info panel for SP solutions.
This commit is contained in:
parent
1cb11975a6
commit
b192bb4f07
5 changed files with 136 additions and 24 deletions
|
@ -11,7 +11,7 @@ public class BinaryPathWriter extends BinaryWriter implements PathWriter {
|
||||||
/**
|
/**
|
||||||
* @param dos
|
* @param dos
|
||||||
*/
|
*/
|
||||||
protected BinaryPathWriter(DataOutputStream dos) {
|
public BinaryPathWriter(DataOutputStream dos) {
|
||||||
super(dos);
|
super(dos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,13 +11,18 @@ import java.awt.event.ActionListener;
|
||||||
import java.awt.event.KeyEvent;
|
import java.awt.event.KeyEvent;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.PrintStream;
|
import java.io.PrintStream;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
import javax.swing.BorderFactory;
|
import javax.swing.BorderFactory;
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
import javax.swing.JButton;
|
import javax.swing.JButton;
|
||||||
import javax.swing.JFileChooser;
|
import javax.swing.JFileChooser;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
@ -34,13 +39,14 @@ import javax.swing.KeyStroke;
|
||||||
import javax.swing.SwingConstants;
|
import javax.swing.SwingConstants;
|
||||||
import javax.swing.Timer;
|
import javax.swing.Timer;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.border.CompoundBorder;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
import javax.swing.filechooser.FileNameExtensionFilter;
|
import javax.swing.filechooser.FileNameExtensionFilter;
|
||||||
|
|
||||||
import org.insa.algo.shortestpath.AStarAlgorithm;
|
|
||||||
import org.insa.algo.shortestpath.BellmanFordAlgorithm;
|
|
||||||
import org.insa.algo.shortestpath.DijkstraAlgorithm;
|
|
||||||
import org.insa.algo.shortestpath.ShortestPathAlgorithm;
|
import org.insa.algo.shortestpath.ShortestPathAlgorithm;
|
||||||
|
import org.insa.algo.shortestpath.ShortestPathAlgorithmFactory;
|
||||||
import org.insa.algo.shortestpath.ShortestPathData;
|
import org.insa.algo.shortestpath.ShortestPathData;
|
||||||
|
import org.insa.algo.shortestpath.ShortestPathData.Mode;
|
||||||
import org.insa.algo.shortestpath.ShortestPathGraphicObserver;
|
import org.insa.algo.shortestpath.ShortestPathGraphicObserver;
|
||||||
import org.insa.algo.shortestpath.ShortestPathSolution;
|
import org.insa.algo.shortestpath.ShortestPathSolution;
|
||||||
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver;
|
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver;
|
||||||
|
@ -52,6 +58,7 @@ import org.insa.graph.Path;
|
||||||
import org.insa.graph.io.BinaryGraphReader;
|
import org.insa.graph.io.BinaryGraphReader;
|
||||||
import org.insa.graph.io.BinaryGraphReaderV2;
|
import org.insa.graph.io.BinaryGraphReaderV2;
|
||||||
import org.insa.graph.io.BinaryPathReader;
|
import org.insa.graph.io.BinaryPathReader;
|
||||||
|
import org.insa.graph.io.BinaryPathWriter;
|
||||||
import org.insa.graph.io.GraphReader;
|
import org.insa.graph.io.GraphReader;
|
||||||
import org.insa.graph.io.MapMismatchException;
|
import org.insa.graph.io.MapMismatchException;
|
||||||
import org.insa.graph.io.Openfile;
|
import org.insa.graph.io.Openfile;
|
||||||
|
@ -60,6 +67,7 @@ import org.insa.graphics.drawing.BasicDrawing;
|
||||||
import org.insa.graphics.drawing.BlackAndWhiteGraphPalette;
|
import org.insa.graphics.drawing.BlackAndWhiteGraphPalette;
|
||||||
import org.insa.graphics.drawing.Drawing;
|
import org.insa.graphics.drawing.Drawing;
|
||||||
import org.insa.graphics.drawing.MapViewDrawing;
|
import org.insa.graphics.drawing.MapViewDrawing;
|
||||||
|
import org.insa.graphics.drawing.overlays.PathOverlay;
|
||||||
|
|
||||||
public class MainWindow extends JFrame {
|
public class MainWindow extends JFrame {
|
||||||
|
|
||||||
|
@ -168,7 +176,7 @@ public class MainWindow extends JFrame {
|
||||||
|
|
||||||
GridBagConstraints c = new GridBagConstraints();
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
c.gridy = 1;
|
c.gridy = 2;
|
||||||
c.weightx = 1;
|
c.weightx = 1;
|
||||||
c.weighty = 1;
|
c.weighty = 1;
|
||||||
c.fill = GridBagConstraints.BOTH;
|
c.fill = GridBagConstraints.BOTH;
|
||||||
|
@ -223,6 +231,97 @@ public class MainWindow extends JFrame {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void displayShortestPathSolution(ShortestPathSolution solution) {
|
||||||
|
JPanel infoPanel = new JPanel();
|
||||||
|
infoPanel.setLayout(new BoxLayout(infoPanel, BoxLayout.PAGE_AXIS));
|
||||||
|
infoPanel.setBorder(new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK),
|
||||||
|
new EmptyBorder(15, 15, 15, 15)));
|
||||||
|
|
||||||
|
ShortestPathData data = (ShortestPathData) solution.getInstance();
|
||||||
|
|
||||||
|
String info = null;
|
||||||
|
if (solution == null || !solution.isFeasible()) {
|
||||||
|
info = String.format("Shortest path: No path found from node #%d to node #%d.", data.getOrigin().getId(),
|
||||||
|
data.getDestination().getId());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
info = String.format("Shortest path: Found a path from node #%d to node #%d", data.getOrigin().getId(),
|
||||||
|
data.getDestination().getId());
|
||||||
|
if (data.getMode() == Mode.LENGTH) {
|
||||||
|
info = String.format("%s, %.2f kilometers.", info, (solution.getPath().getLength() / 1000.0));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
info = String.format("%s, %.2f minutes.", info, (solution.getPath().getMinimumTravelTime() / 60.0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
infoPanel.add(new JLabel(info));
|
||||||
|
|
||||||
|
if (solution != null && solution.isFeasible()) {
|
||||||
|
infoPanel.add(Box.createVerticalStrut(8));
|
||||||
|
|
||||||
|
PathOverlay overlay = drawing.drawPath(solution.getPath());
|
||||||
|
|
||||||
|
JPanel buttonPanel = new JPanel();
|
||||||
|
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
|
||||||
|
buttonPanel.add(Box.createHorizontalGlue());
|
||||||
|
JButton clearButton = new JButton("Hide");
|
||||||
|
clearButton.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
private PathOverlay thisOverlay = overlay;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (thisOverlay.isVisible()) {
|
||||||
|
thisOverlay.setVisible(false);
|
||||||
|
clearButton.setText("Show");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
thisOverlay.setVisible(true);
|
||||||
|
clearButton.setText("Hide");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
JButton saveButton = new JButton("Save");
|
||||||
|
saveButton.addActionListener(new ActionListener() {
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
String filepath = System.getProperty("user.dir");
|
||||||
|
filepath += File.separator + String.format("path_%#x_%d_%d.path", graph.getMapId(),
|
||||||
|
data.getOrigin().getId(), data.getDestination().getId());
|
||||||
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
|
fileChooser.setSelectedFile(new File(filepath));
|
||||||
|
fileChooser.setApproveButtonText("Save");
|
||||||
|
|
||||||
|
if (fileChooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File file = fileChooser.getSelectedFile();
|
||||||
|
try {
|
||||||
|
BinaryPathWriter writer = new BinaryPathWriter(
|
||||||
|
new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))));
|
||||||
|
writer.writePath(solution.getPath());
|
||||||
|
}
|
||||||
|
catch (IOException e1) {
|
||||||
|
JOptionPane.showMessageDialog(MainWindow.this,
|
||||||
|
"Unable to write path to the selected file.");
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
buttonPanel.add(clearButton);
|
||||||
|
buttonPanel.add(saveButton);
|
||||||
|
infoPanel.add(buttonPanel);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add panel to the right side
|
||||||
|
GridBagConstraints c = new GridBagConstraints();
|
||||||
|
c.gridx = 0;
|
||||||
|
c.gridy = 1;
|
||||||
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
((JPanel) mainPanel.getRightComponent()).add(infoPanel, c);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) {
|
private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) {
|
||||||
spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing));
|
spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing));
|
||||||
// algo.addObserver(new ShortestPathTextObserver(printStream));
|
// algo.addObserver(new ShortestPathTextObserver(printStream));
|
||||||
|
@ -230,9 +329,7 @@ public class MainWindow extends JFrame {
|
||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
ShortestPathSolution solution = spAlgorithm.run();
|
ShortestPathSolution solution = spAlgorithm.run();
|
||||||
if (solution != null && solution.isFeasible()) {
|
displayShortestPathSolution(solution);
|
||||||
drawing.drawPath(solution.getPath());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -463,19 +560,19 @@ public class MainWindow extends JFrame {
|
||||||
StartActionEvent evt = (StartActionEvent) e;
|
StartActionEvent evt = (StartActionEvent) e;
|
||||||
ShortestPathData data = new ShortestPathData(graph, evt.getOrigin(), evt.getDestination(),
|
ShortestPathData data = new ShortestPathData(graph, evt.getOrigin(), evt.getDestination(),
|
||||||
evt.getMode());
|
evt.getMode());
|
||||||
ShortestPathAlgorithm spAlgorithm = null;
|
try {
|
||||||
if (evt.getAlgorithmClass() == BellmanFordAlgorithm.class) {
|
ShortestPathAlgorithm spAlgorithm = ShortestPathAlgorithmFactory
|
||||||
spAlgorithm = new BellmanFordAlgorithm(data);
|
.createAlgorithm(evt.getAlgorithmClass(), data);
|
||||||
}
|
|
||||||
else if (evt.getAlgorithmClass() == DijkstraAlgorithm.class) {
|
|
||||||
spAlgorithm = new DijkstraAlgorithm(data);
|
|
||||||
}
|
|
||||||
else if (evt.getAlgorithmClass() == AStarAlgorithm.class) {
|
|
||||||
spAlgorithm = new AStarAlgorithm(data);
|
|
||||||
}
|
|
||||||
spPanel.setEnabled(false);
|
spPanel.setEnabled(false);
|
||||||
launchShortestPathThread(spAlgorithm);
|
launchShortestPathThread(spAlgorithm);
|
||||||
}
|
}
|
||||||
|
catch (Exception e1) {
|
||||||
|
JOptionPane.showMessageDialog(MainWindow.this,
|
||||||
|
"An error occurred while creating the specified algorithm.",
|
||||||
|
"Internal error: Algorithm instantiation failure", JOptionPane.ERROR_MESSAGE);
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
|
|
|
@ -41,7 +41,7 @@ public class BasicDrawing extends JPanel implements Drawing {
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 96779785877771827L;
|
private static final long serialVersionUID = 96779785877771827L;
|
||||||
|
|
||||||
public abstract class BasicOverlay implements Overlay {
|
private abstract class BasicOverlay implements Overlay {
|
||||||
|
|
||||||
// Visible?
|
// Visible?
|
||||||
protected boolean visible;
|
protected boolean visible;
|
||||||
|
@ -56,6 +56,11 @@ public class BasicDrawing extends JPanel implements Drawing {
|
||||||
BasicDrawing.this.repaint();
|
BasicDrawing.this.repaint();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVisible() {
|
||||||
|
return this.visible;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
BasicDrawing.this.overlays.remove(this);
|
BasicDrawing.this.overlays.remove(this);
|
||||||
|
@ -75,7 +80,7 @@ public class BasicDrawing extends JPanel implements Drawing {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public class BasicMarkerOverlay extends BasicOverlay implements MarkerOverlay {
|
private class BasicMarkerOverlay extends BasicOverlay implements MarkerOverlay {
|
||||||
|
|
||||||
// Point of the marker.
|
// Point of the marker.
|
||||||
private Point point;
|
private Point point;
|
||||||
|
@ -116,7 +121,7 @@ public class BasicDrawing extends JPanel implements Drawing {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public class BasicPathOverlay extends BasicOverlay implements PathOverlay {
|
private class BasicPathOverlay extends BasicOverlay implements PathOverlay {
|
||||||
|
|
||||||
// List of points
|
// List of points
|
||||||
List<Point> points;
|
List<Point> points;
|
||||||
|
|
|
@ -49,7 +49,7 @@ public class MapViewDrawing extends MapView implements Drawing {
|
||||||
*/
|
*/
|
||||||
private static final long serialVersionUID = 8606967833704938092L;
|
private static final long serialVersionUID = 8606967833704938092L;
|
||||||
|
|
||||||
public class MapViewOverlay implements Overlay {
|
private class MapViewOverlay implements Overlay {
|
||||||
|
|
||||||
// Marker associated.
|
// Marker associated.
|
||||||
protected Layer[] layers;
|
protected Layer[] layers;
|
||||||
|
@ -68,6 +68,11 @@ public class MapViewDrawing extends MapView implements Drawing {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean isVisible() {
|
||||||
|
return this.layers[0].isVisible();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void delete() {
|
public void delete() {
|
||||||
Layers mlayers = MapViewDrawing.this.getLayerManager().getLayers();
|
Layers mlayers = MapViewDrawing.this.getLayerManager().getLayers();
|
||||||
|
@ -78,7 +83,7 @@ public class MapViewDrawing extends MapView implements Drawing {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public class MapViewMarkerOverlay extends MapViewOverlay implements MarkerOverlay {
|
private class MapViewMarkerOverlay extends MapViewOverlay implements MarkerOverlay {
|
||||||
|
|
||||||
public MapViewMarkerOverlay(Marker marker) {
|
public MapViewMarkerOverlay(Marker marker) {
|
||||||
super(new Layer[] { marker });
|
super(new Layer[] { marker });
|
||||||
|
@ -102,7 +107,7 @@ public class MapViewDrawing extends MapView implements Drawing {
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
public class MapViewPathOverlay extends MapViewOverlay implements PathOverlay {
|
private class MapViewPathOverlay extends MapViewOverlay implements PathOverlay {
|
||||||
|
|
||||||
public MapViewPathOverlay(PolylineAutoScaling path, Marker origin, Marker destination) {
|
public MapViewPathOverlay(PolylineAutoScaling path, Marker origin, Marker destination) {
|
||||||
super(new Layer[] { path, origin, destination });
|
super(new Layer[] { path, origin, destination });
|
||||||
|
|
|
@ -9,6 +9,11 @@ public interface Overlay {
|
||||||
*/
|
*/
|
||||||
public void setVisible(boolean visible);
|
public void setVisible(boolean visible);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this overlay is visible.
|
||||||
|
*/
|
||||||
|
public boolean isVisible();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete this marker.
|
* Delete this marker.
|
||||||
*/
|
*/
|
||||||
|
|
Loading…
Reference in a new issue