This commit is contained in:
Holt59 2018-02-18 23:08:02 +01:00
parent cfb59ac0f1
commit eceaecd813
5 changed files with 406 additions and 196 deletions

View File

@ -1,23 +1,42 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<classpath> <classpath>
<classpathentry kind="src" path="src/main"/> <classpathentry kind="src" output="target/classes" path="src/main">
<classpathentry kind="src" path="src/test"/> <attributes>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> <attribute name="optional" value="true"/>
<classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/> <attribute name="maven.pomderived" value="true"/>
<classpathentry kind="lib" path="libs/piccolo2d-core-3.0.jar"> </attributes>
<attributes> </classpathentry>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-core-3.0-javadoc.jar!/"/> <classpathentry kind="src" output="target/test-classes" path="src/test">
</attributes> <attributes>
</classpathentry> <attribute name="optional" value="true"/>
<classpathentry kind="lib" path="libs/piccolo2d-extras-3.0.jar"> <attribute name="maven.pomderived" value="true"/>
<attributes> </attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-extras-3.0-javadoc.jar!/"/> </classpathentry>
</attributes> <classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8">
</classpathentry> <attributes>
<classpathentry kind="lib" path="libs/piccolo2d-swt-3.0.jar"> <attribute name="maven.pomderived" value="true"/>
<attributes> </attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-swt-3.0-javadoc.jar!/"/> </classpathentry>
</attributes> <classpathentry kind="con" path="org.eclipse.jdt.junit.JUNIT_CONTAINER/5"/>
</classpathentry> <classpathentry kind="lib" path="libs/piccolo2d-core-3.0.jar">
<classpathentry kind="output" path="bin"/> <attributes>
</classpath> <attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-core-3.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/piccolo2d-extras-3.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-extras-3.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="lib" path="libs/piccolo2d-swt-3.0.jar">
<attributes>
<attribute name="javadoc_location" value="jar:platform:/resource/be-graphes-base/libs/piccolo2d-swt-3.0-javadoc.jar!/"/>
</attributes>
</classpathentry>
<classpathentry kind="con" path="org.eclipse.m2e.MAVEN2_CLASSPATH_CONTAINER">
<attributes>
<attribute name="maven.pomderived" value="true"/>
</attributes>
</classpathentry>
<classpathentry kind="output" path="target/classes"/>
</classpath>

1
.gitignore vendored
View File

@ -1,2 +1,3 @@
.DS_Store .DS_Store
bin bin
/target/

View File

@ -10,8 +10,14 @@
<arguments> <arguments>
</arguments> </arguments>
</buildCommand> </buildCommand>
<buildCommand>
<name>org.eclipse.m2e.core.maven2Builder</name>
<arguments>
</arguments>
</buildCommand>
</buildSpec> </buildSpec>
<natures> <natures>
<nature>org.eclipse.m2e.core.maven2Nature</nature>
<nature>org.eclipse.jdt.core.javanature</nature> <nature>org.eclipse.jdt.core.javanature</nature>
</natures> </natures>
</projectDescription> </projectDescription>

View File

