Update solution panel.

This commit is contained in:
Holt59 2018-03-01 21:10:34 +01:00
parent 08fd7120f2
commit 5d28e12903

View File

@ -9,8 +9,6 @@ import java.io.DataOutputStream;
import java.io.File; import java.io.File;
import java.io.FileOutputStream; import java.io.FileOutputStream;
import java.io.IOException; import java.io.IOException;
import java.util.IdentityHashMap;
import java.util.Map;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.Box; import javax.swing.Box;
@ -32,25 +30,81 @@ import org.insa.graph.io.BinaryPathWriter;
import org.insa.graphics.drawing.Drawing; import org.insa.graphics.drawing.Drawing;
import org.insa.graphics.drawing.overlays.PathOverlay; import org.insa.graphics.drawing.overlays.PathOverlay;
public class ShortestPathSolutionPanel extends JPanel public class ShortestPathSolutionPanel extends JPanel implements DrawingChangeListener, GraphChangeListener {
implements DrawingChangeListener, GraphChangeListener {
/** /**
* *
*/ */
private static final long serialVersionUID = 1L; private static final long serialVersionUID = 1L;
// Parent components private class ShortestPathBundle {
Component parent;
// Solution
private final ShortestPathSolution solution;
// Path Overlay (not final due to redraw)
private PathOverlay overlay = null;
/**
* Create a new bundle with the given solution and create a new overlay
* corresponding to the solution (if the solution is feasible).
*
* @param solution Solution for this bundle, must not be null.
*
*/
public ShortestPathBundle(ShortestPathSolution solution) {
this.solution = solution;
if (this.solution.isFeasible()) {
this.overlay = drawing.drawPath(this.solution.getPath());
}
}
/**
* @return Solution associated with this bundle.
*/
public ShortestPathSolution getSolution() {
return this.solution;
}
/**
* @return Data assocaited with this bundle.
*/
public ShortestPathData getData() {
return (ShortestPathData) this.solution.getInstance();
}
/**
* @return Overlay associated with this bundle, or null.
*/
public PathOverlay getOverlay() {
return this.overlay;
}
/**
* Re-draw the current overlay (if any) on the new drawing.
*
*/
public void updateOverlay(Drawing newDrawing) {
if (this.overlay != null) {
PathOverlay oldOverlay = this.overlay;
this.overlay = newDrawing.drawPath(this.solution.getPath());
this.overlay.setVisible(oldOverlay.isVisible());
oldOverlay.delete();
}
}
}
// Solution // Solution
private Drawing drawing; private Drawing drawing;
// Solution selector // Solution selector
JComboBox<ShortestPathSolution> solutionSelect; private final JComboBox<ShortestPathBundle> solutionSelect;
// Map solution -> panel // Map solution -> panel
Map<ShortestPathSolution, JPanel> solutionToPanel = new IdentityHashMap<>(); private final JLabel informationPanel;
// Current bundle
private ShortestPathBundle currentBundle = null;
public ShortestPathSolutionPanel(Component parent, Drawing drawing) { public ShortestPathSolutionPanel(Component parent, Drawing drawing) {
super(); super();
@ -58,87 +112,29 @@ public class ShortestPathSolutionPanel extends JPanel
setBorder(new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK), setBorder(new CompoundBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.BLACK),
new EmptyBorder(15, 15, 15, 15))); new EmptyBorder(15, 15, 15, 15)));
this.parent = parent;
this.drawing = drawing; this.drawing = drawing;
// TODO: Create select + Block for JPanel // TODO: Create select + Block for JPanel
solutionSelect = new JComboBox<>(new ShortestPathSolution[0]); solutionSelect = new JComboBox<>();
solutionSelect.setBackground(Color.WHITE); solutionSelect.setBackground(Color.WHITE);
solutionSelect.setAlignmentX(Component.LEFT_ALIGNMENT); solutionSelect.setAlignmentX(Component.LEFT_ALIGNMENT);
add(solutionSelect); add(solutionSelect);
JPanel bottomPanel = new JPanel(); informationPanel = new JLabel();
bottomPanel.setAlignmentX(Component.LEFT_ALIGNMENT); informationPanel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
add(bottomPanel); informationPanel.setHorizontalAlignment(JLabel.LEFT);
add(informationPanel);
solutionSelect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
@SuppressWarnings("unchecked")
JComboBox<ShortestPathSolution> combo = (JComboBox<ShortestPathSolution>) e
.getSource();
ShortestPathSolution solution = (ShortestPathSolution) combo.getSelectedItem();
bottomPanel.removeAll();
bottomPanel.add(solutionToPanel.get(solution));
}
});
}
public void addSolution(ShortestPathSolution solution) {
// add info panel
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.PAGE_AXIS));
panel.add(createInformationLabel(solution));
if (solution != null && solution.isFeasible()) {
panel.add(Box.createVerticalStrut(8));
panel.add(createPathPanel(solution));
}
solutionToPanel.put(solution, panel);
solutionSelect.addItem(solution);
solutionSelect.setSelectedItem(solution);
}
protected JLabel createInformationLabel(ShortestPathSolution solution) {
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));
}
}
JLabel label = new JLabel(info);
label.setAlignmentX(Component.LEFT_ALIGNMENT);
label.setHorizontalAlignment(JLabel.LEFT);
return label;
}
protected JPanel createPathPanel(ShortestPathSolution solution) {
ShortestPathData data = (ShortestPathData) solution.getInstance();
final PathOverlay overlay = drawing.drawPath(solution.getPath());
JButton clearButton = new JButton("Hide"); JButton clearButton = new JButton("Hide");
clearButton.addActionListener(new ActionListener() { clearButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
PathOverlay overlay = currentBundle.getOverlay();
if (overlay == null) {
return;
}
if (overlay.isVisible()) { if (overlay.isVisible()) {
overlay.setVisible(false); overlay.setVisible(false);
clearButton.setText("Show"); clearButton.setText("Show");
@ -149,14 +145,15 @@ public class ShortestPathSolutionPanel extends JPanel
} }
} }
}); });
JButton saveButton = new JButton("Save"); JButton saveButton = new JButton("Save");
saveButton.addActionListener(new ActionListener() { saveButton.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
String filepath = System.getProperty("user.dir"); String filepath = System.getProperty("user.dir");
filepath += File.separator filepath += File.separator + String.format("path_%#x_%d_%d.path",
+ String.format("path_%#x_%d_%d.path", data.getGraph().getMapId(), currentBundle.getData().getGraph().getMapId(), currentBundle.getData().getOrigin().getId(),
data.getOrigin().getId(), data.getDestination().getId()); currentBundle.getData().getDestination().getId());
JFileChooser fileChooser = new JFileChooser(); JFileChooser fileChooser = new JFileChooser();
fileChooser.setSelectedFile(new File(filepath)); fileChooser.setSelectedFile(new File(filepath));
fileChooser.setApproveButtonText("Save"); fileChooser.setApproveButtonText("Save");
@ -164,13 +161,12 @@ public class ShortestPathSolutionPanel extends JPanel
if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) { if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
File file = fileChooser.getSelectedFile(); File file = fileChooser.getSelectedFile();
try { try {
BinaryPathWriter writer = new BinaryPathWriter(new DataOutputStream( BinaryPathWriter writer = new BinaryPathWriter(
new BufferedOutputStream(new FileOutputStream(file)))); new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))));
writer.writePath(solution.getPath()); writer.writePath(currentBundle.getSolution().getPath());
} }
catch (IOException e1) { catch (IOException e1) {
JOptionPane.showMessageDialog(parent, JOptionPane.showMessageDialog(parent, "Unable to write path to the selected file.");
"Unable to write path to the selected file.");
e1.printStackTrace(); e1.printStackTrace();
} }
} }
@ -182,15 +178,63 @@ public class ShortestPathSolutionPanel extends JPanel
buttonPanel.add(Box.createHorizontalGlue()); buttonPanel.add(Box.createHorizontalGlue());
buttonPanel.add(clearButton); buttonPanel.add(clearButton);
buttonPanel.add(saveButton); buttonPanel.add(saveButton);
buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT); buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
add(buttonPanel);
return buttonPanel; solutionSelect.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ShortestPathBundle bundle = (ShortestPathBundle) solutionSelect.getSelectedItem();
if (currentBundle.getOverlay() != null) {
currentBundle.getOverlay().setVisible(false);
}
buttonPanel.setVisible(bundle.getSolution().isFeasible());
clearButton.setText(bundle.getSolution().isFeasible() ? "Hide" : "Show");
if (bundle.getOverlay() != null) {
bundle.getOverlay().setVisible(true);
}
currentBundle = bundle;
}
});
}
public void addSolution(ShortestPathSolution solution) {
ShortestPathBundle bundle = new ShortestPathBundle(solution);
solutionSelect.addItem(bundle);
solutionSelect.setSelectedItem(bundle);
}
protected void updateInformationLabel(ShortestPathBundle bundle) {
ShortestPathData data = bundle.getData();
String info = null;
if (!bundle.getSolution().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,
(bundle.getSolution().getPath().getLength() / 1000.0));
}
else {
info = String.format("%s, %.2f minutes.", info,
(bundle.getSolution().getPath().getMinimumTravelTime() / 60.0));
}
}
informationPanel.setText(info);
} }
@Override @Override
public void newGraphLoaded(Graph graph) { public void newGraphLoaded(Graph graph) {
// TODO: this.solutionSelect.removeAllItems();
this.currentBundle = null;
} }
@Override @Override
@ -202,7 +246,9 @@ public class ShortestPathSolutionPanel extends JPanel
@Override @Override
public void onRedrawRequest() { public void onRedrawRequest() {
// TODO: for (int i = 0; i < this.solutionSelect.getItemCount(); ++i) {
this.solutionSelect.getItemAt(i).updateOverlay(drawing);
}
} }
} }