Add panel for WCC like SP.

This commit is contained in:
Holt59 2018-03-05 22:40:32 +01:00
parent 426867a302
commit c4b4455287
3 changed files with 198 additions and 73 deletions

View File

@ -32,4 +32,26 @@ public class WeaklyConnectedComponentsSolution extends AbstractSolution {
return components; return components;
} }
/*
* (non-Javadoc)
*
* @see java.lang.Object#toString()
*/
@Override
public String toString() {
int nIsolated = 0;
int nGt10 = 0;
for (ArrayList<Node> component: components) {
if (component.size() == 1) {
nIsolated += 1;
}
else if (component.size() > 10) {
nGt10 += 1;
}
}
return "Found " + components.size() + " components (" + nGt10 + " with more than 10 nodes, "
+ nIsolated + " isolated nodes) in " + getSolvingTime().getSeconds() + " seconds.";
}
} }

View File

@ -60,8 +60,9 @@ 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, Mode mode, public StartActionEvent(Class<? extends AbstractAlgorithm<?>> algoClass, List<Node> nodes,
ArcFilter arcFilter, boolean graphicVisualization, boolean textualVisualization) { Mode mode, 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;
@ -131,39 +132,27 @@ public class AlgorithmPanel extends JPanel {
/** /**
*/ */
public AlgorithmPanel(Component parent, Class<? extends AbstractAlgorithm<?>> baseAlgorithm) { public AlgorithmPanel(Component parent, Class<? extends AbstractAlgorithm<?>> baseAlgorithm,
String title, String[] nodeNames, boolean enableModeSelection,
boolean enableArcFilterSelection) {
super(); super();
setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS)); setLayout(new BoxLayout(this, BoxLayout.PAGE_AXIS));
setBorder(new EmptyBorder(15, 15, 15, 15)); setBorder(new EmptyBorder(15, 15, 15, 15));
// Set title. // Set title.
JLabel titleLabel = new JLabel("Shortest-Path"); add(createTitleLabel(title));
titleLabel.setBackground(Color.RED);
titleLabel.setHorizontalAlignment(JLabel.LEFT);
titleLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
Font font = titleLabel.getFont();
font = font.deriveFont(Font.BOLD, 18);
titleLabel.setFont(font);
add(titleLabel);
add(Box.createVerticalStrut(8)); add(Box.createVerticalStrut(8));
// Add algorithm selection // Add algorithm selection
JComboBox<String> algoSelect = new JComboBox<>( JComboBox<String> algoSelect = createAlgoritmSelectComboBox(baseAlgorithm);
AlgorithmFactory.getAlgorithmNames(baseAlgorithm).toArray(new String[0])); if (algoSelect.getItemCount() > 1) {
algoSelect.setBackground(Color.WHITE);
algoSelect.setAlignmentX(Component.LEFT_ALIGNMENT);
add(algoSelect); add(algoSelect);
components.add(algoSelect); components.add(algoSelect);
}
// Add inputs for node. // Add inputs for node.
this.nodesInputPanel = new NodesInputPanel(); this.nodesInputPanel = createNodesInputPanel(nodeNames);
this.nodesInputPanel.setAlignmentX(Component.LEFT_ALIGNMENT);
nodesInputPanel.addTextField("Origin: ", new Color(57, 172, 115));
nodesInputPanel.addTextField("Destination: ", new Color(255, 77, 77));
nodesInputPanel.setEnabled(false);
add(this.nodesInputPanel); add(this.nodesInputPanel);
components.add(this.nodesInputPanel); components.add(this.nodesInputPanel);
@ -190,6 +179,7 @@ public class AlgorithmPanel extends JPanel {
c.fill = GridBagConstraints.HORIZONTAL; c.fill = GridBagConstraints.HORIZONTAL;
if (enableModeSelection) {
c.gridx = 0; c.gridx = 0;
c.gridy = 0; c.gridy = 0;
c.weightx = 0; c.weightx = 0;
@ -200,6 +190,7 @@ public class AlgorithmPanel extends JPanel {
c.gridx = 2; c.gridx = 2;
c.weightx = 1; c.weightx = 1;
modeAndObserverPanel.add(timeModeButton, c); modeAndObserverPanel.add(timeModeButton, c);
}
c.gridy = 2; c.gridy = 2;
c.gridx = 0; c.gridx = 0;
@ -212,6 +203,7 @@ public class AlgorithmPanel extends JPanel {
c.weightx = 1; c.weightx = 1;
modeAndObserverPanel.add(textObserver, c); modeAndObserverPanel.add(textObserver, c);
if (enableArcFilterSelection) {
c.gridy = 1; c.gridy = 1;
c.gridx = 0; c.gridx = 0;
c.weightx = 0; c.weightx = 0;
@ -220,6 +212,7 @@ public class AlgorithmPanel extends JPanel {
c.gridwidth = 2; c.gridwidth = 2;
c.weightx = 1; c.weightx = 1;
modeAndObserverPanel.add(arcFilterSelect, c); modeAndObserverPanel.add(arcFilterSelect, c);
}
components.add(timeModeButton); components.add(timeModeButton);
components.add(lengthModeButton); components.add(lengthModeButton);
@ -244,12 +237,12 @@ 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 mode = lengthModeButton.isSelected()
? AbstractInputData.Mode.LENGTH
: AbstractInputData.Mode.TIME; : AbstractInputData.Mode.TIME;
for (ActionListener lis: startActionListeners) { for (ActionListener lis: startActionListeners) {
lis.actionPerformed( lis.actionPerformed(new StartActionEvent(
new StartActionEvent(
AlgorithmFactory.getAlgorithmClass(baseAlgorithm, AlgorithmFactory.getAlgorithmClass(baseAlgorithm,
(String) algoSelect.getSelectedItem()), (String) algoSelect.getSelectedItem()),
nodesInputPanel.getNodeForInputs(), mode, nodesInputPanel.getNodeForInputs(), mode,
@ -306,6 +299,57 @@ public class AlgorithmPanel extends JPanel {
setEnabled(false); setEnabled(false);
} }
/**
* Create the title JLabel for this panel.
*
* @param title Title for the label.
*
* @return
*/
protected JLabel createTitleLabel(String title) {
JLabel titleLabel = new JLabel(title);
titleLabel.setBackground(Color.RED);
titleLabel.setHorizontalAlignment(JLabel.LEFT);
titleLabel.setAlignmentX(Component.LEFT_ALIGNMENT);
Font font = titleLabel.getFont();
font = font.deriveFont(Font.BOLD, 18);
titleLabel.setFont(font);
return titleLabel;
}
/**
* Create the combo box for the algorithm selection.
*
* @return
*/
protected JComboBox<String> createAlgoritmSelectComboBox(
Class<? extends AbstractAlgorithm<?>> baseAlgorithm) {
JComboBox<String> algoSelect = new JComboBox<>(
AlgorithmFactory.getAlgorithmNames(baseAlgorithm).toArray(new String[0]));
algoSelect.setBackground(Color.WHITE);
algoSelect.setAlignmentX(Component.LEFT_ALIGNMENT);
return algoSelect;
}
/**
* Create a node input panel with the given node input names.
*
* @param nodeNames
* @return
*/
protected NodesInputPanel createNodesInputPanel(String[] nodeNames) {
final Color[] nodeColors = { new Color(57, 172, 115), new Color(255, 77, 77),
new Color(77, 77, 255), new Color(77, 255, 77) };
NodesInputPanel panel = new NodesInputPanel();
panel.setAlignmentX(Component.LEFT_ALIGNMENT);
for (int i = 0; i < nodeNames.length; ++i) {
panel.addTextField(nodeNames[i] + ": ", nodeColors[i % nodeColors.length]);
}
panel.setEnabled(false);
return panel;
}
protected boolean allNotNull(List<Node> nodes) { protected boolean allNotNull(List<Node> nodes) {
boolean allNotNull = true; boolean allNotNull = true;
for (Node node: nodes) { for (Node node: nodes) {

View File

@ -42,6 +42,7 @@ import javax.swing.border.CompoundBorder;
import javax.swing.border.EmptyBorder; import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import org.insa.algo.AbstractSolution;
import org.insa.algo.AlgorithmFactory; import org.insa.algo.AlgorithmFactory;
import org.insa.algo.shortestpath.ShortestPathAlgorithm; import org.insa.algo.shortestpath.ShortestPathAlgorithm;
import org.insa.algo.shortestpath.ShortestPathData; import org.insa.algo.shortestpath.ShortestPathData;
@ -100,20 +101,21 @@ public class MainWindow extends JFrame {
// Drawing and click adapter. // Drawing and click adapter.
protected Drawing drawing; protected Drawing drawing;
private MapViewDrawing mapViewDrawing; private final MapViewDrawing mapViewDrawing;
private BasicDrawing basicDrawing; private final BasicDrawing basicDrawing;
// Main panel. // Main panel.
private JSplitPane mainPanel; private final JSplitPane mainPanel;
// Algorithm panel // Algorithm panels
private AlgorithmPanel spPanel; private final List<AlgorithmPanel> algoPanels = new ArrayList<>();
private final AlgorithmPanel wccPanel, spPanel;
// Path panel // Path panel
private PathsPanel pathPanel; private final 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 final ArrayList<JMenuItem> graphLockItems = new ArrayList<JMenuItem>();
// Label containing the map ID of the current graph. // Label containing the map ID of the current graph.
private JLabel graphInfoPanel; private JLabel graphInfoPanel;
@ -151,7 +153,43 @@ public class MainWindow extends JFrame {
this.drawing = this.basicDrawing; this.drawing = this.basicDrawing;
spPanel = new AlgorithmPanel(this, ShortestPathAlgorithm.class); wccPanel = new AlgorithmPanel(this, WeaklyConnectedComponentsAlgorithm.class,
"Weakly-Connected Components", new String[] {}, false, false);
wccPanel.addStartActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
StartActionEvent evt = (StartActionEvent) e;
WeaklyConnectedComponentsData data = new WeaklyConnectedComponentsData(graph);
WeaklyConnectedComponentsAlgorithm wccAlgorithm = null;
try {
wccAlgorithm = (WeaklyConnectedComponentsAlgorithm) AlgorithmFactory
.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);
e1.printStackTrace();
return;
}
wccPanel.setEnabled(false);
if (evt.isGraphicVisualizationEnabled()) {
wccAlgorithm.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing));
}
if (evt.isTextualVisualizationEnabled()) {
wccAlgorithm.addObserver(new WeaklyConnectedComponentTextObserver(printStream));
}
launchWeaklyConnectedComponentsThread(wccAlgorithm);
}
});
spPanel = new AlgorithmPanel(this, ShortestPathAlgorithm.class, "Shortest-Path",
new String[] { "Origin", "Destination" }, true, true);
spPanel.addStartActionListener(new ActionListener() { spPanel.addStartActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
@ -185,7 +223,10 @@ public class MainWindow extends JFrame {
launchShortestPathThread(spAlgorithm); launchShortestPathThread(spAlgorithm);
} }
}); });
spPanel.setVisible(false);
// add algorithm panels
algoPanels.add(wccPanel);
algoPanels.add(spPanel);
this.pathPanel = new PathsPanel(this); this.pathPanel = new PathsPanel(this);
@ -242,7 +283,10 @@ public class MainWindow extends JFrame {
rightComponent.add(pathPanel, c); rightComponent.add(pathPanel, c);
c.gridy = 1; c.gridy = 1;
rightComponent.add(spPanel, c); for (AlgorithmPanel panel: algoPanels) {
panel.setVisible(false);
rightComponent.add(panel, c);
}
c = new GridBagConstraints(); c = new GridBagConstraints();
c.gridx = 0; c.gridx = 0;
@ -312,6 +356,19 @@ public class MainWindow extends JFrame {
spPanel.solutionPanel.setVisible(true); spPanel.solutionPanel.setVisible(true);
} }
private void launchWeaklyConnectedComponentsThread(
WeaklyConnectedComponentsAlgorithm wccAlgorithm) {
launchThread(new Runnable() {
@Override
public void run() {
AbstractSolution solution = wccAlgorithm.run();
wccPanel.solutionPanel.addSolution(solution, false);
wccPanel.solutionPanel.setVisible(true);
wccPanel.setEnabled(true);
}
});
}
private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) { private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) {
launchThread(new Runnable() { launchThread(new Runnable() {
@Override @Override
@ -475,6 +532,19 @@ public class MainWindow extends JFrame {
}, false); }, false);
} }
/**
* Show and enable the given AlgorithmPanel (and hide all others).
*
* @param algorithmPanel
*/
private void enableAlgorithmPanel(AlgorithmPanel algorithmPanel) {
int dividerLocation = mainPanel.getDividerLocation();
for (AlgorithmPanel panel: algoPanels) {
panel.setVisible(panel == algorithmPanel);
}
mainPanel.setDividerLocation(dividerLocation);
}
private JMenuBar createMenuBar() { private JMenuBar createMenuBar() {
// Open Map item... // Open Map item...
@ -648,16 +718,7 @@ public class MainWindow extends JFrame {
wccItem.addActionListener(baf.createBlockingAction(new ActionListener() { wccItem.addActionListener(baf.createBlockingAction(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm( enableAlgorithmPanel(wccPanel);
new WeaklyConnectedComponentsData(graph));
algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing));
algo.addObserver(new WeaklyConnectedComponentTextObserver(printStream));
launchThread(new Runnable() {
@Override
public void run() {
algo.run();
}
});
} }
})); }));
@ -666,9 +727,7 @@ public class MainWindow extends JFrame {
spItem.addActionListener(baf.createBlockingAction(new ActionListener() { spItem.addActionListener(baf.createBlockingAction(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
int dividerLocation = mainPanel.getDividerLocation(); enableAlgorithmPanel(spPanel);
spPanel.setVisible(true);
mainPanel.setDividerLocation(dividerLocation);
} }
})); }));
graphLockItems.add(wccItem); graphLockItems.add(wccItem);