Add a new page to see the schedule of each stop, for each line

This commit is contained in:
Lucas 2024-05-01 23:35:54 +02:00
parent e154358d30
commit 0b469c7fe0
11 changed files with 178 additions and 48 deletions

View file

@ -62,7 +62,7 @@
<manifest> <manifest>
<addClasspath>true</addClasspath> <addClasspath>true</addClasspath>
<classpathPrefix>${project.build.finalName}.lib/</classpathPrefix> <classpathPrefix>${project.build.finalName}.lib/</classpathPrefix>
<mainClass>fr.u_paris.gla.project.gui.View</mainClass> <mainClass>fr.u_paris.gla.project.App</mainClass>
</manifest> </manifest>
</archive> </archive>
</configuration> </configuration>

View file

@ -7,19 +7,15 @@ import java.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.PrintStream; import java.io.PrintStream;
import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Properties; import java.util.Properties;
import javax.imageio.ImageIO; import javax.imageio.ImageIO;
import javax.swing.ImageIcon; import javax.swing.*;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.WindowConstants;
import fr.u_paris.gla.project.itinerary.Finder; import fr.u_paris.gla.project.gui.View;
import fr.u_paris.gla.project.itinerary.Parse; import fr.u_paris.gla.project.itinerary.*;
import fr.u_paris.gla.project.itinerary.Path;
import fr.u_paris.gla.project.itinerary.Stop;
/** Simple application model. /** Simple application model.
* *
@ -67,11 +63,26 @@ public class App {
} }
} }
} }
else{ else {
testRelease(); // testRelease();
run();
} }
} }
public static void run() {
Parse parse = new Parse();
parse.parseFiles();
Graph graph = parse.createGraph();
Finder finder = parse.createFinder(graph);
ArrayList<Stop> s = new ArrayList<>();
s.add(new Stop("M8", "Balard", 1.0315897, 3.0265513));
s.add(new Stop("M14", "Gare de Lyon", 2.4658452681, 3.0265513));
SwingUtilities.invokeLater(() -> new View(graph, finder, s));
}
public static void testRelease(){ public static void testRelease(){
Parse parse = new Parse(); Parse parse = new Parse();
parse.parseFiles(); parse.parseFiles();

View file

@ -3,10 +3,10 @@ package fr.u_paris.gla.project.gui;
import fr.u_paris.gla.project.idfm.CSVImageProvider; import fr.u_paris.gla.project.idfm.CSVImageProvider;
import fr.u_paris.gla.project.idfm.IDFMNetworkExtractor; import fr.u_paris.gla.project.idfm.IDFMNetworkExtractor;
import fr.u_paris.gla.project.idfm.ImagePair; import fr.u_paris.gla.project.idfm.ImagePair;
import fr.u_paris.gla.project.itinerary.Path; import fr.u_paris.gla.project.itinerary.*;
import fr.u_paris.gla.project.itinerary.Stop;
import javax.swing.*; import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.table.DefaultTableModel; import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel; import javax.swing.table.TableModel;
import java.awt.*; import java.awt.*;
@ -16,6 +16,9 @@ import java.net.URI;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import java.net.URL; import java.net.URL;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.logging.Logger; import java.util.logging.Logger;
public class View extends JFrame { public class View extends JFrame {
@ -25,7 +28,6 @@ public class View extends JFrame {
private JPanel CardPanel; private JPanel CardPanel;
private JMenuItem Home; private JMenuItem Home;
private JMenuItem Network; private JMenuItem Network;
private JMenuItem Favorites;
private JPanel NetworkPanel; private JPanel NetworkPanel;
private JTextField TextLocation; private JTextField TextLocation;
@ -55,6 +57,13 @@ public class View extends JFrame {
private JComboBox LinesComboBox; private JComboBox LinesComboBox;
private JButton ShowLineButton; private JButton ShowLineButton;
private JMenuItem Stops;
private JPanel StopsPanel;
private JLabel StopsLabel;
private JComboBox StopsComboBox;
private JComboBox StopsLinesComboBox;
private JButton SeeStopButton;
private JTextField TextCoord; private JTextField TextCoord;
private JButton ButtonCoord; private JButton ButtonCoord;
private JPanel SearchCoordPanel; private JPanel SearchCoordPanel;
@ -80,7 +89,7 @@ public class View extends JFrame {
private int count = 0; private int count = 0;
public View(ArrayList<Stop> s) throws HeadlessException { public View(Graph graph, Finder finder, ArrayList<Stop> s) throws HeadlessException {
setSize(800, 600); setSize(800, 600);
MainPanel = new JPanel(); MainPanel = new JPanel();
GridLayout MainLayout = new GridLayout(1, 2, 50, 0); GridLayout MainLayout = new GridLayout(1, 2, 50, 0);
@ -146,6 +155,7 @@ public class View extends JFrame {
ShowLineButton.setAlignmentX(Component.CENTER_ALIGNMENT); ShowLineButton.setAlignmentX(Component.CENTER_ALIGNMENT);
LinesPanel = new JPanel(); LinesPanel = new JPanel();
LinesPanel.setBackground(new Color(214,173,153));
LinesPanel.setLayout(new BoxLayout(LinesPanel, BoxLayout.Y_AXIS)); LinesPanel.setLayout(new BoxLayout(LinesPanel, BoxLayout.Y_AXIS));
LinesPanel.add(Box.createHorizontalGlue()); LinesPanel.add(Box.createHorizontalGlue());
LinesPanel.add(Box.createHorizontalStrut(2)); LinesPanel.add(Box.createHorizontalStrut(2));
@ -157,8 +167,35 @@ public class View extends JFrame {
LinesPanel.add(Box.createHorizontalStrut(2)); LinesPanel.add(Box.createHorizontalStrut(2));
LinesPanel.add(Box.createHorizontalGlue()); LinesPanel.add(Box.createHorizontalGlue());
StopsComboBox = new JComboBox();
StopsComboBox.setMaximumSize(new Dimension(200, StopsComboBox.getPreferredSize().height));
StopsComboBox.setPreferredSize(StopsComboBox.getPreferredSize());
StopsLinesComboBox = new JComboBox();
StopsLinesComboBox.setMaximumSize(new Dimension(200, StopsLinesComboBox.getPreferredSize().height));
StopsLinesComboBox.setPreferredSize(StopsComboBox.getPreferredSize());
StopsLabel = new JLabel("See stop schedules");
StopsLabel.setAlignmentX(Component.CENTER_ALIGNMENT);
SeeStopButton = new JButton("See Schedule");
SeeStopButton.setAlignmentX(Component.CENTER_ALIGNMENT);
StopsPanel = new JPanel();
StopsPanel.setBackground(new Color(171,197,105));
StopsPanel.setLayout(new BoxLayout(StopsPanel, BoxLayout.Y_AXIS));
StopsPanel.add(Box.createHorizontalGlue());
StopsPanel.add(Box.createHorizontalStrut(2));
StopsPanel.add(StopsLabel);
StopsPanel.add(Box.createHorizontalStrut(10));
StopsPanel.add(StopsComboBox);
StopsPanel.add(Box.createHorizontalStrut(10));
StopsPanel.add(StopsLinesComboBox);
StopsPanel.add(Box.createHorizontalStrut(10));
StopsPanel.add(SeeStopButton);
StopsPanel.add(Box.createHorizontalStrut(2));
StopsPanel.add(Box.createHorizontalGlue());
JPanel buttonBarPanel = new JPanel(new BorderLayout());
ButtonBar = new JMenuBar(); ButtonBar = new JMenuBar();
GridLayout ButtonLayout = new GridLayout(4, 1); GridLayout ButtonLayout = new GridLayout(5, 1);
ButtonBar.setLayout(ButtonLayout); ButtonBar.setLayout(ButtonLayout);
Home = new JMenuItem("Home"); Home = new JMenuItem("Home");
ButtonBar.add(Home); ButtonBar.add(Home);
@ -168,8 +205,12 @@ public class View extends JFrame {
ButtonBar.add(Itinerary); ButtonBar.add(Itinerary);
Lines = new JMenuItem("Lines"); Lines = new JMenuItem("Lines");
ButtonBar.add(Lines); ButtonBar.add(Lines);
Stops = new JMenuItem("Stops");
ButtonBar.add(Stops);
buttonBarPanel.add(ButtonBar, BorderLayout.CENTER);
buttonBarPanel.setVisible(true);
ButtonBar.setPreferredSize(new Dimension(50, 500)); ButtonBar.setPreferredSize(new Dimension(50, MainPanel.getHeight()));
MainPanel.add(ButtonBar); MainPanel.add(ButtonBar);
MainPanel.add(CardPanel); MainPanel.add(CardPanel);
@ -220,12 +261,39 @@ public class View extends JFrame {
CardPanel.revalidate(); CardPanel.revalidate();
}); });
Stops.addActionListener(e -> {
CardPanel.removeAll();
CardPanel.add(StopsPanel);
CardPanel.repaint();
CardPanel.revalidate();
});
CSVImageProvider.getLineImageMap().forEach(p -> LinesComboBox.addItem(p)); CSVImageProvider.getLineImageMap().forEach(p -> LinesComboBox.addItem(p));
ShowLineButton.addActionListener(f -> { ShowLineButton.addActionListener(f -> {
ImagePair item = (ImagePair) LinesComboBox.getSelectedItem(); ImagePair item = (ImagePair) LinesComboBox.getSelectedItem();
openWebpage(item.getValue()); openWebpage(item.getValue());
}); });
Set<Stop> nodes = graph.getNodes();
List<Stop> nodesList = nodes.stream().sorted(Comparator.comparing(Stop::getName)).toList();
nodesList.forEach(stop -> StopsComboBox.addItem(stop));
StopsComboBox.addItemListener(e -> {
if (e.getStateChange() == ItemEvent.SELECTED) {
Stop stop = (Stop) StopsComboBox.getSelectedItem();
StopsLinesComboBox.removeAllItems();
graph.getConnections(stop).forEach(c -> {
if (!c.toString().equals("WALK"))
StopsLinesComboBox.addItem(c);
});
}
});
SeeStopButton.addActionListener(f -> {
Connection c;
if ((c = (Connection) StopsLinesComboBox.getSelectedItem()) != null) {
createHourWindow(c.getSchedules());
}
});
TextLocation.addKeyListener(new KeyAdapter() { TextLocation.addKeyListener(new KeyAdapter() {
@Override @Override
public void keyReleased(KeyEvent e) { public void keyReleased(KeyEvent e) {
@ -278,7 +346,6 @@ public class View extends JFrame {
super.mouseClicked(e); super.mouseClicked(e);
System.out.println("MouseClick: " + e.getX() + ";" + e.getY()); System.out.println("MouseClick: " + e.getX() + ";" + e.getY());
showOptionsDialog(tableStops, e.getX(), e.getY()); showOptionsDialog(tableStops, e.getX(), e.getY());
} }
}); });
@ -290,6 +357,38 @@ public class View extends JFrame {
}); });
} }
private void createHourWindow(ArrayList<Integer> schedules) {
JFrame frame = new JFrame("Schedule");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel panel = new JPanel(new GridLayout(0, 1));
panel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
JScrollPane scrollPane = new JScrollPane(panel);
frame.getContentPane().add(scrollPane);
for (int time : schedules) {
int hours = time / 3600;
int minutes = (time % 3600) / 60;
JLabel label = new JLabel(String.format("%dh%d", hours, minutes));
label.setBorder(BorderFactory.createCompoundBorder(
BorderFactory.createLineBorder(Color.BLACK),
BorderFactory.createEmptyBorder(5, 5, 5, 5)));
label.setHorizontalAlignment(SwingConstants.CENTER);
panel.add(label);
}
if (schedules.isEmpty()) {
panel.add(new JLabel("No time available"));
}
scrollPane.repaint();
frame.repaint();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(200, 400);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.setResizable(false);
}
private void showOptionsDialog(JTable table, int x, int y) { private void showOptionsDialog(JTable table, int x, int y) {
int selectedRow = table.rowAtPoint(new Point(x, y)); int selectedRow = table.rowAtPoint(new Point(x, y));
if (selectedRow != -1) { // If a row is selected if (selectedRow != -1) { // If a row is selected
@ -359,12 +458,14 @@ public class View extends JFrame {
// Add new rows based on the search results // Add new rows based on the search results
count = 0; count = 0;
Path last = null; Path last = null;
for (Path path : paths) { if (paths != null) {
// Add a row to the table with Stop's line in the first column and Stop's name in the second column for (Path path : paths) {
model.addRow(new Object[]{path.getLine(), path.getCurrentStop(), path.getStartTime()}); // Add a row to the table with Stop's line in the first column and Stop's name in the second column
model.addRow(new Object[]{path.getLine(), path.getCurrentStop(), path.getStartTime()});
++count; ++count;
last = path; last = path;
}
} }
if (last != null) model.addRow(new Object[]{last.getLine(), last.getNextStop()}); if (last != null) model.addRow(new Object[]{last.getLine(), last.getNextStop()});
@ -416,10 +517,12 @@ public class View extends JFrame {
} }
} }
/*
public static void main(String[] args) { public static void main(String[] args) {
ArrayList<Stop> s = new ArrayList<>(); ArrayList<Stop> s = new ArrayList<>();
s.add(new Stop("M8", "Balard", 1.0315897, 3.0265513)); s.add(new Stop("M8", "Balard", 1.0315897, 3.0265513));
s.add(new Stop("M14", "Gare de Lyon", 2.4658452681, 3.0265513)); s.add(new Stop("M14", "Gare de Lyon", 2.4658452681, 3.0265513));
SwingUtilities.invokeLater(() -> new View(s)); SwingUtilities.invokeLater(() -> new View(graph, finder, s));
} }
*/
} }

