Add path panel separated from solution panel.
This commit is contained in:
parent
f22c1c93fa
commit
a5764948f9
@ -61,8 +61,8 @@ public class AlgorithmPanel extends JPanel {
|
|||||||
private final boolean graphicVisualization;
|
private final boolean graphicVisualization;
|
||||||
private final boolean textualVisualization;
|
private final boolean textualVisualization;
|
||||||
|
|
||||||
public StartActionEvent(Class<? extends AbstractAlgorithm<?>> algoClass, List<Node> nodes, AbstractInputData.Mode mode,
|
public StartActionEvent(Class<? extends AbstractAlgorithm<?>> algoClass, List<Node> nodes, Mode mode,
|
||||||
AbstractInputData.ArcFilter arcFilter, boolean graphicVisualization, boolean textualVisualization) {
|
ArcFilter arcFilter, boolean graphicVisualization, boolean textualVisualization) {
|
||||||
super(AlgorithmPanel.this, START_EVENT_ID, START_EVENT_COMMAND);
|
super(AlgorithmPanel.this, START_EVENT_ID, START_EVENT_COMMAND);
|
||||||
this.nodes = nodes;
|
this.nodes = nodes;
|
||||||
this.mode = mode;
|
this.mode = mode;
|
||||||
@ -82,14 +82,14 @@ public class AlgorithmPanel extends JPanel {
|
|||||||
/**
|
/**
|
||||||
* @return Mode associated with this event.
|
* @return Mode associated with this event.
|
||||||
*/
|
*/
|
||||||
public AbstractInputData.Mode getMode() {
|
public Mode getMode() {
|
||||||
return this.mode;
|
return this.mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @return Arc filter associated with this event.
|
* @return Arc filter associated with this event.
|
||||||
*/
|
*/
|
||||||
public AbstractInputData.ArcFilter getArcFilter() {
|
public ArcFilter getArcFilter() {
|
||||||
return this.arcFilter;
|
return this.arcFilter;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,28 +168,29 @@ public class AlgorithmPanel extends JPanel {
|
|||||||
add(this.nodesInputPanel);
|
add(this.nodesInputPanel);
|
||||||
components.add(this.nodesInputPanel);
|
components.add(this.nodesInputPanel);
|
||||||
|
|
||||||
JComboBox<AbstractInputData.ArcFilter> arcFilterSelect = new JComboBox<>(new AbstractInputData.ArcFilter[] { new AbstractInputData.ArcFilter() {
|
JComboBox<AbstractInputData.ArcFilter> arcFilterSelect = new JComboBox<>(
|
||||||
@Override
|
new AbstractInputData.ArcFilter[] { new AbstractInputData.ArcFilter() {
|
||||||
public boolean isAllowed(Arc arc) {
|
@Override
|
||||||
return true;
|
public boolean isAllowed(Arc arc) {
|
||||||
}
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "All arcs are allowed";
|
return "All arcs are allowed";
|
||||||
}
|
}
|
||||||
}, new AbstractInputData.ArcFilter() {
|
}, new AbstractInputData.ArcFilter() {
|
||||||
@Override
|
@Override
|
||||||
public boolean isAllowed(Arc arc) {
|
public boolean isAllowed(Arc arc) {
|
||||||
return arc.getRoadInformation().getAccessRestrictions().isAllowedFor(AccessMode.MOTORCAR)
|
return arc.getRoadInformation().getAccessRestrictions().isAllowedFor(AccessMode.MOTORCAR)
|
||||||
&& !arc.getRoadInformation().getAccessRestrictions().isPrivate();
|
&& !arc.getRoadInformation().getAccessRestrictions().isPrivate();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "Only non-private roads allowed for motorcars";
|
return "Only non-private roads allowed for motorcars";
|
||||||
}
|
}
|
||||||
} });
|
} });
|
||||||
arcFilterSelect.setBackground(Color.WHITE);
|
arcFilterSelect.setBackground(Color.WHITE);
|
||||||
|
|
||||||
// Add mode selection
|
// Add mode selection
|
||||||
@ -265,13 +266,17 @@ public class AlgorithmPanel extends JPanel {
|
|||||||
startAlgoButton.addActionListener(new ActionListener() {
|
startAlgoButton.addActionListener(new ActionListener() {
|
||||||
@Override
|
@Override
|
||||||
public void actionPerformed(ActionEvent e) {
|
public void actionPerformed(ActionEvent e) {
|
||||||
AbstractInputData.Mode mode = lengthModeButton.isSelected() ? AbstractInputData.Mode.LENGTH : AbstractInputData.Mode.TIME;
|
AbstractInputData.Mode mode = lengthModeButton.isSelected() ? AbstractInputData.Mode.LENGTH
|
||||||
|
: AbstractInputData.Mode.TIME;
|
||||||
|
|
||||||
for (ActionListener lis: startActionListeners) {
|
for (ActionListener lis: startActionListeners) {
|
||||||
lis.actionPerformed(new StartActionEvent(
|
lis.actionPerformed(
|
||||||
AlgorithmFactory.getAlgorithmClass(baseAlgorithm, (String) algoSelect.getSelectedItem()),
|
new StartActionEvent(
|
||||||
nodesInputPanel.getNodeForInputs(), mode, (AbstractInputData.ArcFilter) arcFilterSelect.getSelectedItem(),
|
AlgorithmFactory.getAlgorithmClass(baseAlgorithm,
|
||||||
graphicObserver.isSelected(), textObserver.isSelected()));
|
(String) algoSelect.getSelectedItem()),
|
||||||
|
nodesInputPanel.getNodeForInputs(), mode,
|
||||||
|
(AbstractInputData.ArcFilter) arcFilterSelect.getSelectedItem(),
|
||||||
|
graphicObserver.isSelected(), textObserver.isSelected()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -106,9 +106,12 @@ public class MainWindow extends JFrame {
|
|||||||
// Main panel.
|
// Main panel.
|
||||||
private JSplitPane mainPanel;
|
private JSplitPane mainPanel;
|
||||||
|
|
||||||
// Shortest path panel
|
// Algorithm panel
|
||||||
private AlgorithmPanel spPanel;
|
private AlgorithmPanel spPanel;
|
||||||
|
|
||||||
|
// Path panel
|
||||||
|
private PathsPanel pathPanel;
|
||||||
|
|
||||||
// List of items that cannot be used without a graph
|
// List of items that cannot be used without a graph
|
||||||
private ArrayList<JMenuItem> graphLockItems = new ArrayList<JMenuItem>();
|
private ArrayList<JMenuItem> graphLockItems = new ArrayList<JMenuItem>();
|
||||||
|
|
||||||
@ -183,14 +186,18 @@ public class MainWindow extends JFrame {
|
|||||||
});
|
});
|
||||||
spPanel.setVisible(false);
|
spPanel.setVisible(false);
|
||||||
|
|
||||||
|
this.pathPanel = new PathsPanel(this);
|
||||||
|
|
||||||
// Add click listeners to both drawing.
|
// Add click listeners to both drawing.
|
||||||
basicDrawing.addDrawingClickListener(spPanel.nodesInputPanel);
|
basicDrawing.addDrawingClickListener(spPanel.nodesInputPanel);
|
||||||
mapViewDrawing.addDrawingClickListener(spPanel.nodesInputPanel);
|
mapViewDrawing.addDrawingClickListener(spPanel.nodesInputPanel);
|
||||||
|
|
||||||
this.graphChangeListeneres.add(spPanel.nodesInputPanel);
|
this.graphChangeListeneres.add(spPanel.nodesInputPanel);
|
||||||
this.graphChangeListeneres.add(spPanel.solutionPanel);
|
this.graphChangeListeneres.add(spPanel.solutionPanel);
|
||||||
|
this.graphChangeListeneres.add(pathPanel);
|
||||||
this.drawingChangeListeners.add(spPanel.nodesInputPanel);
|
this.drawingChangeListeners.add(spPanel.nodesInputPanel);
|
||||||
this.drawingChangeListeners.add(spPanel.solutionPanel);
|
this.drawingChangeListeners.add(spPanel.solutionPanel);
|
||||||
|
this.drawingChangeListeners.add(pathPanel);
|
||||||
|
|
||||||
// Create action factory.
|
// Create action factory.
|
||||||
this.currentThread = new ThreadWrapper(this);
|
this.currentThread = new ThreadWrapper(this);
|
||||||
@ -231,11 +238,14 @@ public class MainWindow extends JFrame {
|
|||||||
c.gridx = 0;
|
c.gridx = 0;
|
||||||
c.gridy = 0;
|
c.gridy = 0;
|
||||||
c.fill = GridBagConstraints.HORIZONTAL;
|
c.fill = GridBagConstraints.HORIZONTAL;
|
||||||
|
rightComponent.add(pathPanel, c);
|
||||||
|
|
||||||
|
c.gridy = 1;
|
||||||
rightComponent.add(spPanel, c);
|
rightComponent.add(spPanel, c);
|
||||||
|
|
||||||
c = new 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;
|
||||||
@ -293,7 +303,10 @@ public class MainWindow extends JFrame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void displayShortestPathSolution(ShortestPathSolution solution) {
|
private void displayShortestPathSolution(ShortestPathSolution solution) {
|
||||||
spPanel.solutionPanel.addSolution(solution);
|
spPanel.solutionPanel.addSolution(solution, false); // Do not add overlay in the solution panel.
|
||||||
|
if (solution.isFeasible()) {
|
||||||
|
pathPanel.addPath(solution.getPath());
|
||||||
|
}
|
||||||
spPanel.solutionPanel.setVisible(true);
|
spPanel.solutionPanel.setVisible(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -526,7 +539,7 @@ public class MainWindow extends JFrame {
|
|||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Path path = reader.readPath(graph);
|
Path path = reader.readPath(graph);
|
||||||
drawing.drawPath(path);
|
pathPanel.addPath(path);
|
||||||
}
|
}
|
||||||
catch (MapMismatchException exception) {
|
catch (MapMismatchException exception) {
|
||||||
JOptionPane.showMessageDialog(MainWindow.this,
|
JOptionPane.showMessageDialog(MainWindow.this,
|
||||||
|
272
src/main/org/insa/graphics/PathsPanel.java
Normal file
272
src/main/org/insa/graphics/PathsPanel.java
Normal file
@ -0,0 +1,272 @@
|
|||||||
|
package org.insa.graphics;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Component;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.io.BufferedOutputStream;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.FileOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
|
import javax.swing.Box;
|
||||||
|
import javax.swing.BoxLayout;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JComboBox;
|
||||||
|
import javax.swing.JFileChooser;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JOptionPane;
|
||||||
|
import javax.swing.JPanel;
|
||||||
|
import javax.swing.JTextArea;
|
||||||
|
import javax.swing.UIManager;
|
||||||
|
import javax.swing.border.EmptyBorder;
|
||||||
|
|
||||||
|
import org.insa.graph.Graph;
|
||||||
|
import org.insa.graph.Path;
|
||||||
|
import org.insa.graph.io.BinaryPathWriter;
|
||||||
|
import org.insa.graphics.drawing.Drawing;
|
||||||
|
import org.insa.graphics.drawing.overlays.PathOverlay;
|
||||||
|
|
||||||
|
public class PathsPanel extends JPanel implements DrawingChangeListener, GraphChangeListener {
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
private static final long serialVersionUID = 1L;
|
||||||
|
|
||||||
|
private class PathBundle {
|
||||||
|
|
||||||
|
// Solution
|
||||||
|
private final Path path;
|
||||||
|
|
||||||
|
// Path Overlay (not final due to redraw)
|
||||||
|
private PathOverlay overlay;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a new bundle with the given path and create a new overlay
|
||||||
|
* corresponding to the path.
|
||||||
|
*
|
||||||
|
* @param path Path for this bundle, must not be null.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public PathBundle(Path path) {
|
||||||
|
this.path = path;
|
||||||
|
this.overlay = drawing.drawPath(this.path);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Path associated with this bundle.
|
||||||
|
*/
|
||||||
|
public Path getPath() {
|
||||||
|
return this.path;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Overlay associated with this bundle (never null).
|
||||||
|
*/
|
||||||
|
public PathOverlay getOverlay() {
|
||||||
|
return this.overlay;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Re-draw the current overlay (if any) on the new drawing.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public void updateOverlay() {
|
||||||
|
PathOverlay oldOverlay = this.overlay;
|
||||||
|
this.overlay = drawing.drawPath(path);
|
||||||
|
this.overlay.setVisible(oldOverlay.isVisible());
|
||||||
|
oldOverlay.delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* (non-Javadoc)
|
||||||
|
*
|
||||||
|
* @see java.lang.Object#toString()
|
||||||
|
*/
|
||||||
|
public String toString() {
|
||||||
|
return "Path from #" + path.getOrigin().getId() + " to #" + path.getDestination().getId();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
// Solution
|
||||||
|
private Drawing drawing;
|
||||||
|
|
||||||
|
// Solution selector
|
||||||
|
private final JComboBox<PathBundle> solutionSelect;
|
||||||
|
|
||||||
|
// Map solution -> panel
|
||||||
|
private final JTextArea informationPanel;
|
||||||
|
|
||||||
|
// Current bundle
|
||||||
|
private PathBundle currentBundle = null;
|
||||||
|
|
||||||
|
public PathsPanel(Component parent) {
|
||||||
|
super();
|
||||||
|
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
|
||||||
|
|
||||||
|
setBorder(new EmptyBorder(15, 15, 15, 15));
|
||||||
|
|
||||||
|
solutionSelect = new JComboBox<>();
|
||||||
|
solutionSelect.setBackground(Color.WHITE);
|
||||||
|
solutionSelect.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
add(solutionSelect);
|
||||||
|
|
||||||
|
informationPanel = new JTextArea();
|
||||||
|
informationPanel.setWrapStyleWord(true);
|
||||||
|
informationPanel.setLineWrap(true);
|
||||||
|
informationPanel.setOpaque(true);
|
||||||
|
informationPanel.setFocusable(false);
|
||||||
|
informationPanel.setEditable(false);
|
||||||
|
informationPanel.setBackground(UIManager.getColor("Label.background"));
|
||||||
|
informationPanel.setFont(UIManager.getFont("Label.font"));
|
||||||
|
informationPanel.setBorder(UIManager.getBorder("Label.border"));
|
||||||
|
informationPanel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
|
||||||
|
|
||||||
|
add(Box.createVerticalStrut(8));
|
||||||
|
add(informationPanel);
|
||||||
|
|
||||||
|
JButton clearButton = new JButton("Hide");
|
||||||
|
clearButton.addActionListener(new ActionListener() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
if (currentBundle != null) {
|
||||||
|
if (currentBundle.getOverlay().isVisible()) {
|
||||||
|
currentBundle.getOverlay().setVisible(false);
|
||||||
|
clearButton.setText("Show");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
currentBundle.getOverlay().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_%s_%d_%d.path",
|
||||||
|
currentBundle.getPath().getGraph().getMapId().toLowerCase().replaceAll("[^a-z0-9_]", "_"),
|
||||||
|
currentBundle.getPath().getOrigin().getId(), currentBundle.getPath().getDestination().getId());
|
||||||
|
JFileChooser fileChooser = new JFileChooser();
|
||||||
|
fileChooser.setSelectedFile(new File(filepath));
|
||||||
|
fileChooser.setApproveButtonText("Save");
|
||||||
|
|
||||||
|
if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
|
||||||
|
File file = fileChooser.getSelectedFile();
|
||||||
|
try {
|
||||||
|
BinaryPathWriter writer = new BinaryPathWriter(
|
||||||
|
new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file))));
|
||||||
|
writer.writePath(currentBundle.getPath());
|
||||||
|
}
|
||||||
|
catch (IOException e1) {
|
||||||
|
JOptionPane.showMessageDialog(parent, "Unable to write path to the selected file.");
|
||||||
|
e1.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
JPanel buttonPanel = new JPanel();
|
||||||
|
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
|
||||||
|
buttonPanel.add(Box.createHorizontalGlue());
|
||||||
|
buttonPanel.add(clearButton);
|
||||||
|
buttonPanel.add(saveButton);
|
||||||
|
buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
|
||||||
|
add(Box.createVerticalStrut(4));
|
||||||
|
add(buttonPanel);
|
||||||
|
|
||||||
|
solutionSelect.addActionListener(new ActionListener() {
|
||||||
|
public void actionPerformed(ActionEvent e) {
|
||||||
|
|
||||||
|
PathBundle bundle = (PathBundle) solutionSelect.getSelectedItem();
|
||||||
|
|
||||||
|
// Handle case when the JComboBox is empty.
|
||||||
|
if (bundle == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentBundle != null) {
|
||||||
|
currentBundle.getOverlay().setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
updateInformationLabel(bundle);
|
||||||
|
clearButton.setText("Hide");
|
||||||
|
bundle.getOverlay().setVisible(true);
|
||||||
|
currentBundle = bundle;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Default hidden
|
||||||
|
this.setVisible(false);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addPath(Path path) {
|
||||||
|
PathBundle bundle = new PathBundle(path);
|
||||||
|
solutionSelect.addItem(bundle);
|
||||||
|
solutionSelect.setSelectedItem(bundle);
|
||||||
|
|
||||||
|
this.setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void updateInformationLabel(PathBundle bundle) {
|
||||||
|
String info = "";
|
||||||
|
info += String.format("Length = %.3f kilometers, duration = ", bundle.getPath().getLength() / 1000.);
|
||||||
|
double time = bundle.getPath().getMinimumTravelTime();
|
||||||
|
int hours = (int) (time / 3600);
|
||||||
|
int minutes = (int) (time / 60) % 60;
|
||||||
|
int seconds = ((int) time) % 60;
|
||||||
|
info += String.format("%d hours, %d minutes, %d seconds.", hours, minutes, seconds);
|
||||||
|
informationPanel.setText(info);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setEnabled(boolean enabled) {
|
||||||
|
super.setEnabled(enabled);
|
||||||
|
solutionSelect.setEnabled(enabled);
|
||||||
|
|
||||||
|
if (enabled) {
|
||||||
|
// Trigger event
|
||||||
|
solutionSelect.actionPerformed(null);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
PathBundle bundle = (PathBundle) this.solutionSelect.getSelectedItem();
|
||||||
|
if (bundle != null) {
|
||||||
|
bundle.getOverlay().setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void newGraphLoaded(Graph graph) {
|
||||||
|
for (int i = 0; i < this.solutionSelect.getItemCount(); ++i) {
|
||||||
|
this.solutionSelect.getItemAt(i).getOverlay().delete();
|
||||||
|
}
|
||||||
|
this.solutionSelect.removeAllItems();
|
||||||
|
this.currentBundle = null;
|
||||||
|
this.setVisible(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onDrawingLoaded(Drawing oldDrawing, Drawing newDrawing) {
|
||||||
|
if (newDrawing != drawing) {
|
||||||
|
drawing = newDrawing;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onRedrawRequest() {
|
||||||
|
for (int i = 0; i < this.solutionSelect.getItemCount(); ++i) {
|
||||||
|
this.solutionSelect.getItemAt(i).updateOverlay();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -23,7 +23,6 @@ import javax.swing.border.EmptyBorder;
|
|||||||
|
|
||||||
import org.insa.algo.AbstractInputData;
|
import org.insa.algo.AbstractInputData;
|
||||||
import org.insa.algo.AbstractSolution;
|
import org.insa.algo.AbstractSolution;
|
||||||
import org.insa.algo.shortestpath.ShortestPathSolution;
|
|
||||||
import org.insa.graph.Graph;
|
import org.insa.graph.Graph;
|
||||||
import org.insa.graph.Path;
|
import org.insa.graph.Path;
|
||||||
import org.insa.graphics.drawing.Drawing;
|
import org.insa.graphics.drawing.Drawing;
|
||||||
@ -51,9 +50,11 @@ public class SolutionPanel extends JPanel implements DrawingChangeListener, Grap
|
|||||||
* @param solution Solution for this bundle, must not be null.
|
* @param solution Solution for this bundle, must not be null.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public SolutionBundle(AbstractSolution solution) {
|
public SolutionBundle(AbstractSolution solution, boolean createOverlays) {
|
||||||
this.solution = solution;
|
this.solution = solution;
|
||||||
this.overlays = createOverlaysFromSolution();
|
if (createOverlays) {
|
||||||
|
this.overlays = createOverlaysFromSolution();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -77,11 +78,21 @@ public class SolutionPanel extends JPanel implements DrawingChangeListener, Grap
|
|||||||
return this.overlays;
|
return this.overlays;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return true if this bundle has overlays.
|
||||||
|
*/
|
||||||
|
public boolean hasOverlays() {
|
||||||
|
return !this.overlays.isEmpty();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Re-draw the current overlay (if any) on the new drawing.
|
* Re-draw the current overlay (if any) on the new drawing.
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
public void updateOverlays() {
|
public void updateOverlays() {
|
||||||
|
if (this.overlays.isEmpty()) {
|
||||||
|
return; // This bundle has no overlay.
|
||||||
|
}
|
||||||
List<PathOverlay> oldOverlays = this.overlays;
|
List<PathOverlay> oldOverlays = this.overlays;
|
||||||
this.overlays = createOverlaysFromSolution();
|
this.overlays = createOverlaysFromSolution();
|
||||||
for (int i = 0; i < oldOverlays.size(); ++i) {
|
for (int i = 0; i < oldOverlays.size(); ++i) {
|
||||||
@ -153,6 +164,8 @@ public class SolutionPanel extends JPanel implements DrawingChangeListener, Grap
|
|||||||
informationPanel.setFont(UIManager.getFont("Label.font"));
|
informationPanel.setFont(UIManager.getFont("Label.font"));
|
||||||
informationPanel.setBorder(UIManager.getBorder("Label.border"));
|
informationPanel.setBorder(UIManager.getBorder("Label.border"));
|
||||||
informationPanel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
|
informationPanel.setAlignmentX(JLabel.LEFT_ALIGNMENT);
|
||||||
|
|
||||||
|
add(Box.createVerticalStrut(8));
|
||||||
add(informationPanel);
|
add(informationPanel);
|
||||||
|
|
||||||
JButton clearButton = new JButton("Hide");
|
JButton clearButton = new JButton("Hide");
|
||||||
@ -173,42 +186,13 @@ public class SolutionPanel extends JPanel implements DrawingChangeListener, Grap
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
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_%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");
|
|
||||||
//
|
|
||||||
// if (fileChooser.showOpenDialog(parent) == JFileChooser.APPROVE_OPTION) {
|
|
||||||
// File file = fileChooser.getSelectedFile();
|
|
||||||
// try {
|
|
||||||
// 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.");
|
|
||||||
// e1.printStackTrace();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
JPanel buttonPanel = new JPanel();
|
JPanel buttonPanel = new JPanel();
|
||||||
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
|
buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.LINE_AXIS));
|
||||||
buttonPanel.add(Box.createHorizontalGlue());
|
buttonPanel.add(Box.createHorizontalGlue());
|
||||||
buttonPanel.add(clearButton);
|
buttonPanel.add(clearButton);
|
||||||
buttonPanel.add(saveButton);
|
|
||||||
buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
buttonPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
|
||||||
|
|
||||||
|
add(Box.createVerticalStrut(4));
|
||||||
add(buttonPanel);
|
add(buttonPanel);
|
||||||
|
|
||||||
solutionSelect.addActionListener(new ActionListener() {
|
solutionSelect.addActionListener(new ActionListener() {
|
||||||
@ -228,7 +212,7 @@ public class SolutionPanel extends JPanel implements DrawingChangeListener, Grap
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateInformationLabel(bundle);
|
updateInformationLabel(bundle);
|
||||||
buttonPanel.setVisible(bundle.getSolution().isFeasible());
|
buttonPanel.setVisible(bundle.getSolution().isFeasible() && bundle.hasOverlays());
|
||||||
clearButton.setText(bundle.getSolution().isFeasible() ? "Hide" : "Show");
|
clearButton.setText(bundle.getSolution().isFeasible() ? "Hide" : "Show");
|
||||||
|
|
||||||
for (PathOverlay overlay: bundle.getOverlays()) {
|
for (PathOverlay overlay: bundle.getOverlays()) {
|
||||||
@ -241,8 +225,19 @@ public class SolutionPanel extends JPanel implements DrawingChangeListener, Grap
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addSolution(ShortestPathSolution solution) {
|
public void addSolution(AbstractSolution solution) {
|
||||||
SolutionBundle bundle = new SolutionBundle(solution);
|
addSolution(solution, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add the given solution to the panel.
|
||||||
|
*
|
||||||
|
* @param solution the solution to add to the panel
|
||||||
|
* @param createOverlays Whether or not overlay should be created for this
|
||||||
|
* solution.
|
||||||
|
*/
|
||||||
|
public void addSolution(AbstractSolution solution, boolean createOverlays) {
|
||||||
|
SolutionBundle bundle = new SolutionBundle(solution, createOverlays);
|
||||||
solutionSelect.addItem(bundle);
|
solutionSelect.addItem(bundle);
|
||||||
solutionSelect.setSelectedItem(bundle);
|
solutionSelect.setSelectedItem(bundle);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user