@ -11,10 +11,12 @@ import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.io.OutputStream; import java.io.OutputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.util.ArrayList; import java.util.ArrayList;
import javax.swing.BorderFactory; import javax.swing.BorderFactory;
import javax.swing.BoxLayout; import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JFileChooser; import javax.swing.JFileChooser;
import javax.swing.JFrame; import javax.swing.JFrame;
import javax.swing.JLabel; import javax.swing.JLabel;
@ -28,13 +30,21 @@ import javax.swing.JSplitPane;
import javax.swing.JTextArea; import javax.swing.JTextArea;
import javax.swing.KeyStroke; import javax.swing.KeyStroke;
import javax.swing.SwingConstants; import javax.swing.SwingConstants;
import javax.swing.UIManager;
import javax.swing.filechooser.FileNameExtensionFilter; import javax.swing.filechooser.FileNameExtensionFilter;
import org.insa.algo.AbstractSolution;
import org.insa.algo.shortestpath.BellmanFordAlgorithm;
import org.insa.algo.shortestpath.ShortestPathAlgorithm;
import org.insa.algo.shortestpath.ShortestPathGraphicObserver;
import org.insa.algo.shortestpath.ShortestPathInstance;
import org.insa.algo.shortestpath.ShortestPathInstance.Mode;
import org.insa.algo.shortestpath.ShortestPathSolution;
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver; import org.insa.algo.weakconnectivity.WeaklyConnectedComponentGraphicObserver;
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentTextObserver; import org.insa.algo.weakconnectivity.WeaklyConnectedComponentTextObserver;
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm; import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsAlgorithm;
import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsInstance; import org.insa.algo.weakconnectivity.WeaklyConnectedComponentsInstance;
import org.insa.drawing.DrawingVisible; import org.insa.drawing.Drawing;
import org.insa.drawing.graph.BlackAndWhiteGraphPalette; import org.insa.drawing.graph.BlackAndWhiteGraphPalette;
import org.insa.drawing.graph.GraphDrawing; import org.insa.drawing.graph.GraphDrawing;
import org.insa.drawing.graph.PathDrawing; import org.insa.drawing.graph.PathDrawing;
@ -48,71 +58,76 @@ import org.insa.graph.io.Openfile;
import com.sun.glass.events.KeyEvent; import com.sun.glass.events.KeyEvent;
public class MainWindow extends JFrame { public class MainWindow extends JFrame {
public class JOutputStream extends OutputStream { public class JOutputStream extends OutputStream {
private JTextArea textArea; private JTextArea textArea;
public JOutputStream(JTextArea textArea) { public JOutputStream(JTextArea textArea) {
this.textArea = textArea; this.textArea = textArea;
} }
@Override @Override
public void write(int b) throws IOException { public void write(int b) throws IOException {
// redirects data to the text area // redirects data to the text area
textArea.setText(textArea.getText() + String.valueOf((char)b)); textArea.setText(textArea.getText() + String.valueOf((char)b));
// scrolls the text area to the end of data // scrolls the text area to the end of data
textArea.setCaretPosition(textArea.getDocument().getLength()); textArea.setCaretPosition(textArea.getDocument().getLength());
// keeps the textArea up to date // keeps the textArea up to date
textArea.update(textArea.getGraphics()); textArea.update(textArea.getGraphics());
} }
} }
/** /**
* *
*/ */
private static final long serialVersionUID = -527660583705140687L; private static final long serialVersionUID = -527660583705140687L;
/** /**
* *
*/ */
private static final String WINDOW_TITLE = "BE Graphes INSA"; private static final String WINDOW_TITLE = "BE Graphes INSA";
/** /**
* *
*/ */
private static final Dimension DEFAULT_DIMENSION = new Dimension(800, 600); private static final Dimension DEFAULT_DIMENSION = new Dimension(800, 600);
// Current graph. // Current graph.
private Graph graph; private Graph graph;
// Current loaded path. // Current loaded path.
private Path currentPath; private Path currentPath;
// List of item for the top menus. // List of item for the top menus.
private JMenuItem openMapItem; private JMenuItem openMapItem;
// List of items that cannot be used without a graph // List of items that cannot be used without a graph
private ArrayList<JMenuItem> graphItems = new ArrayList<JMenuItem>(); private ArrayList<JMenuItem> graphItems = new ArrayList<JMenuItem>();
// Label containing the map ID of the current graph. // Label containing the map ID of the current graph.
private JLabel mapIdPanel; private JLabel mapIdPanel;
private JPanel threadPanel;
// Log stream and print stream // Log stream and print stream
private JOutputStream logStream; private JOutputStream logStream;
private PrintStream printStream; private PrintStream printStream;
// Current running thread
private Thread currentThread;
/** /**
* *
*/ */
private DrawingVisible drawing; private Drawing drawing;
public MainWindow() { public MainWindow() {
super(WINDOW_TITLE); super(WINDOW_TITLE);
setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE); setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
setLayout(new BorderLayout()); setLayout(new BorderLayout());
setSize(DEFAULT_DIMENSION); setSize(DEFAULT_DIMENSION);
setJMenuBar(createMenuBar()); setJMenuBar(createMenuBar());
addWindowListener(new WindowAdapter() { addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent e) { public void windowClosing(WindowEvent e) {
int confirmed = JOptionPane.showConfirmDialog(null, int confirmed = JOptionPane.showConfirmDialog(null,
@ -125,13 +140,13 @@ public class MainWindow extends JFrame {
} }
} }
}); });
// Create graph area // Create graph area
JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); JSplitPane sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
drawing = new DrawingVisible(); drawing = new Drawing();
drawing.setBackground(Color.WHITE); drawing.setBackground(Color.WHITE);
JTextArea infoPanel = new JTextArea(); JTextArea infoPanel = new JTextArea();
infoPanel.setMinimumSize(new Dimension(200, 50)); infoPanel.setMinimumSize(new Dimension(200, 50));
// infoPanel.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, Color.GRAY)); // infoPanel.setBorder(BorderFactory.createMatteBorder(0, 1, 0, 0, Color.GRAY));
@ -140,36 +155,70 @@ public class MainWindow extends JFrame {
infoPanel.setEditable(false); infoPanel.setEditable(false);
this.logStream = new JOutputStream(infoPanel); this.logStream = new JOutputStream(infoPanel);
this.printStream = new PrintStream(this.logStream); this.printStream = new PrintStream(this.logStream);
sp.setResizeWeight(0.8); sp.setResizeWeight(0.8);
// sp.setEnabled(false); // sp.setEnabled(false);
sp.setDividerSize(5); sp.setDividerSize(5);
sp.setBackground(Color.WHITE); sp.setBackground(Color.WHITE);
sp.add(drawing); sp.add(drawing);
sp.add(new JScrollPane(infoPanel)); sp.add(new JScrollPane(infoPanel));
this.add(sp, BorderLayout.CENTER); this.add(sp, BorderLayout.CENTER);
this.add(createStatusBar(), BorderLayout.SOUTH); this.add(createStatusBar(), BorderLayout.SOUTH);
} }
private void launchThread(Runnable runnable) {
currentThread = new Thread(new Runnable() {
@Override
public void run() {
threadPanel.setVisible(true);
runnable.run();
threadPanel.setVisible(false);
}
});
currentThread.start();
}
private ShortestPathInstance getShortestPathParameters() {
// TODO: Select origin / end nodes.
return new ShortestPathInstance(
graph, graph.getNodes().get(2), graph.getNodes().get(139), Mode.TIME);
}
private void launchShortestPathThread(ShortestPathAlgorithm spAlgorithm) {
spAlgorithm.addObserver(new ShortestPathGraphicObserver(drawing));
// algo.addObserver(new ShortestPathTextObserver(printStream));
launchThread(new Runnable() {
@Override
public void run() {
spAlgorithm.run();
AbstractSolution solution = spAlgorithm.getLastSolution();
if (solution != null && solution.isFeasible()) {
new PathDrawing(drawing).drawPath(((ShortestPathSolution)solution).getPath());
}
}
});
}
@SuppressWarnings("restriction")
private JMenuBar createMenuBar() { private JMenuBar createMenuBar() {
// Open Map item... // Open Map item...
openMapItem = new JMenuItem("Open Map... ", openMapItem = new JMenuItem("Open Map... ",
KeyEvent.VK_O); KeyEvent.VK_O);
openMapItem.setAccelerator(KeyStroke.getKeyStroke( openMapItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_O, ActionEvent.ALT_MASK)); KeyEvent.VK_O, ActionEvent.ALT_MASK));
openMapItem.addActionListener(new ActionListener() { openMapItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter( FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Map & compressed map files", "map", "map.gz"); "Map & compressed map files", "map", "map.gz");
chooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
chooser.setFileFilter(filter); chooser.setFileFilter(filter);
if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
BinaryGraphReader reader; BinaryGraphReader reader;
try { try {
reader = new BinaryGraphReader( reader = new BinaryGraphReader(
Openfile.open(chooser.getSelectedFile().getAbsolutePath())); Openfile.open(chooser.getSelectedFile().getAbsolutePath()));
@ -177,38 +226,38 @@ public class MainWindow extends JFrame {
JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file."); JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file.");
return ; return ;
} }
try { try {
graph = reader.read(); graph = reader.read();
} }
catch (Exception exception) { catch (Exception exception) {
JOptionPane.showMessageDialog(MainWindow.this, "Unable to read graph from the selected file."); JOptionPane.showMessageDialog(MainWindow.this, "Unable to read graph from the selected file.");
return ; return ;
} }
drawing.clear(); drawing.clear();
new GraphDrawing(drawing).drawGraph(graph); new GraphDrawing(drawing).drawGraph(graph);
for (JMenuItem item: graphItems) { for (JMenuItem item: graphItems) {
item.setEnabled(true); item.setEnabled(true);
} }
mapIdPanel.setText("Map ID: 0x" + Integer.toHexString(graph.getMapId())); mapIdPanel.setText("Map ID: 0x" + Integer.toHexString(graph.getMapId()));
} }
} }
}); });
// Open Path item... // Open Path item...
JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P); JMenuItem openPathItem = new JMenuItem("Open Path... ", KeyEvent.VK_P);
openPathItem.setAccelerator(KeyStroke.getKeyStroke( openPathItem.setAccelerator(KeyStroke.getKeyStroke(
KeyEvent.VK_P, ActionEvent.ALT_MASK)); KeyEvent.VK_P, ActionEvent.ALT_MASK));
openPathItem.addActionListener(new ActionListener() { openPathItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
JFileChooser chooser = new JFileChooser(); JFileChooser chooser = new JFileChooser();
FileNameExtensionFilter filter = new FileNameExtensionFilter( FileNameExtensionFilter filter = new FileNameExtensionFilter(
"Path & compressed path files", "path", "path.gz"); "Path & compressed path files", "path", "path.gz");
chooser.setCurrentDirectory(new File(System.getProperty("user.dir"))); chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
chooser.setFileFilter(filter); chooser.setFileFilter(filter);
if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) { if (chooser.showOpenDialog(MainWindow.this) == JFileChooser.APPROVE_OPTION) {
BinaryPathReader reader; BinaryPathReader reader;
try { try {
reader = new BinaryPathReader( reader = new BinaryPathReader(
Openfile.open(chooser.getSelectedFile().getAbsolutePath())); Openfile.open(chooser.getSelectedFile().getAbsolutePath()));
@ -216,23 +265,23 @@ public class MainWindow extends JFrame {
JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file."); JOptionPane.showMessageDialog(MainWindow.this, "Cannot open the selected file.");
return ; return ;
} }
try { try {
currentPath = reader.readPath(graph); currentPath = reader.readPath(graph);
} }
catch (MapMismatchException exception) { catch (MapMismatchException exception) {
JOptionPane.showMessageDialog(MainWindow.this, "The selected file does not contain a path for the current graph."); JOptionPane.showMessageDialog(MainWindow.this, "The selected file does not contain a path for the current graph.");
return; return;
} }
catch (Exception exception) { catch (Exception exception) {
JOptionPane.showMessageDialog(MainWindow.this, "Unable to read path from the selected file."); JOptionPane.showMessageDialog(MainWindow.this, "Unable to read path from the selected file.");
return ; return ;
} }
new PathDrawing(drawing).drawPath(currentPath); new PathDrawing(drawing).drawPath(currentPath);
} }
} }
}); });
graphItems.add(openPathItem); graphItems.add(openPathItem);
// Close item // Close item
JMenuItem closeItem = new JMenuItem("Quit", KeyEvent.VK_Q); JMenuItem closeItem = new JMenuItem("Quit", KeyEvent.VK_Q);
closeItem.setAccelerator(KeyStroke.getKeyStroke( closeItem.setAccelerator(KeyStroke.getKeyStroke(
@ -250,7 +299,7 @@ public class MainWindow extends JFrame {
fileMenu.add(openPathItem); fileMenu.add(openPathItem);
fileMenu.addSeparator(); fileMenu.addSeparator();
fileMenu.add(closeItem); fileMenu.add(closeItem);
// Second menu // Second menu
JMenuItem drawGraphItem = new JMenuItem("Redraw", KeyEvent.VK_R); JMenuItem drawGraphItem = new JMenuItem("Redraw", KeyEvent.VK_R);
drawGraphItem.setAccelerator(KeyStroke.getKeyStroke( drawGraphItem.setAccelerator(KeyStroke.getKeyStroke(
@ -258,10 +307,14 @@ public class MainWindow extends JFrame {
drawGraphItem.addActionListener(new ActionListener() { drawGraphItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
drawing.clear(); launchThread(new Runnable() {
drawing.setAutoRepaint(true); @Override
new GraphDrawing(drawing).drawGraph(graph); public void run() {
drawing.setAutoRepaint(false); drawing.clear();
drawing.setAutoRepaint(true);
new GraphDrawing(drawing).drawGraph(graph);
}
});
} }
}); });
graphItems.add(drawGraphItem); graphItems.add(drawGraphItem);
@ -271,40 +324,58 @@ public class MainWindow extends JFrame {
drawGraphBWItem.addActionListener(new ActionListener() { drawGraphBWItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
drawing.clear(); launchThread(new Runnable() {
drawing.setAutoRepaint(true); @Override
new GraphDrawing(drawing, new BlackAndWhiteGraphPalette()).drawGraph(graph); public void run() {
drawing.setAutoRepaint(false); drawing.clear();
drawing.setAutoRepaint(true);
new GraphDrawing(drawing, new BlackAndWhiteGraphPalette()).drawGraph(graph);
}
});
} }
}); });
graphItems.add(drawGraphBWItem); graphItems.add(drawGraphBWItem);
JMenu graphMenu = new JMenu("Graph"); JMenu graphMenu = new JMenu("Graph");
graphMenu.add(drawGraphItem); graphMenu.add(drawGraphItem);
graphMenu.add(drawGraphBWItem); graphMenu.add(drawGraphBWItem);
// Algo menu // Algo menu
JMenu algoMenu = new JMenu("Algorithms"); JMenu algoMenu = new JMenu("Algorithms");
// Weakly connected components
JMenuItem wccItem = new JMenuItem("Weakly Connected Components"); JMenuItem wccItem = new JMenuItem("Weakly Connected Components");
wccItem.addActionListener(new ActionListener() { wccItem.addActionListener(new ActionListener() {
@Override @Override
public void actionPerformed(ActionEvent e) { public void actionPerformed(ActionEvent e) {
WeaklyConnectedComponentsInstance instance = new WeaklyConnectedComponentsInstance(graph); WeaklyConnectedComponentsInstance instance = new WeaklyConnectedComponentsInstance(graph);
WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm(instance); WeaklyConnectedComponentsAlgorithm algo = new WeaklyConnectedComponentsAlgorithm(instance);
algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing)); algo.addObserver(new WeaklyConnectedComponentGraphicObserver(drawing));
// algo.addObserver(new WeaklyConnectedComponentTextObserver(printStream));
(new Thread(algo)).start(); launchThread(algo);
}
});
// Shortest path
JMenuItem bellmanItem = new JMenuItem("Shortest Path (Bellman-Ford)");
bellmanItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
launchShortestPathThread(new BellmanFordAlgorithm(getShortestPathParameters()));
} }
}); });
graphItems.add(wccItem); graphItems.add(wccItem);
graphItems.add(bellmanItem);
algoMenu.add(wccItem); algoMenu.add(wccItem);
algoMenu.addSeparator();
algoMenu.add(bellmanItem);
// algoMenu.add(djikstraItem);
// algoMenu.add(aStarItem);
// Create the menu bar. // Create the menu bar.
JMenuBar menuBar = new JMenuBar(); JMenuBar menuBar = new JMenuBar();
menuBar.add(fileMenu); menuBar.add(fileMenu);
menuBar.add(graphMenu); menuBar.add(graphMenu);
menuBar.add(algoMenu); menuBar.add(algoMenu);
@ -312,29 +383,60 @@ public class MainWindow extends JFrame {
for (JMenuItem item: graphItems) { for (JMenuItem item: graphItems) {
item.setEnabled(false); item.setEnabled(false);
} }
return menuBar; return menuBar;
} }
private JPanel createStatusBar() { private JPanel createStatusBar() {
// create the status bar panel and shove it down the bottom of the frame // create the status bar panel and shove it down the bottom of the frame
JPanel statusPanel = new JPanel(); JPanel statusPanel = new JPanel();
statusPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY)); statusPanel.setBorder(BorderFactory.createMatteBorder(1, 0, 0, 0, Color.GRAY));
statusPanel.setPreferredSize(new Dimension(getWidth(), 20)); statusPanel.setPreferredSize(new Dimension(getWidth(), 34));
statusPanel.setLayout(new BoxLayout(statusPanel, BoxLayout.X_AXIS)); statusPanel.setLayout(new BorderLayout());
mapIdPanel = new JLabel(); mapIdPanel = new JLabel();
mapIdPanel.setHorizontalAlignment(SwingConstants.LEFT); mapIdPanel.setHorizontalAlignment(SwingConstants.LEFT);
statusPanel.add(mapIdPanel); statusPanel.add(mapIdPanel, BorderLayout.WEST);
JLabel threadInfo = new JLabel("Thread running... ");
JButton threadButton = new JButton("Stop");
threadButton.addActionListener(new ActionListener() {
@SuppressWarnings("deprecation")
@Override
public void actionPerformed(ActionEvent e) {
if (currentThread != null && currentThread.isAlive()) {
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) {
currentThread.stop();
currentThread = null;
threadPanel.setVisible(false);
}
}
}
});
threadPanel = new JPanel();
threadPanel.add(threadInfo);
threadPanel.add(threadButton);
// threadPanel.setVisible(false);
statusPanel.add(threadPanel, BorderLayout.EAST);
return statusPanel; return statusPanel;
} }
public static void main(final String[] args) { public static void main(final String[] args) {
// Try to set system look and feel.
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()) ;
}
catch (Exception e) { }
MainWindow w = new MainWindow(); MainWindow w = new MainWindow();
w.setExtendedState(JFrame.MAXIMIZED_BOTH); w.setExtendedState(JFrame.MAXIMIZED_BOTH);
w.setVisible(true); w.setVisible(true);
} }
} }