View file

@ -66,12 +66,20 @@ public final class CSVImageProvider {
lineImageMap = new ArrayList<>(); lineImageMap = new ArrayList<>();
try { try {
CSVTools.readCSVFromFile(FILE_NAME, CSVTools.readCSVFromFile(FILE_NAME,
(String[] line) -> lineImageMap.add(new ImagePair( (String[] line) ->
line[ImageFormat.LINE_INDEX], {
line[ImageFormat.LINE_DETAIL_INDEX], String label = line[ImageFormat.LINE_INDEX];
line[ImageFormat.IMAGE_URL_INDEX] String detail = line[ImageFormat.LINE_DETAIL_INDEX];
))); String imageUrl = line[ImageFormat.IMAGE_URL_INDEX];
} catch(IOException e){
int index = (int) lineImageMap.stream()
.filter(pair -> pair.getLine().equals(label))
.count();
lineImageMap.add(new ImagePair(label, detail, imageUrl));
});
}
catch(IOException e){
LOGGER.severe("File is not generated yet"); LOGGER.severe("File is not generated yet");
} }
lineImageMap.sort(Comparator.comparing(ImagePair::getLabel)); lineImageMap.sort(Comparator.comparing(ImagePair::getLabel));

View file

@ -102,18 +102,17 @@ public class IDFMNetworkExtractor {
public static boolean checkFileExistence(String filePath) { public static boolean checkFileExistence(String filePath) {
File file = new File(filePath); File file = new File(filePath);
if (file.exists()) { if (file.exists()) {
LOGGER.severe(filePath+ " already exists."); LOGGER.log(Level.INFO, filePath+ " already exists.");
return true; return true;
} else { } else {
LOGGER.severe(filePath + " does not exist."); LOGGER.log(Level.INFO, filePath + " does not exist.");
return false; return false;
} }
} }
public static void buildFiles() { public static void buildFiles() {
if (checkFileExistence("./"+HOURS_FILE_NAME) && checkFileExistence("./"+TRACE_FILE_NAME) && checkFileExistence(("./"+IMAGES_FILE_NAME))) { if (checkFileExistence("./"+HOURS_FILE_NAME) && checkFileExistence("./"+TRACE_FILE_NAME) && checkFileExistence(("./"+IMAGES_FILE_NAME))) {
LOGGER.severe("Files already exists."); LOGGER.log(Level.INFO, "Files already exists.");
return; return;
} }

View file

@ -5,10 +5,12 @@ package fr.u_paris.gla.project.idfm;
* These getters ables a ComboBox to show the label returned by toString, and get a specific value when the object is returned * These getters ables a ComboBox to show the label returned by toString, and get a specific value when the object is returned
*/ */
public class ImagePair { public class ImagePair {
private final String line;
private final String label; private final String label;
private final String value; private final String value;
public ImagePair(String label, String label_detail, String value){ public ImagePair(String label, String label_detail, String value){
this.line = label;
this.label = label + " - " + label_detail; this.label = label + " - " + label_detail;
this.value = value; this.value = value;
} }
@ -17,6 +19,10 @@ public class ImagePair {
return this.label; return this.label;
} }
public String getLine(){
return this.line;
}
public String getValue(){ public String getValue(){
return this.value; return this.value;
} }

View file

@ -96,4 +96,9 @@ public class Connection{
if(nextTime < currentTime) { nextTime += 86400;} if(nextTime < currentTime) { nextTime += 86400;}
return nextTime - currentTime + this.time; return nextTime - currentTime + this.time;
} }
@Override
public String toString() {
return lineName;
}
} }

View file

@ -27,8 +27,7 @@ public class Finder {
graph.addNode(fromNode); graph.addNode(fromNode);
graph.addNode(toNode); graph.addNode(toNode);
List<Path> res = findPath(fromNode, toNode, startTime); return findPath(fromNode, toNode, startTime);
return res;
} }
/** /**

View file

@ -4,7 +4,7 @@ import java.util.HashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
public class Graph{ public class Graph {
private final Set<Stop> nodes; private final Set<Stop> nodes;
private final Map<Stop, Set<Connection>> connections; private final Map<Stop, Set<Connection>> connections;

View file

@ -212,11 +212,9 @@ public class Parse {
} }
public void parseFiles(){ public void parseFiles(){
IDFMNetworkExtractor.buildFiles(); IDFMNetworkExtractor.buildFiles();
try { try {
CSVTools.readCSVFromFile(TRACE_FILE_NAME, CSVTools.readCSVFromFile(TRACE_FILE_NAME,
(String[] line) -> addLine(line, nodes, tmp, connections)); (String[] line) -> addLine(line, nodes, tmp, connections));
@ -228,11 +226,18 @@ public class Parse {
c.sortSchedule(); c.sortSchedule();
} }
} }
}
} catch (IOException e) { catch (IOException e) {
LOGGER.log(Level.SEVERE, "Error while reading the line paths", e); LOGGER.log(Level.SEVERE, "Error while reading the line paths", e);
} }
}
public Graph createGraph() {
return new Graph(nodes, connections);
}
public Finder createFinder(Graph graph) {
return new Finder(graph);
} }
public List<Path> getItinerary(Stop src, Stop dst, double startTime ){ public List<Path> getItinerary(Stop src, Stop dst, double startTime ){

View file

@ -32,13 +32,7 @@ public class Stop {
@Override @Override
public String toString() { public String toString() {
return "Stop{" + return name;
"id=" + id +
", lines=" + lines +
", name='" + name + '\'' +
", latitude=" + latitude +
", longitude=" + longitude +
'}';
} }
public int getId(){ public int getId(){