Add info panel for SP solutions.

This commit is contained in:
Holt59 2018-02-25 20:03:06 +01:00
parent 1cb11975a6
commit b192bb4f07
5 changed files with 136 additions and 24 deletions

View File

@ -11,7 +11,7 @@ public class BinaryPathWriter extends BinaryWriter implements PathWriter {
/**
* @param dos
*/
protected BinaryPathWriter(DataOutputStream dos) {
public BinaryPathWriter(DataOutputStream dos) {
super(dos);
}

View File

@ -11,13 +11,18 @@ import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.BufferedOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;
import java.util.ArrayList;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
@ -34,13 +39,14 @@ import javax.swing.KeyStroke;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder;
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.ShortestPathAlgorithmFactory;
import org.insa.algo.shortestpath.ShortestPathData;
import org.insa.algo.shortestpath.ShortestPathData.Mode;
import org.insa.algo.shortestpath.ShortestPathGraphicObserver;
import org.insa.algo.shortestpath.ShortestPathSolution;
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.BinaryGraphReaderV2;
import org.insa.graph.io.BinaryPathReader;
import org.insa.graph.io.BinaryPathWriter;
import org.insa.graph.io.GraphReader;
import org.insa.graph.io.MapMismatchException;
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.Drawing;
import org.insa.graphics.drawing.MapViewDrawing;
import org.insa.graphics.drawing.overlays.PathOverlay;
public class MainWindow extends JFrame {
@ -168,7 +176,7 @@ public class MainWindow extends JFrame {
GridBagConstraints c = new GridBagConstraints();
c.gridx = 0;
c.gridy = 1;
c.gridy = 2;
c.weightx = 1;
c.weighty = 1;
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) {
spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing));
// algo.addObserver(new ShortestPathTextObserver(printStream));
@ -230,9 +329,7 @@ public class MainWindow extends JFrame {
@Override
public void run() {
ShortestPathSolution solution = spAlgorithm.run();
if (solution != null && solution.isFeasible()) {
drawing.drawPath(solution.getPath());
}
displayShortestPathSolution(solution);
}
});
}
@ -463,19 +560,19 @@ public class MainWindow extends JFrame {
StartActionEvent evt = (StartActionEvent) e;
ShortestPathData data = new ShortestPathData(graph, evt.getOrigin(), evt.getDestination(),
evt.getMode());
ShortestPathAlgorithm spAlgorithm = null;
if (evt.getAlgorithmClass() == BellmanFordAlgorithm.class) {
spAlgorithm = new BellmanFordAlgorithm(data);
}
else if (evt.getAlgorithmClass() == DijkstraAlgorithm.class) {
spAlgorithm = new DijkstraAlgorithm(data);
}
else if (evt.getAlgorithmClass() == AStarAlgorithm.class) {
spAlgorithm = new AStarAlgorithm(data);
}
try {
ShortestPathAlgorithm spAlgorithm = ShortestPathAlgorithmFactory
.createAlgorithm(evt.getAlgorithmClass(), data);
spPanel.setEnabled(false);
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();
}
}
});
}
}));

View File

@ -41,7 +41,7 @@ public class BasicDrawing extends JPanel implements Drawing {
*/
private static final long serialVersionUID = 96779785877771827L;
public abstract class BasicOverlay implements Overlay {
private abstract class BasicOverlay implements Overlay {
// Visible?
protected boolean visible;
@ -56,6 +56,11 @@ public class BasicDrawing extends JPanel implements Drawing {
BasicDrawing.this.repaint();
}
@Override
public boolean isVisible() {
return this.visible;
}
@Override
public void delete() {
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.
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<Point> points;

View File

@ -49,7 +49,7 @@ public class MapViewDrawing extends MapView implements Drawing {
*/
private static final long serialVersionUID = 8606967833704938092L;
public class MapViewOverlay implements Overlay {
private class MapViewOverlay implements Overlay {
// Marker associated.
protected Layer[] layers;
@ -68,6 +68,11 @@ public class MapViewDrawing extends MapView implements Drawing {
}
}
@Override
public boolean isVisible() {
return this.layers[0].isVisible();
}
@Override
public void delete() {
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) {
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) {
super(new Layer[] { path, origin, destination });

View File

@ -9,6 +9,11 @@ public interface Overlay {
*/
public void setVisible(boolean visible);
/**
* @return true if this overlay is visible.
*/
public boolean isVisible();
/**
* Delete this marker.
*/