Fix output stream in textarea. Add blocking actions.
This commit is contained in:
parent
0514c627b4
commit
ca94ddf7ff
7 changed files with 315 additions and 119 deletions
58
src/main/org/insa/graphics/BlockingActionFactory.java
Normal file
58
src/main/org/insa/graphics/BlockingActionFactory.java
Normal file
|
@ -0,0 +1,58 @@
|
|||
package org.insa.graphics;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.JOptionPane;
|
||||
|
||||
public class BlockingActionFactory {
|
||||
|
||||
// List of running actions.
|
||||
private ArrayList<RunningAction> actions = new ArrayList<>();
|
||||
|
||||
// Parent component.
|
||||
private Component parentComponent;
|
||||
|
||||
public BlockingActionFactory(Component parentComponent) {
|
||||
this.parentComponent = parentComponent;
|
||||
}
|
||||
|
||||
public void addAction(RunningAction action) {
|
||||
actions.add(action);
|
||||
}
|
||||
|
||||
public ActionListener createBlockingAction(ActionListener listener) {
|
||||
return new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
boolean accepted = true;
|
||||
|
||||
// Check if actions...
|
||||
for (int i = 0; i < actions.size() && accepted; ++i) {
|
||||
RunningAction action = actions.get(i);
|
||||
// If action is running, ask user...
|
||||
if (action.isRunning()) {
|
||||
System.out.println("Action " + action.getInformation() + " is running... ");
|
||||
if (JOptionPane.showConfirmDialog(parentComponent, "Action {" + action.getInformation()
|
||||
+ "} is running, do you want to stop it?") == JOptionPane.OK_OPTION) {
|
||||
System.out.println("Action " + action.getInformation() + " has been interrupted.");
|
||||
action.interrupt();
|
||||
}
|
||||
else {
|
||||
System.out.println("Action " + action.getInformation() + " not interrupted... ");
|
||||
accepted = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If action is accepted, run it...
|
||||
if (accepted) {
|
||||
listener.actionPerformed(e);
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -1,14 +0,0 @@
|
|||
package org.insa.graphics;
|
||||
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
|
||||
public abstract class BlockingActionListener implements ActionListener {
|
||||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
this.actionAccepted(e);
|
||||
}
|
||||
|
||||
public abstract void actionAccepted(ActionEvent e);
|
||||
}
|
|
@ -12,10 +12,7 @@ import java.awt.event.WindowEvent;
|
|||
import java.io.DataInputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
|
@ -44,17 +41,19 @@ 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;
|
||||
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentTextObserver;
|
||||
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm;
|
||||
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsData;
|
||||
import org.insa.graph.Graph;
|
||||
import org.insa.graph.Node;
|
||||
import org.insa.graph.Path;
|
||||
import org.insa.graph.io.GraphReader;
|
||||
import org.insa.graph.io.BinaryGraphReader;
|
||||
import org.insa.graph.io.BinaryGraphReaderV2;
|
||||
import org.insa.graph.io.BinaryPathReader;
|
||||
import org.insa.graph.io.GraphReader;
|
||||
import org.insa.graph.io.MapMismatchException;
|
||||
import org.insa.graph.io.Openfile;
|
||||
import org.insa.graphics.MultiPointsClickListener.CallableWithNodes;
|
||||
import org.insa.graphics.drawing.BasicDrawing;
|
||||
import org.insa.graphics.drawing.BlackAndWhiteGraphPalette;
|
||||
import org.insa.graphics.drawing.Drawing;
|
||||
|
@ -62,30 +61,6 @@ import org.insa.graphics.drawing.MapViewDrawing;
|
|||
|
||||
public class MainWindow extends JFrame {
|
||||
|
||||
protected class JOutputStream extends OutputStream {
|
||||
private JTextArea textArea;
|
||||
|
||||
public JOutputStream(JTextArea textArea) {
|
||||
this.textArea = textArea;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
// redirects data to the text area
|
||||
textArea.setText(textArea.getText() + String.valueOf((char) b));
|
||||
// scrolls the text area to the end of data
|
||||
textArea.setCaretPosition(textArea.getDocument().getLength());
|
||||
// keeps the textArea up to date
|
||||
textArea.update(textArea.getGraphics());
|
||||
}
|
||||
}
|
||||
|
||||
protected interface CallableWithNodes {
|
||||
|
||||
void call(ArrayList<Node> nodes);
|
||||
|
||||
};
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
|
@ -102,14 +77,13 @@ public class MainWindow extends JFrame {
|
|||
private static final int THREAD_TIMER_DELAY = 1000; // in milliseconds
|
||||
|
||||
// Current graph.
|
||||
private Graph graph;
|
||||
protected Graph graph;
|
||||
|
||||
// Current loaded path.
|
||||
private Path currentPath;
|
||||
// private Path currentPath;
|
||||
|
||||
// Drawing and click adapter.
|
||||
private Drawing drawing;
|
||||
private MultiPointsClickListener clickAdapter = null;
|
||||
protected Drawing drawing;
|
||||
|
||||
// Main panel.
|
||||
private JSplitPane mainPanel;
|
||||
|
@ -124,23 +98,41 @@ public class MainWindow extends JFrame {
|
|||
private JLabel mapIdPanel;
|
||||
|
||||
// Thread information
|
||||
private Instant threadStartTime;
|
||||
private Timer threadTimer;
|
||||
private JPanel threadPanel;
|
||||
|
||||
// Log stream and print stream
|
||||
private JOutputStream logStream;
|
||||
private StreamCapturer logStream;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
private PrintStream printStream;
|
||||
|
||||
// Current running thread
|
||||
private Thread currentThread;
|
||||
private ThreadWrapper currentThread;
|
||||
|
||||
// Multi point listener
|
||||
private MultiPointsClickListener clickAdapter = null;
|
||||
|
||||
// Factory
|
||||
private BlockingActionFactory baf;
|
||||
|
||||
public MainWindow() {
|
||||
super(WINDOW_TITLE);
|
||||
|
||||
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
|
||||
setLayout(new BorderLayout());
|
||||
|
||||
// Create drawing and action listeners...
|
||||
this.drawing = new BasicDrawing();
|
||||
|
||||
this.clickAdapter = new MultiPointsClickListener(this);
|
||||
this.currentThread = new ThreadWrapper(this);
|
||||
this.baf = new BlockingActionFactory(this);
|
||||
this.baf.addAction(clickAdapter);
|
||||
this.baf.addAction(currentThread);
|
||||
|
||||
// Click adapter
|
||||
addDrawingClickListeners();
|
||||
setJMenuBar(createMenuBar());
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
|
@ -158,21 +150,15 @@ public class MainWindow extends JFrame {
|
|||
// Create graph area
|
||||
mainPanel = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
|
||||
|
||||
this.drawing = new BasicDrawing();
|
||||
|
||||
// Click adapter
|
||||
addDrawingClickListeners();
|
||||
|
||||
JTextArea infoPanel = new JTextArea();
|
||||
infoPanel.setMinimumSize(new Dimension(200, 50));
|
||||
infoPanel.setBackground(Color.WHITE);
|
||||
infoPanel.setLineWrap(true);
|
||||
infoPanel.setEditable(false);
|
||||
this.logStream = new JOutputStream(infoPanel);
|
||||
this.logStream = new StreamCapturer(infoPanel);
|
||||
this.printStream = new PrintStream(this.logStream);
|
||||
|
||||
mainPanel.setResizeWeight(0.8);
|
||||
// sp.setEnabled(false);
|
||||
mainPanel.setDividerSize(5);
|
||||
|
||||
mainPanel.setBackground(Color.WHITE);
|
||||
|
@ -183,10 +169,10 @@ public class MainWindow extends JFrame {
|
|||
// Top Panel
|
||||
this.add(createTopPanel(), BorderLayout.NORTH);
|
||||
this.add(createStatusBar(), BorderLayout.SOUTH);
|
||||
|
||||
}
|
||||
|
||||
private void restartThreadTimer() {
|
||||
threadStartTime = Instant.now();
|
||||
threadTimer.restart();
|
||||
}
|
||||
|
||||
|
@ -200,7 +186,7 @@ public class MainWindow extends JFrame {
|
|||
*/
|
||||
private void launchThread(Runnable runnable, boolean canInterrupt) {
|
||||
if (canInterrupt) {
|
||||
currentThread = new Thread(new Runnable() {
|
||||
currentThread.setThread(new Thread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
restartThreadTimer();
|
||||
|
@ -208,22 +194,22 @@ public class MainWindow extends JFrame {
|
|||
runnable.run();
|
||||
clearCurrentThread();
|
||||
}
|
||||
});
|
||||
}));
|
||||
}
|
||||
else {
|
||||
currentThread = new Thread(runnable);
|
||||
currentThread.setThread(new Thread(runnable));
|
||||
}
|
||||
currentThread.start();
|
||||
currentThread.startThread();
|
||||
}
|
||||
|
||||
private void launchThread(Runnable runnable) {
|
||||
launchThread(runnable, true);
|
||||
}
|
||||
|
||||
private void clearCurrentThread() {
|
||||
protected void clearCurrentThread() {
|
||||
stopThreadTimer();
|
||||
threadPanel.setVisible(false);
|
||||
currentThread = null;
|
||||
currentThread.setThread(null);
|
||||
}
|
||||
|
||||
private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) {
|
||||
|
@ -241,7 +227,6 @@ public class MainWindow extends JFrame {
|
|||
}
|
||||
|
||||
private void addDrawingClickListeners() {
|
||||
this.clickAdapter = new MultiPointsClickListener(graph, drawing);
|
||||
drawing.addDrawingClickListener(this.clickAdapter);
|
||||
}
|
||||
|
||||
|
@ -265,9 +250,9 @@ public class MainWindow extends JFrame {
|
|||
// Open Map item...
|
||||
openMapItem = new JMenuItem("Open Map... ", KeyEvent.VK_O);
|
||||
openMapItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, ActionEvent.ALT_MASK));
|
||||
openMapItem.addActionListener(new BlockingActionListener() {
|
||||
openMapItem.addActionListener(baf.createBlockingAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter("Map & compressed map files", "map",
|
||||
"map2", "mapgr", "map.gz");
|
||||
|
@ -313,14 +298,14 @@ public class MainWindow extends JFrame {
|
|||
}, false);
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
// Open Path item...
|
||||
JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P);
|
||||
openPathItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_P, ActionEvent.ALT_MASK));
|
||||
openPathItem.addActionListener(new BlockingActionListener() {
|
||||
openPathItem.addActionListener(baf.createBlockingAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
JFileChooser chooser = new JFileChooser();
|
||||
FileNameExtensionFilter filter = new FileNameExtensionFilter("Path & compressed path files", "path",
|
||||
"path.gz");
|
||||
|
@ -336,7 +321,8 @@ public class MainWindow extends JFrame {
|
|||
return;
|
||||
}
|
||||
try {
|
||||
currentPath = reader.readPath(graph);
|
||||
Path path = reader.readPath(graph);
|
||||
drawing.drawPath(path);
|
||||
}
|
||||
catch (MapMismatchException exception) {
|
||||
JOptionPane.showMessageDialog(MainWindow.this,
|
||||
|
@ -347,18 +333,17 @@ public class MainWindow extends JFrame {
|
|||
JOptionPane.showMessageDialog(MainWindow.this, "Unable to read path from the selected file.");
|
||||
return;
|
||||
}
|
||||
drawing.drawPath(currentPath);
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
graphLockItems.add(openPathItem);
|
||||
|
||||
// Close item
|
||||
JMenuItem closeItem = new JMenuItem("Quit", KeyEvent.VK_Q);
|
||||
closeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_Q, ActionEvent.ALT_MASK));
|
||||
closeItem.addActionListener(new BlockingActionListener() {
|
||||
closeItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
MainWindow.this.dispatchEvent(new WindowEvent(MainWindow.this, WindowEvent.WINDOW_CLOSING));
|
||||
}
|
||||
});
|
||||
|
@ -373,9 +358,9 @@ public class MainWindow extends JFrame {
|
|||
// Second menu
|
||||
JMenuItem drawGraphItem = new JMenuItem("Redraw", KeyEvent.VK_R);
|
||||
drawGraphItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_R, ActionEvent.ALT_MASK));
|
||||
drawGraphItem.addActionListener(new BlockingActionListener() {
|
||||
drawGraphItem.addActionListener(baf.createBlockingAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
launchThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -384,13 +369,13 @@ public class MainWindow extends JFrame {
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
graphLockItems.add(drawGraphItem);
|
||||
JMenuItem drawGraphBWItem = new JMenuItem("Redraw (B&W)", KeyEvent.VK_B);
|
||||
drawGraphBWItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, ActionEvent.ALT_MASK));
|
||||
drawGraphBWItem.addActionListener(new BlockingActionListener() {
|
||||
drawGraphBWItem.addActionListener(baf.createBlockingAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
launchThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -399,13 +384,13 @@ public class MainWindow extends JFrame {
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
graphLockItems.add(drawGraphBWItem);
|
||||
JMenuItem drawGraphMapsforgeItem = new JMenuItem("Redraw (Map)", KeyEvent.VK_M);
|
||||
drawGraphMapsforgeItem.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_M, ActionEvent.ALT_MASK));
|
||||
drawGraphMapsforgeItem.addActionListener(new BlockingActionListener() {
|
||||
drawGraphMapsforgeItem.addActionListener(baf.createBlockingAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
launchThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -414,7 +399,7 @@ public class MainWindow extends JFrame {
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
graphLockItems.add(drawGraphMapsforgeItem);
|
||||
|
||||
JMenu graphMenu = new JMenu("Graph");
|
||||
|
@ -428,13 +413,13 @@ public class MainWindow extends JFrame {
|
|||
|
||||
// Weakly connected components
|
||||
JMenuItem wccItem = new JMenuItem("Weakly Connected Components");
|
||||
wccItem.addActionListener(new BlockingActionListener() {
|
||||
wccItem.addActionListener(baf.createBlockingAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
WeaklyConnectedComponentsData instance = new WeaklyConnectedComponentsData(graph);
|
||||
WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm(instance);
|
||||
algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing));
|
||||
// algo.addObserver(new WeaklyConnectedComponentTextObserver(printStream));
|
||||
algo.addObserver(new WeaklyConnectedComponentTextObserver(printStream));
|
||||
launchThread(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
|
@ -442,13 +427,13 @@ public class MainWindow extends JFrame {
|
|||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
}));
|
||||
|
||||
// Shortest path
|
||||
JMenuItem bellmanItem = new JMenuItem("Shortest Path (Bellman-Ford)");
|
||||
bellmanItem.addActionListener(new BlockingActionListener() {
|
||||
bellmanItem.addActionListener(baf.createBlockingAction(new ActionListener() {
|
||||
@Override
|
||||
public void actionAccepted(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
int idx = JOptionPane.showOptionDialog(MainWindow.this, "Which mode do you want?", "Mode selection",
|
||||
JOptionPane.DEFAULT_OPTION, JOptionPane.QUESTION_MESSAGE, null, Mode.values(), Mode.LENGTH);
|
||||
|
||||
|
@ -463,7 +448,7 @@ public class MainWindow extends JFrame {
|
|||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}));
|
||||
graphLockItems.add(wccItem);
|
||||
graphLockItems.add(bellmanItem);
|
||||
|
||||
|
@ -487,14 +472,6 @@ public class MainWindow extends JFrame {
|
|||
return menuBar;
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private void stopCurrentThread() {
|
||||
// Should not be used in production code, but here I have no idea how
|
||||
// to do this properly... Cannot use .interrupt() because it would requires
|
||||
// the algorithm to watch the ThreadInteruption exception.
|
||||
currentThread.stop();
|
||||
}
|
||||
|
||||
private JPanel createStatusBar() {
|
||||
// create the status bar panel and shove it down the bottom of the frame
|
||||
JPanel statusPanel = new JPanel();
|
||||
|
@ -513,14 +490,12 @@ public class MainWindow extends JFrame {
|
|||
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
if (currentThread != null && currentThread.isAlive()) {
|
||||
if (currentThread.isRunning()) {
|
||||
int confirmed = JOptionPane.showConfirmDialog(null,
|
||||
"Are you sure you want to kill the running thread?", "Kill Confirmation",
|
||||
JOptionPane.YES_NO_OPTION);
|
||||
if (confirmed == JOptionPane.YES_OPTION) {
|
||||
stopCurrentThread();
|
||||
clearCurrentThread();
|
||||
threadPanel.setVisible(false);
|
||||
currentThread.interrupt();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -529,8 +504,7 @@ public class MainWindow extends JFrame {
|
|||
threadTimer = new Timer(THREAD_TIMER_DELAY, new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
Duration elapsed = Duration.between(threadStartTime, Instant.now());
|
||||
long seconds = elapsed.getSeconds();
|
||||
long seconds = currentThread.getDuration().getSeconds();
|
||||
threadTimerLabel
|
||||
.setText(String.format("%02d:%02d:%02d", seconds / 3600, seconds / 60 % 60, seconds % 60));
|
||||
}
|
||||
|
|
|
@ -1,16 +1,26 @@
|
|||
package org.insa.graphics;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import org.insa.graph.Graph;
|
||||
import org.insa.graph.Node;
|
||||
import org.insa.graph.Point;
|
||||
import org.insa.graphics.MainWindow.CallableWithNodes;
|
||||
import org.insa.graphics.drawing.Drawing;
|
||||
import org.insa.graphics.drawing.DrawingClickListener;
|
||||
|
||||
public class MultiPointsClickListener implements DrawingClickListener {
|
||||
public class MultiPointsClickListener implements DrawingClickListener, RunningAction {
|
||||
|
||||
protected interface CallableWithNodes {
|
||||
|
||||
/**
|
||||
* Function called when the given number of nodes is reached.
|
||||
*
|
||||
* @param nodes
|
||||
*/
|
||||
void call(ArrayList<Node> nodes);
|
||||
|
||||
};
|
||||
|
||||
// Enable/Disable.
|
||||
private boolean enabled = false;
|
||||
|
@ -18,6 +28,9 @@ public class MultiPointsClickListener implements DrawingClickListener {
|
|||
// List of points.
|
||||
private ArrayList<Node> points = new ArrayList<Node>();
|
||||
|
||||
// Starting time
|
||||
private Instant startTime;
|
||||
|
||||
// Number of points to find before running.
|
||||
private int nTargetPoints = 0;
|
||||
|
||||
|
@ -25,14 +38,10 @@ public class MultiPointsClickListener implements DrawingClickListener {
|
|||
CallableWithNodes callable = null;
|
||||
|
||||
// Graph
|
||||
private final Graph graph;
|
||||
private final MainWindow mainWindow;
|
||||
|
||||
// Drawing
|
||||
private final Drawing drawing;
|
||||
|
||||
public MultiPointsClickListener(Graph graph, Drawing drawing) {
|
||||
this.graph = graph;
|
||||
this.drawing = drawing;
|
||||
public MultiPointsClickListener(MainWindow mainWindow) {
|
||||
this.mainWindow = mainWindow;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -45,14 +54,14 @@ public class MultiPointsClickListener implements DrawingClickListener {
|
|||
/**
|
||||
* Enable this listener.
|
||||
*
|
||||
* @param nTargetPoints
|
||||
* Number of point to found before calling the callable.
|
||||
* @param nTargetPoints Number of point to found before calling the callable.
|
||||
*/
|
||||
public void enable(int nTargetPoints, CallableWithNodes callable) {
|
||||
this.enabled = true;
|
||||
this.nTargetPoints = nTargetPoints;
|
||||
this.points.clear();
|
||||
this.callable = callable;
|
||||
this.startTime = Instant.now();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -67,8 +76,8 @@ public class MultiPointsClickListener implements DrawingClickListener {
|
|||
if (!isEnabled()) {
|
||||
return;
|
||||
}
|
||||
Node node = graph.findClosestNode(lonlat);
|
||||
drawing.drawMarker(node.getPoint(), Color.BLUE);
|
||||
Node node = mainWindow.graph.findClosestNode(lonlat);
|
||||
mainWindow.drawing.drawMarker(node.getPoint(), Color.BLUE);
|
||||
points.add(node);
|
||||
if (points.size() == nTargetPoints) {
|
||||
callable.call(points);
|
||||
|
@ -76,4 +85,29 @@ public class MultiPointsClickListener implements DrawingClickListener {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return isEnabled();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void interrupt() {
|
||||
disable();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getStartingTime() {
|
||||
return startTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getDuration() {
|
||||
return Duration.between(getStartingTime(), Instant.now());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInformation() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
33
src/main/org/insa/graphics/RunningAction.java
Normal file
33
src/main/org/insa/graphics/RunningAction.java
Normal file
|
@ -0,0 +1,33 @@
|
|||
package org.insa.graphics;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
public interface RunningAction {
|
||||
|
||||
/**
|
||||
* @return true if this action is running.
|
||||
*/
|
||||
public boolean isRunning();
|
||||
|
||||
/**
|
||||
* Interrupt this action.
|
||||
*/
|
||||
public void interrupt();
|
||||
|
||||
/**
|
||||
* @return Starting time of this action.
|
||||
*/
|
||||
public Instant getStartingTime();
|
||||
|
||||
/**
|
||||
* @return Current duration of this action.
|
||||
*/
|
||||
public Duration getDuration();
|
||||
|
||||
/**
|
||||
* @return Information for this action.
|
||||
*/
|
||||
public String getInformation();
|
||||
|
||||
}
|
49
src/main/org/insa/graphics/StreamCapturer.java
Normal file
49
src/main/org/insa/graphics/StreamCapturer.java
Normal file
|
@ -0,0 +1,49 @@
|
|||
package org.insa.graphics;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
|
||||
import javax.swing.JTextArea;
|
||||
|
||||
public class StreamCapturer extends OutputStream {
|
||||
|
||||
private StringBuilder buffer;
|
||||
private String prefix = null;
|
||||
private JTextArea output;
|
||||
|
||||
/**
|
||||
* @param prefix
|
||||
* @param output
|
||||
*/
|
||||
public StreamCapturer(JTextArea output, String prefix) {
|
||||
this.prefix = prefix;
|
||||
buffer = new StringBuilder(128);
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
public StreamCapturer(JTextArea output) {
|
||||
this(output, null);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void write(int b) throws IOException {
|
||||
char c = (char) b;
|
||||
String value = Character.toString(c);
|
||||
buffer.append(value);
|
||||
if (value.equals("\n")) {
|
||||
output.append(getPrefix() + buffer.toString());
|
||||
output.setCaretPosition(output.getText().length());
|
||||
buffer.delete(0, buffer.length());
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return Formatted prefix, or empty string if no prefix is set.
|
||||
*/
|
||||
public String getPrefix() {
|
||||
if (this.prefix == null) {
|
||||
return "";
|
||||
}
|
||||
return "[" + prefix + "] ";
|
||||
}
|
||||
}
|
62
src/main/org/insa/graphics/ThreadWrapper.java
Normal file
62
src/main/org/insa/graphics/ThreadWrapper.java
Normal file
|
@ -0,0 +1,62 @@
|
|||
package org.insa.graphics;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
|
||||
public class ThreadWrapper implements RunningAction {
|
||||
|
||||
// Thread hold by this wrapper.
|
||||
private Thread thread;
|
||||
|
||||
// Starting time of the thread.
|
||||
Instant startingTime;
|
||||
|
||||
// MainWindow
|
||||
private MainWindow mainWindow;
|
||||
|
||||
public ThreadWrapper(MainWindow mainWindow) {
|
||||
this.thread = null;
|
||||
this.mainWindow = mainWindow;
|
||||
}
|
||||
|
||||
public void setThread(Thread thread) {
|
||||
this.thread = thread;
|
||||
}
|
||||
|
||||
public void startThread() {
|
||||
this.startingTime = Instant.now();
|
||||
this.thread.start();
|
||||
}
|
||||
|
||||
public Thread getThread() {
|
||||
return this.thread;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isRunning() {
|
||||
return thread != null && thread.isAlive();
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@Override
|
||||
public void interrupt() {
|
||||
thread.stop();
|
||||
this.mainWindow.clearCurrentThread();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Instant getStartingTime() {
|
||||
return startingTime;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Duration getDuration() {
|
||||
return Duration.between(getStartingTime(), Instant.now());
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getInformation() {
|
||||
return getClass().getName();
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in a new issue