From c70618435aa316df483e0940e7baf45802e4bb2a Mon Sep 17 00:00:00 2001 From: HU helene Date: Mon, 18 Mar 2024 17:01:51 +0100 Subject: [PATCH 1/6] #14 Basic gui --- .../java/fr/u_paris/gla/project/gui/View.form | 197 ++++++++++++++++++ .../java/fr/u_paris/gla/project/gui/View.java | 66 ++++++ 2 files changed, 263 insertions(+) create mode 100644 src/main/java/fr/u_paris/gla/project/gui/View.form create mode 100644 src/main/java/fr/u_paris/gla/project/gui/View.java diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.form b/src/main/java/fr/u_paris/gla/project/gui/View.form new file mode 100644 index 0000000..e536cd5 --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/gui/View.form @@ -0,0 +1,197 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.java b/src/main/java/fr/u_paris/gla/project/gui/View.java new file mode 100644 index 0000000..52be130 --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/gui/View.java @@ -0,0 +1,66 @@ +package fr.u_paris.gla.project.gui; + +import javax.swing.*; +import java.awt.*; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; + +public class View extends JFrame{ + private JPanel Cardpanel; + private JMenuItem Home; + private JMenuItem Network; + private JMenuItem Favorites; + private JPanel NetworkPanel; + private JPanel FavoritesPanel; + private JTextField textField1; + private JButton searchButton; + private JPanel HomePanel; + private JPanel MainPanel; + + public View() throws HeadlessException { + setContentPane(MainPanel); + setTitle("app"); + setExtendedState(JFrame.MAXIMIZED_BOTH); + //setUndecorated(true); + setVisible(true);; + setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + + Home.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Cardpanel.removeAll(); + Cardpanel.add(HomePanel); + Cardpanel.repaint(); + Cardpanel.revalidate(); + } + }); + + Network.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Cardpanel.removeAll(); + Cardpanel.add(NetworkPanel); + Cardpanel.repaint(); + Cardpanel.revalidate(); + } + }); + + Favorites.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Cardpanel.removeAll(); + Cardpanel.add(FavoritesPanel); + Cardpanel.repaint(); + Cardpanel.revalidate(); + } + }); + + + } + + public static void main(String[] args) { + View v = new View(); + + + } +} From 5bd350643a8ac7ccd3865abffe239a6e4a8eb51b Mon Sep 17 00:00:00 2001 From: HU helene Date: Mon, 25 Mar 2024 10:10:38 +0100 Subject: [PATCH 2/6] #14 Basic gui change panel color --- src/main/java/fr/u_paris/gla/project/gui/View.form | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.form b/src/main/java/fr/u_paris/gla/project/gui/View.form index e536cd5..0d5e3d8 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.form +++ b/src/main/java/fr/u_paris/gla/project/gui/View.form @@ -3,7 +3,7 @@ - + @@ -16,8 +16,10 @@ + + @@ -27,7 +29,9 @@ - + + + @@ -85,6 +89,7 @@ + @@ -106,6 +111,7 @@ + From 9514d5d254428a20fd027884e303eba5e3eb96bf Mon Sep 17 00:00:00 2001 From: Lucas Date: Mon, 8 Apr 2024 14:19:44 +0200 Subject: [PATCH 3/6] [feat] Result table for stops list WIP --- pom.xml | 19 ++- .../java/fr/u_paris/gla/project/gui/View.form | 12 +- .../java/fr/u_paris/gla/project/gui/View.java | 95 +++++++++++- .../gla/project/itinerary/Connection.java | 37 +++++ .../u_paris/gla/project/itinerary/Graph.java | 28 ++++ .../itinerary/ItineraryCalculator.java | 146 ++++++++++++++++++ .../u_paris/gla/project/itinerary/Stop.java | 98 ++++++++++++ 7 files changed, 430 insertions(+), 5 deletions(-) create mode 100644 src/main/java/fr/u_paris/gla/project/itinerary/Connection.java create mode 100644 src/main/java/fr/u_paris/gla/project/itinerary/Graph.java create mode 100644 src/main/java/fr/u_paris/gla/project/itinerary/ItineraryCalculator.java create mode 100644 src/main/java/fr/u_paris/gla/project/itinerary/Stop.java diff --git a/pom.xml b/pom.xml index 787e8a2..61d26c4 100644 --- a/pom.xml +++ b/pom.xml @@ -37,6 +37,22 @@ + + org.apache.maven.plugins + maven-dependency-plugin + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/${project.build.finalName}.lib + + + + org.apache.maven.plugins maven-jar-plugin @@ -45,7 +61,8 @@ true - fr.u_paris.gla.project.App + ${project.build.finalName}.lib/ + fr.u_paris.gla.project.itinerary.ItineraryCalculator diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.form b/src/main/java/fr/u_paris/gla/project/gui/View.form index 0d5e3d8..703d5bc 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.form +++ b/src/main/java/fr/u_paris/gla/project/gui/View.form @@ -37,7 +37,7 @@ - + @@ -83,7 +83,7 @@ - + @@ -103,6 +103,14 @@ + + + + + + + + diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.java b/src/main/java/fr/u_paris/gla/project/gui/View.java index 52be130..7fc0831 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.java +++ b/src/main/java/fr/u_paris/gla/project/gui/View.java @@ -1,9 +1,15 @@ package fr.u_paris.gla.project.gui; +import fr.u_paris.gla.project.itinerary.Stop; + import javax.swing.*; +import javax.swing.table.DefaultTableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; +import java.awt.event.KeyAdapter; +import java.awt.event.KeyEvent; +import java.util.ArrayList; public class View extends JFrame{ private JPanel Cardpanel; @@ -16,8 +22,23 @@ public class View extends JFrame{ private JButton searchButton; private JPanel HomePanel; private JPanel MainPanel; + private DefaultTableModel dtm; + + private JTable table; + + private JScrollPane mypane; + + private ArrayList StopList; + + private Stop StopCur; + + private ArrayList searchRes; + + public View(ArrayList s) throws HeadlessException { + this.createUIComponents(); + this.StopList = s; + this.StopCur = StopList.get(0); - public View() throws HeadlessException { setContentPane(MainPanel); setTitle("app"); setExtendedState(JFrame.MAXIMIZED_BOTH); @@ -56,11 +77,81 @@ public class View extends JFrame{ }); + textField1.addKeyListener(new KeyAdapter() { + @Override + public void keyReleased(KeyEvent e) { + super.keyReleased(e); + if (e.getKeyCode() == KeyEvent.VK_ENTER) { + System.out.println("Enter key released"); + } + } + }); + } + + + public static void main(String[] args) { - View v = new View(); + ArrayList 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)); + System.out.println(s.toString()); + View v = new View(s); + v.showSearch(s); } + + + private void createUIComponents() { + // TODO: place custom component creation code here + + table = new JTable(); + dtm = new DefaultTableModel(0, 0); + + String[] header = new String[] { "Line", "Stop" }; + dtm.setColumnIdentifiers(header); + table.setModel(dtm); + mypane = new JScrollPane(table); + + + } + + private void showSearch(ArrayList stops) { + // Clear existing rows from the table + dtm.setRowCount(0); + + // Add new rows based on the search results + for (Stop stop : stops) { + // Add a row to the table with Stop's line in the first column and Stop's name in the second column + + dtm.addRow(new Object[]{stop.getLines(), stop.getName()}); + } + this.displayTableValues(); + dtm.fireTableDataChanged(); + table.repaint(); + table.revalidate(); + Cardpanel.repaint(); + Cardpanel.revalidate(); + + } + + private void displayTableValues() { + int rowCount = dtm.getRowCount(); + int columnCount = dtm.getColumnCount(); + + // Iterate over each row + for (int row = 0; row < rowCount; row++) { + // Iterate over each column + for (int col = 0; col < columnCount; col++) { + // Get the value at the current cell + Object value = dtm.getValueAt(row, col); + // Display the value + System.out.println("Value at row " + row + ", column " + col + ": " + value); + } + } + } + + } diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Connection.java b/src/main/java/fr/u_paris/gla/project/itinerary/Connection.java new file mode 100644 index 0000000..1cafbec --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Connection.java @@ -0,0 +1,37 @@ +package fr.u_paris.gla.project.itinerary; + +public class Connection{ + // Destination of the connection between the two stops + private final Stop stop; + + // The line used for this connection + private final String lineName; + + private final double distance; + + private final int time; + + public Connection(Stop stop, String lineName, double distance, int time){ + this.stop = stop; + this.lineName=lineName; + this.distance = distance; + this.time = time; + } + + + public String getLineName() { + return lineName; + } + + public double getDistance() { + return distance; + } + + public int getTime() { + return time; + } + + public Stop getStop() { + return stop; + } +} diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Graph.java b/src/main/java/fr/u_paris/gla/project/itinerary/Graph.java new file mode 100644 index 0000000..795add9 --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Graph.java @@ -0,0 +1,28 @@ +package fr.u_paris.gla.project.itinerary; + +import java.util.HashMap; +import java.util.Map; +import java.util.Set; + +public class Graph{ + private final Set nodes; + + private final Map> connections; + + public Graph(Set nodes, Map> connections) { + this.nodes = nodes; + this.connections = connections; + } + + public Set getConnections(Stop node) { + return connections.get(node); + } + + public Set getNodes() { + return nodes; + } + + public Map> getConnections() { + return connections; + } +} diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/ItineraryCalculator.java b/src/main/java/fr/u_paris/gla/project/itinerary/ItineraryCalculator.java new file mode 100644 index 0000000..5391c19 --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/itinerary/ItineraryCalculator.java @@ -0,0 +1,146 @@ +package fr.u_paris.gla.project.itinerary; + +import fr.u_paris.gla.project.idfm.*; +import fr.u_paris.gla.project.utils.CSVTools; +import fr.u_paris.gla.project.utils.GPS; + +import java.io.IOException; +import java.util.*; +import java.util.logging.Level; +import java.util.logging.Logger; + +public class ItineraryCalculator { + private static final Logger LOGGER = Logger + .getLogger(IDFMNetworkExtractor.class.getName()); + + // IDF mobilite generated file + private static final String TRACE_FILE_NAME = "./trace.csv"; + + private static final String HOURS_FILE_NAME = "./hours.csv"; + + // IDF mobilite file format + + private static final int IDFM_TRACE_ID_INDEX = 0; + + private static final int IDFM_TRACE_DERIV_INDEX = 1; + + private static final int IDFM_TRACE_FROM_INDEX = 2; + + private static final int IDFM_TRACE_FROM_GPS_INDEX = 3; + + private static final int IDFM_TRACE_TO_INDEX= 4; + + private static final int IDFM_TRACE_TO_GPS_INDEX = 5; + + private static final int IDFM_TRACE_TIME_INDEX = 6; + + private static final int IDFM_TRACE_DISTANCE_INDEX = 7; + + private static final double ERROR_MARGIN = 1.; + + + /** + * Returns the coordinates from a String to a double array: + * "49.08, 3.07" -> {49.08, 3.07} + * @param gps the string representation + * @return the double array + */ + private static double[] getCoords(String gps) { + String []stringCoords = gps.split(", "); + return new double[] {Double.parseDouble(stringCoords[0]), Double.parseDouble(stringCoords[1])}; + } + + /** + * Searchs for a stop with the same name and GPS coordinates in the graph, and creates it if non existant + * @param nodes a graph of the stops + * @param tmp list of the created stops + * @param name the name of the stop + * @param gps the coordinate of the stop + * @param lineId the line the stop is on + * @return the Stop object + */ + private static Stop getOrCreateStop(HashSet nodes, HashMap> tmp, String name, String gps, String lineId) { + ArrayList stopList = tmp.get(name); + // First we search by name, and then compare the coordinates since multiple stations can have the same name. A margin of error is necessary since stops can have multiple GPS coordinates + if (stopList != null) { + for(Stop stop : stopList) { + double[] coords = getCoords(gps); + double dist = GPS.distance(coords[0], coords[1], stop.getLatitude(), stop.getLongitude()); + if(dist < ERROR_MARGIN) { + stop.addLine(lineId); + return stop; + } + } + } + + double[] coords = getCoords(gps); + Stop newStop = new Stop(lineId, name, coords[0], coords[1]); + nodes.add(newStop); + stopList = stopList == null ? new ArrayList<>() : stopList; + stopList.add(newStop); + tmp.put(name, stopList); + return newStop; + } + + /** + * Adds into the graph the connection between two stops, parsed from a CSV line + * @param line the current line we want to parse + * @param nodes the graph of stops + * @param tmp list of the created stops + * @param connections + */ + private static void addLine(String[] line, HashSet nodes, HashMap> tmp, HashMap> connections) { + Stop fromStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_FROM_INDEX], line[IDFM_TRACE_FROM_GPS_INDEX], line[IDFM_TRACE_ID_INDEX]); + Stop toStop = getOrCreateStop(nodes, tmp, line[IDFM_TRACE_TO_INDEX], line[IDFM_TRACE_TO_GPS_INDEX], line[IDFM_TRACE_ID_INDEX]); + + String[] timeString = line[IDFM_TRACE_TIME_INDEX].split(":"); + int time = Integer.parseInt(timeString[0]) * 60 + Integer.parseInt(timeString[1]); + + Connection connection = new Connection(toStop, line[IDFM_TRACE_ID_INDEX], Double.parseDouble(line[IDFM_TRACE_DISTANCE_INDEX]), time); + + connections.computeIfAbsent(fromStop, k -> new HashSet<>()).add(connection); + } + + public static void main(String[] args){ + if (args.length != 0) { + LOGGER.severe("Invalid command line. Target file names are in the main file for now."); + return; + } + + try { + HashSet nodes = new HashSet<>(); + HashMap> connections = new HashMap<>(); + HashMap> tmp = new HashMap<>(); + CSVTools.readCSVFromFile(TRACE_FILE_NAME, + (String[] line) -> addLine(line, nodes, tmp, connections)); + + + Stop porteivry = tmp.get("Porte d'Ivry").get(0); + Stop repu = tmp.get("République").get(0); + + Graph graph = new Graph(nodes, connections); + int cpt = 0; + for (Map.Entry> entry : graph.getConnections().entrySet()) { + if (entry.getValue() == null) cpt +=1; + } + Stop garenord = tmp.get("Gare du Nord").get(0); + + Stop chatelet = tmp.get("Châtelet").get(0); + //System.out.println(graph.getConnections(garenord)); + //System.out.println(cpt); + //System.out.println(graph.getConnections(porteivry)); + Finder finder = new Finder(graph); + + List res = finder.findPath(porteivry, chatelet); + + for (Stop element : res) { + System.out.println(element); + } + + } catch (IOException e) { + LOGGER.log(Level.SEVERE, "Error while reading the line paths", e); + } + + + } +} diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Stop.java b/src/main/java/fr/u_paris/gla/project/itinerary/Stop.java new file mode 100644 index 0000000..80526a4 --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Stop.java @@ -0,0 +1,98 @@ +package fr.u_paris.gla.project.itinerary; + +import java.util.HashSet; +import java.util.Set; + +public class Stop implements GraphNode { + // The total number of stops + private static int counter = 0; + + private final int id; + + + + // The set of all the lines the stop is on + private final Set lines; + + + + private final String name; + + private final double latitude; + + private final double longitude; + + private double f; + + public Stop(String line, String name, double latitude, double longitude) { + lines = new HashSet<>(); + lines.add(line); + this.id = counter++; + this.name = name; + this.latitude = latitude; + this.longitude = longitude; + this.f = 0; + } + + @Override + public String toString() { + return "Stop{" + + "id=" + id + + ", lines=" + lines + + ", name='" + name + '\'' + + ", latitude=" + latitude + + ", longitude=" + longitude + + '}'; + } + + @Override + public int getId(){ + return id; + } + + @Override + public double getHeuristicCost(Stop goalNode) { + return 0; + } + + @Override + public Set getNeighbors() { + return null; + } + + @Override + public double getCost(Stop neighbor) { + return 0; + } + + @Override + public double getF() { + return f; + } + + public void setF(double value) { + this.f = value; + } + + public String getName(){ + return name; + } + + public double getLatitude(){ + return latitude; + } + + public double getLongitude(){ + return longitude; + } + + public void addLine(String s){ + lines.add(s); + } + + public Set getLines() { + return lines; + } + + +} From c073af652f9ad24b8f16666feaa29720abf20642 Mon Sep 17 00:00:00 2001 From: MAMBILA TETE jean philipp <@mambilat> Date: Mon, 22 Apr 2024 16:27:26 +0200 Subject: [PATCH 4/6] [chore] add missing dependencies --- .../u_paris/gla/project/itinerary/Finder.java | 91 ++++++++++++++++++ .../gla/project/itinerary/GraphNode.java | 14 +++ .../u_paris/gla/project/utils/CSVTools.java | 96 +++++++++++++++++++ 3 files changed, 201 insertions(+) create mode 100644 src/main/java/fr/u_paris/gla/project/itinerary/Finder.java create mode 100644 src/main/java/fr/u_paris/gla/project/itinerary/GraphNode.java create mode 100644 src/main/java/fr/u_paris/gla/project/utils/CSVTools.java diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/Finder.java b/src/main/java/fr/u_paris/gla/project/itinerary/Finder.java new file mode 100644 index 0000000..f07b850 --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/itinerary/Finder.java @@ -0,0 +1,91 @@ +package fr.u_paris.gla.project.itinerary; + +import java.util.*; + +public class Finder { + private Graph graph; + public Finder(Graph graph) { + this.graph = graph; + } + + public List findPath(Stop startNode, Stop goalNode) { + PriorityQueue openSet = new PriorityQueue<>(Comparator.comparingDouble(GraphNode::getF)); + HashSet closedSet = new HashSet<>(); + HashMap cameFrom = new HashMap<>(); + HashMap gScore = new HashMap<>(); + HashMap fScore = new HashMap<>(); + + // Initialize scores for all nodes to infinity + for (Stop node : graph.getNodes()) { + gScore.put(node, Double.POSITIVE_INFINITY); + fScore.put(node, Double.POSITIVE_INFINITY); + } + + // The cost of going from start to start is zero + gScore.put(startNode, 0.0); + // For the first node, fScore = gScore + heuristic + fScore.put(startNode, startNode.getHeuristicCost(goalNode)); + openSet.add(startNode); + + while (!openSet.isEmpty()) { + Stop current = openSet.poll(); + //System.out.println(current); + //System.out.println(graph.getConnections(current)); + + if (current.equals(goalNode)) { + return reconstructPath(cameFrom, current); + } + + closedSet.add(current); + + if(graph.getConnections(current) == null) { + continue; + } + + for (Connection connection : graph.getConnections(current) ) { + Stop neighbor = connection.getStop(); + if (closedSet.contains(neighbor)) { + continue; // Ignore the neighbor which is already evaluated. + } + + double tentativeGScore = gScore.get(current) + connection.getDistance(); + + if (!openSet.contains(neighbor)) { + openSet.add(neighbor); + } else if (tentativeGScore >= gScore.get(neighbor)) { + continue; // This is not a better path. + } + + // This path is the best until now. Record it! + cameFrom.put(neighbor, current); + gScore.put(neighbor, tentativeGScore); + fScore.put(neighbor, tentativeGScore + neighbor.getHeuristicCost(goalNode)); + neighbor.setF(fScore.get(neighbor)); + } + } + + // If we reach here, it means there's no path from start to goal + return null; + } + + private List reconstructPath(HashMap cameFrom, Stop current) { + List totalPath = new ArrayList<>(); + totalPath.add(current); + + while (cameFrom.containsKey(current)) { + current = cameFrom.get(current); + totalPath.add(0, current); // Add to the beginning of the list to maintain order + } + + return totalPath; + } + + //TODO: + public List findPath(double longitude, double latitude){ + return null; + } + + +} + + diff --git a/src/main/java/fr/u_paris/gla/project/itinerary/GraphNode.java b/src/main/java/fr/u_paris/gla/project/itinerary/GraphNode.java new file mode 100644 index 0000000..175db6e --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/itinerary/GraphNode.java @@ -0,0 +1,14 @@ +package fr.u_paris.gla.project.itinerary; + +import java.util.List; +import java.util.Set; + +public interface GraphNode { + int getId(); + double getHeuristicCost(Stop goalNode); + + Set getNeighbors(); + double getCost(Stop neighbor); + double getF(); + void setF(double value); +} diff --git a/src/main/java/fr/u_paris/gla/project/utils/CSVTools.java b/src/main/java/fr/u_paris/gla/project/utils/CSVTools.java new file mode 100644 index 0000000..dd41636 --- /dev/null +++ b/src/main/java/fr/u_paris/gla/project/utils/CSVTools.java @@ -0,0 +1,96 @@ +/** + * + */ +package fr.u_paris.gla.project.utils; + +import java.io.*; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.function.Consumer; +import java.util.stream.Stream; + +import com.opencsv.CSVParserBuilder; +import com.opencsv.CSVReader; +import com.opencsv.CSVReaderBuilder; +import com.opencsv.CSVWriterBuilder; +import com.opencsv.ICSVParser; +import com.opencsv.ICSVWriter; +import com.opencsv.exceptions.CsvValidationException; + +/** A CSV tool class. + * + * @author Emmanuel Bigeon */ +public final class CSVTools { + + /** Hidden constructor of tool class */ + private CSVTools() { + // Tool class + } + + private static void readCSVFromInputStream(InputStream is, Consumer contentLineConsumer) + throws IOException { + ICSVParser parser = new CSVParserBuilder().withSeparator(';').build(); + try (Reader reader = new BufferedReader( + new InputStreamReader(is, StandardCharsets.UTF_8))) { + CSVReaderBuilder csvBuilder = new CSVReaderBuilder(reader) + .withCSVParser(parser); + try (CSVReader csv = csvBuilder.build()) { + String[] line = csv.readNextSilently(); // Eliminate header + while (csv.peek() != null) { + line = csv.readNext(); + contentLineConsumer.accept(line); + } + } + } catch (CsvValidationException e) { + throw new IOException("Invalid csv file", e); //$NON-NLS-1$ + } + } + + public static void readCSVFromFile(String filename, Consumer contentLineConsumer) + throws IOException { + File file = new File(filename); + readCSVFromInputStream(new FileInputStream(file), contentLineConsumer); + } + + /** get a CSV file from a URL, download and parse it, and keep values in memory + * @param url the address of the CSV file + * @param contentLineConsumer the variable used to store the data + * @throws IOException if it's impossible to download the file + */ + public static void readCSVFromURL(String url, Consumer contentLineConsumer) + throws IOException { + readCSVFromInputStream(new URL(url).openStream(), contentLineConsumer); + } + + /** Save our current CSV variable's data into an actual file + * @param filename the saved file's name and path + * @param contentLineConsumer our data variable + * @throws IOException if we can't write the data into the file + */ + public static void writeCSVToFile(String filename, + Stream contentLinesConsumer) throws IOException { + try (FileWriter writer = new FileWriter(filename, StandardCharsets.UTF_8)) { + CSVWriterBuilder wBuilder = new CSVWriterBuilder(writer).withSeparator(';'); + try (ICSVWriter csv = wBuilder.build()) { + contentLinesConsumer.forEachOrdered(csv::writeNext); + } + } + } + + // /** Save our current CSV variable's data into an actual file + // * @param filename the saved file's name and path + // * @param contentLineConsumer our data variable + // * @throws IOException if we can't write the data into the file + // */ + // public static void writeCSVToFile(String filename, + // Stream contentLinesConsumer) throws IOException { + // try (FileWriter writer = new FileWriter(filename, StandardCharsets.UTF_8)) { + // CSVWriterBuilder wBuilder = new CSVWriterBuilder(writer).withSeparator(';'); + // try (ICSVWriter csv = wBuilder.build()) { + // contentLinesConsumer.forEachOrdered(line -> Arrays.stream(line).forEach(csv::writeNext)); + // } + // } + // } + +} From 49bc9a038c912a9d61b77d365564c9bdc210e7e0 Mon Sep 17 00:00:00 2001 From: MAMBILA TETE jean philipp <@mambilat> Date: Tue, 23 Apr 2024 21:13:30 +0200 Subject: [PATCH 5/6] [chore] jtable not displayed correctly --- .../java/fr/u_paris/gla/project/gui/View.form | 48 ++++++-- .../java/fr/u_paris/gla/project/gui/View.java | 108 ++++++++++++------ 2 files changed, 112 insertions(+), 44 deletions(-) diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.form b/src/main/java/fr/u_paris/gla/project/gui/View.form index 703d5bc..21d3701 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.form +++ b/src/main/java/fr/u_paris/gla/project/gui/View.form @@ -58,7 +58,7 @@ - + @@ -100,6 +100,7 @@ + @@ -109,7 +110,12 @@ - + + + + + + @@ -135,9 +141,18 @@ + + + + + + + + + - + @@ -156,13 +171,6 @@ - - - - - - - @@ -204,6 +212,26 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.java b/src/main/java/fr/u_paris/gla/project/gui/View.java index 7fc0831..d6db5f1 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.java +++ b/src/main/java/fr/u_paris/gla/project/gui/View.java @@ -4,6 +4,7 @@ import fr.u_paris.gla.project.itinerary.Stop; import javax.swing.*; import javax.swing.table.DefaultTableModel; +import javax.swing.table.TableModel; import java.awt.*; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; @@ -11,7 +12,7 @@ import java.awt.event.KeyAdapter; import java.awt.event.KeyEvent; import java.util.ArrayList; -public class View extends JFrame{ +public class View extends JFrame { private JPanel Cardpanel; private JMenuItem Home; private JMenuItem Network; @@ -27,13 +28,22 @@ public class View extends JFrame{ private JTable table; private JScrollPane mypane; + private JPanel ItineraryPanel; + private JMenuItem Itinerary; private ArrayList StopList; - private Stop StopCur; + private Stop departureCur; + + private Stop arrivalCur; + + private String searchCur; private ArrayList searchRes; + private int count = 0; + + public View(ArrayList s) throws HeadlessException { this.createUIComponents(); this.StopList = s; @@ -43,7 +53,8 @@ public class View extends JFrame{ setTitle("app"); setExtendedState(JFrame.MAXIMIZED_BOTH); //setUndecorated(true); - setVisible(true);; + setVisible(true); + ; setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); Home.addActionListener(new ActionListener() { @@ -59,8 +70,10 @@ public class View extends JFrame{ Network.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { + showSearch(s); Cardpanel.removeAll(); Cardpanel.add(NetworkPanel); + Cardpanel.repaint(); Cardpanel.revalidate(); } @@ -82,76 +95,103 @@ public class View extends JFrame{ public void keyReleased(KeyEvent e) { super.keyReleased(e); if (e.getKeyCode() == KeyEvent.VK_ENTER) { - System.out.println("Enter key released"); + + searchCur = textField1.getText(); + showSearch(s); + System.out.println("Enter key released with text " + searchCur); + Cardpanel.removeAll(); + Cardpanel.add(NetworkPanel); + + Cardpanel.repaint(); + Cardpanel.revalidate(); } } }); + searchButton.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + Cardpanel.removeAll(); + searchCur = textField1.getText(); + showSearch(s); + System.out.println("search button clicked with text " + searchCur); + Cardpanel.add(NetworkPanel); + + Cardpanel.repaint(); + Cardpanel.revalidate(); + } + }); } - - public static void main(String[] args) { ArrayList 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)); - System.out.println(s.toString()); View v = new View(s); - v.showSearch(s); - + } private void createUIComponents() { // TODO: place custom component creation code here - table = new JTable(); - dtm = new DefaultTableModel(0, 0); - String[] header = new String[] { "Line", "Stop" }; + dtm = new DefaultTableModel(1, 2); + + String[] header = new String[]{"Line", "Stop"}; dtm.setColumnIdentifiers(header); - table.setModel(dtm); + dtm.setValueAt("test", 0, 0); + dtm.setValueAt("test", 0, 1); + table = new JTable(dtm); + table.setPreferredScrollableViewportSize(table.getPreferredSize()); + mypane = new JScrollPane(table); } - private void showSearch(ArrayList stops) { + public void showSearch(ArrayList stops) { // Clear existing rows from the table dtm.setRowCount(0); // Add new rows based on the search results + count = 0; for (Stop stop : stops) { // Add a row to the table with Stop's line in the first column and Stop's name in the second column - dtm.addRow(new Object[]{stop.getLines(), stop.getName()}); + dtm.addRow(new Object[]{stop.getLines().iterator().next(), stop.getName()}); + ++count; } - this.displayTableValues(); - dtm.fireTableDataChanged(); - table.repaint(); + + table.setModel(dtm); table.revalidate(); - Cardpanel.repaint(); - Cardpanel.revalidate(); + table.repaint(); + + mypane.setViewportView(table); + mypane.revalidate(); + mypane.repaint(); + + NetworkPanel.revalidate(); + NetworkPanel.repaint(); + + + this.displayTableValues(); } - private void displayTableValues() { - int rowCount = dtm.getRowCount(); - int columnCount = dtm.getColumnCount(); - - // Iterate over each row - for (int row = 0; row < rowCount; row++) { - // Iterate over each column - for (int col = 0; col < columnCount; col++) { - // Get the value at the current cell - Object value = dtm.getValueAt(row, col); - // Display the value - System.out.println("Value at row " + row + ", column " + col + ": " + value); + public void displayTableValues() { + TableModel mod = table.getModel(); + for (int row = 0; row < mod.getRowCount(); row++) { + for (int column = 0; column < mod.getColumnCount(); column++) { + System.out.print(mod.getValueAt(row, column).toString() + " "); } - } - } + System.out.print(";"); + } + System.out.println(); + + } } From c30835654927ab793dd84d9b1dfebc8d030149d2 Mon Sep 17 00:00:00 2001 From: MAMBILA TETE jean philipp <@mambilat> Date: Thu, 25 Apr 2024 23:51:55 +0200 Subject: [PATCH 6/6] [feat] jtable display fix and listener --- .../java/fr/u_paris/gla/project/gui/View.form | 39 +++++++- .../java/fr/u_paris/gla/project/gui/View.java | 98 +++++++++++++------ 2 files changed, 105 insertions(+), 32 deletions(-) diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.form b/src/main/java/fr/u_paris/gla/project/gui/View.form index 21d3701..928c8a8 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.form +++ b/src/main/java/fr/u_paris/gla/project/gui/View.form @@ -83,7 +83,7 @@ - + @@ -104,14 +104,45 @@ - + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/main/java/fr/u_paris/gla/project/gui/View.java b/src/main/java/fr/u_paris/gla/project/gui/View.java index d6db5f1..e6bc8ef 100644 --- a/src/main/java/fr/u_paris/gla/project/gui/View.java +++ b/src/main/java/fr/u_paris/gla/project/gui/View.java @@ -6,11 +6,9 @@ import javax.swing.*; import javax.swing.table.DefaultTableModel; import javax.swing.table.TableModel; import java.awt.*; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; -import java.awt.event.KeyAdapter; -import java.awt.event.KeyEvent; +import java.awt.event.*; import java.util.ArrayList; +import java.util.stream.Collectors; public class View extends JFrame { private JPanel Cardpanel; @@ -23,19 +21,22 @@ public class View extends JFrame { private JButton searchButton; private JPanel HomePanel; private JPanel MainPanel; - private DefaultTableModel dtm; + private DefaultTableModel model; private JTable table; private JScrollPane mypane; private JPanel ItineraryPanel; private JMenuItem Itinerary; + private JPanel stationsPanel; + private JLabel departText; + private JLabel arrText; private ArrayList StopList; - private Stop departureCur; + private String departureCur; - private Stop arrivalCur; + private String arrivalCur; private String searchCur; @@ -45,9 +46,11 @@ public class View extends JFrame { public View(ArrayList s) throws HeadlessException { - this.createUIComponents(); + model = (DefaultTableModel) table.getModel(); + model.setColumnCount(2); + model.setColumnIdentifiers(new Object[]{"Line", "Stop"}); this.StopList = s; - this.StopCur = StopList.get(0); + setContentPane(MainPanel); setTitle("app"); @@ -121,8 +124,51 @@ public class View extends JFrame { Cardpanel.revalidate(); } }); + table.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + System.out.println("MouseClick: " + e.getX() + ";" + e.getY()); + showOptionsDialog(table, e.getX(), e.getY()); + + } + }); + + + mypane.addMouseListener(new MouseAdapter() { + @Override + public void mouseClicked(MouseEvent e) { + super.mouseClicked(e); + } + }); } + private void showOptionsDialog(JTable table, int x, int y) { + int selectedRow = table.rowAtPoint(new Point(x, y)); + if (selectedRow != -1) { // If a row is selected + + String stationSel = (String) table.getValueAt(selectedRow, 1); + + // Options to set Departure, Arrival, or Cancel + Object[] options = {"Departure", "Arrival", "Cancel"}; + int choice = JOptionPane.showOptionDialog(null, "What action would you like to perform for " + stationSel + "?", "Action Selection", + JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, options[2]); + + // Handling the choice + if (choice == 0) { + this.departureCur = stationSel; + this.departText.setText("Departure: " + stationSel); + } else if (choice == 1) { + this.arrivalCur = stationSel; + this.arrText.setText("Arrival: " + stationSel); + } else { + System.out.println("rien"); + } + System.out.println("Départ: " + this.departureCur + "; Arrivée: " + this.arrivalCur); + } + } + + public static void main(String[] args) { ArrayList s = new ArrayList<>(); @@ -134,38 +180,34 @@ public class View extends JFrame { } - private void createUIComponents() { - // TODO: place custom component creation code here - dtm = new DefaultTableModel(1, 2); - - String[] header = new String[]{"Line", "Stop"}; - dtm.setColumnIdentifiers(header); - dtm.setValueAt("test", 0, 0); - dtm.setValueAt("test", 0, 1); - table = new JTable(dtm); - table.setPreferredScrollableViewportSize(table.getPreferredSize()); - - mypane = new JScrollPane(table); - - - } - public void showSearch(ArrayList stops) { // Clear existing rows from the table - dtm.setRowCount(0); + + model.setRowCount(0); + model.setColumnCount(2); + // Add new rows based on the search results count = 0; for (Stop stop : stops) { // Add a row to the table with Stop's line in the first column and Stop's name in the second column - dtm.addRow(new Object[]{stop.getLines().iterator().next(), stop.getName()}); + model.addRow(new Object[]{String.join(",", stop.getLines()), stop.getName()}); ++count; } - table.setModel(dtm); + System.out.println(stops.toString()); + for (int i = 0; i < model.getRowCount(); i++) { + for (int j = 0; j < model.getColumnCount(); j++) { + System.out.print("valeur at coord " + i +";" + j +": " + model.getValueAt(i, j) + "\t"); + } + System.out.println(); + } + + System.out.println(count); + table.revalidate(); table.repaint();