View File

@ -1,88 +1,170 @@
package org.insa.drawing ; package org.insa.drawing;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.image.*;
import javax.swing.JPanel;
/** /**
* Classe abstraite pour dessiner a l'ecran. * Cette implementation de la classe Dessin produit vraiment un affichage
* Deux implementations : une sous-classe DessinVisible qui dessine vraiment a l'ecran * (au contraire de la classe DessinInvisible).
* et une sous-classe DessinInvisible qui ne dessine rien (pour ne pas ralentir les tests avec l'affichage).
*/ */
import java.awt.* ; public class Drawing extends JPanel {
public interface Drawing {
/** /**
* Enable auto-repaint mode - When this mode is enable, call to
* drawing function will automatically repaint the drawing, which
* may be very slow in some case.
*
* @param autoRepaint Use true to enable auto-repaint, false to disable.
* *
*/ */
public void setAutoRepaint(boolean autoRepaint); private static final long serialVersionUID = 96779785877771827L;
private final Graphics2D gr;
private float long1;
private float long2;
private float lat1;
private float lat2;
// Width and height of the image
private final int width, height;
private boolean bb_is_set ;
private Image image;
private ZoomAndPanListener zoomAndPanListener;
public boolean autoRepaint = true;
/** /**
* Repaint the drawing. * Cree et affiche une nouvelle fenetre de dessin.
*
*/ */
public void repaint(); public Drawing() {
this.zoomAndPanListener = new ZoomAndPanListener(this, ZoomAndPanListener.DEFAULT_MIN_ZOOM_LEVEL, 20, 1.2);
this.addMouseListener(zoomAndPanListener);
this.addMouseMotionListener(zoomAndPanListener);
this.addMouseWheelListener(zoomAndPanListener);
this.width = 2000;
this.height = 1600;
BufferedImage img = new BufferedImage(this.width, this.height, BufferedImage.TYPE_3BYTE_BGR);
this.image = img;
this.gr = img.createGraphics();
this.zoomAndPanListener.setCoordTransform(this.gr.getTransform());
this.bb_is_set = false;
this.long1 = 0.0f;
this.long2 = this.width;
this.lat1 = 0.0f;
this.lat2 = this.height;
this.clear();
this.repaint();
}
@Override
public void paintComponent(Graphics g1) {
Graphics2D g = (Graphics2D)g1;
g.clearRect(0, 0, getWidth(), getHeight());
g.setTransform(zoomAndPanListener.getCoordTransform());
g.drawImage(image, 0, 0, this);
}
/** public void setAutoRepaint(boolean autoRepaint) {
* Set the pencil width. this.autoRepaint = autoRepaint;
* }
* @param width Width for the pencil.
* protected void doAutoPaint() {
*/ if (autoRepaint) {
public void setWidth(int width); this.repaint();
}
/** }
* Set the pencil color.
* public void setWidth(int width) {
* @param color Color for the pencil. this.gr.setStroke(new BasicStroke(width));
* }
*/
public void setColor(Color col);
/**
* Clear the drawing.
*/
public void clear();
/** public void setColor(Color col) {
* Indique les bornes de la fenetre graphique. this.gr.setColor(col);
* Le calcul des coordonnees en pixel se fera automatiquement }
* a l'appel des methodes drawLine et autres.
*
* @param long1 longitude du bord gauche
* @param long2 longitude du bord droit
* @param lat1 latitude du bord bas
* @param lat2 latitude du bord haut
*
*/
public void setBB(double long1, double long2, double lat1, double lat2);
/** public void clear() {
* Trace un segment. this.gr.setColor(Color.WHITE);
* @param long1 longitude du premier point this.gr.fillRect(0, 0, this.width, this.height);
* @param lat1 latitude du premier point }
* @param long2 longitude du second point
* @param lat2 latitude du second point
*/
public void drawLine(float long1, float lat1, float long2, float lat2);
/** public void setBB(double long1, double long2, double lat1, double lat2) {
* Trace un point.
* @param lon longitude du point
* @param lat latitude du point
* @param width grosseur du point
*/
public void drawPoint(float lon, float lat, int width);
/** if (long1 > long2 || lat1 > lat2) {
* Ecrit du texte a la position indiquee. throw new Error("DessinVisible.setBB : mauvaises coordonnees.");
* @param lon longitude du point ou positionner le texte. }
* @param lat latitude du point ou positionner le texte.
* @param txt le texte a ecrire. this.long1 = (float)long1;
*/ this.long2 = (float)long2;
public void putText(float lon, float lat, String txt); this.lat1= (float)lat1;
this.lat2 = (float)lat2;
this.bb_is_set = true;
double scale = 1 / Math.max(this.width / (double)this.getWidth(), this.height / (double)this.getHeight());
this.zoomAndPanListener.getCoordTransform().setToIdentity();
this.zoomAndPanListener.getCoordTransform().translate((this.getWidth() - this.width * scale) / 2,
(this.getHeight() - this.height * scale) / 2);
this.zoomAndPanListener.getCoordTransform().scale(scale, scale);
this.zoomAndPanListener.setZoomLevel(0);
this.repaint();
}
private int projx(float lon) {
return (int)(width * (lon - this.long1) / (this.long2 - this.long1)) ;
}
private int projy(float lat) {
return (int)(height * (1 - (lat - this.lat1) / (this.lat2 - this.lat1))) ;
}
private void checkBB() {
if (!this.bb_is_set) {
throw new Error("Classe DessinVisible : vous devez invoquer la methode setBB avant de dessiner.") ;
}
}
public void drawLine(float long1, float lat1, float long2, float lat2) {
this.checkBB() ;
int x1 = this.projx(long1) ;
int x2 = this.projx(long2) ;
int y1 = this.projy(lat1) ;
int y2 = this.projy(lat2) ;
gr.drawLine(x1, y1, x2, y2) ;
this.doAutoPaint();
}
public void drawPoint(float lon, float lat, int width) {
this.checkBB() ;
int x = this.projx(lon) - width / 2 ;
int y = this.projy(lat) - width / 2 ;
gr.fillOval (x, y, width, width) ;
this.doAutoPaint();
}
public void putText(float lon, float lat, String txt) {
this.checkBB() ;
int x = this.projx(lon) ;
int y = this.projy(lat) ;
gr.drawString (txt, x, y) ;
this.doAutoPaint();
}
} }