0

first of all, I'm aware of the title being a a bit ambiguous, so I'm going to try to explain the issues I'm having more clearly.

I've created a program that imports data from csv.files, which consists of measure points like date, time, heart rate etc. The user is first met with a login screen, that connects to a database, which then lets the user get access to the mainframe of the program.

The program consists of a class called Activity, which has a method that reads the activity, along with some other methods. This class then gets impemented by another class called Datapoint, which splits the different values from the csv.files into measuring points like date, time, longitude and latitude.

Finally, the third class that only consists of data is called Statistics, which takes the values and adds them into datapoints such as average, min and max speed etc.

Now to my problem. I've created a GUI for this which let's the user import csv.files, and then add the datapoints from the file into a map, a plotted diagram, and a page which shows the values from the statistics class. This works fine, and everything is updated when imported.

The activities chosen are then being added to a JList, from where the user can chose a certain activity, which preferrably a mouselistener. When the activity in the list is double-clicked, the graphs should update with the chosen activity's datapoints from the list, but I don't know how to do it. The other issue is that the imported activity writes over the old one, so that the JList contains a duplicate of the activities imported.

Instead of just showing the GUI, I figured I'd provide you with all the information regarding the classes that the GUI handles, so it's easier for you to pinpoint how I should solve my problem. I'll post the Classes below.

Activity:

package model;

import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

public class Activity { 

    private String file;
    private String title;
    private String location;
    private String note;
    private String activityType;
    private String category;

    private List<DataPoint> dataPoints = new ArrayList<DataPoint>();
    private String line = "";
    //private String[] dataPoints;

    public Activity (){

        //csvFileReader("activity_103378385.csv");


    }

    public  void csvFileReader(String file) {
        try {
            this.file = file;
            BufferedReader in = new BufferedReader(new FileReader(file));
            line = in.readLine(); // läser bort första raden av aktiviteten
            while ((line = in.readLine()) != null) {
                line = line.replaceAll(",", ".");
                String[] data = line.split(";");
                dataPoints.add(new DataPoint(data));   
            }

            in.close();                 

        /*   for (DataPoint act : dataPoints)             
                System.out.println(act); */

        } 
        catch (FileNotFoundException e) {
            e.printStackTrace();
        }
        catch (IOException e) {
            e.printStackTrace();
        }


    }

    public List<DataPoint> getData() {
        return dataPoints;
    }
    public void clear() {
        dataPoints.clear();
    }

    public String getTitle() {
        return title;

    }
    public String getLocation() {
        return location;

    }
    public String getNote() {
        return note;

    }
    public String getActivityType() {
        return activityType;

    }
    public String getCategory() {
        return category;

    }

    @Override
    public String toString(){
        return file.substring(file.lastIndexOf("\\")+1, file.length()-4);
    }



}

And the GUI (where I'm facing the difficulties):

 package view;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Observable;
import java.util.Vector;

import javax.swing.*;

import dao.UserDAO;
import db.DemoDB;
import model.Activity;
import model.DataPoint;
import model.Statistics;

public class LoginGUI extends JFrame{
    DemoDB DemoDBSingleton = null;
    JScrollPane scrollpane;
    private JTabbedPane tabbedPane = new JTabbedPane();
    UserDAO userDao = new UserDAO();
    JFrame mainFrame = new JFrame("Välkommen till din app");
    JFrame f = new JFrame("User Login");
    JLabel l = new JLabel("Användarnamn:");
    JLabel l1 = new JLabel("Lösenord:");
    JTextField textfieldUsername = new JTextField(10);
    JPasswordField textfieldPassword = new JPasswordField(10);
    JButton loginButton = new JButton("Logga In");
    JFileChooser fc = new JFileChooser();
    JMenuBar mb = new JMenuBar();
    JFrame jf;
    JMenu menu;
    JMenuItem importMenu, exitMenu;

    JList<Activity> listAct = new JList<Activity>();
    List<Activity> activityList = new ArrayList<Activity>();


    //MyController controller = new MyController();

    Activity activity = new Activity();
    List<DataPoint> listOfDataPoints = activity.getData();  
    Statistics stats = new Statistics(listOfDataPoints);



    public LoginGUI() throws IOException {

        loginButton.addActionListener(n -> {
            try {
                ListenerLogIn();
            } catch (IOException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        });

        DemoDBSingleton = DemoDB.getInstance();
    //  logInframe();

    }


    private JFrame ProgramMainFrame() throws IOException {

        mainFrame.setSize(800, 600);
        mainFrame.setVisible(true);
        mainFrame.setJMenuBar(mb);
        mainFrame.getContentPane().setLayout(new BorderLayout());



        mainFrame.getContentPane().add(tabbedPane, BorderLayout.CENTER);


        JMenuBar mb = new JMenuBar();
        menu = new JMenu("Meny");
        importMenu = new JMenuItem("Importera aktivitet");
        importMenu.addActionListener(importActionListener);
        exitMenu = new JMenuItem("Avsluta program");
        exitMenu.addActionListener(exitActionListener);
        menu.add(importMenu);
        menu.add(exitMenu);
        mb.add(menu);
        mainFrame.setJMenuBar(mb);

        return mainFrame;

        /*
         * JPanel listholder = new JPanel();
         * listholder.setBorder(BorderFactory.createTitledBorder("ListPanel"));
         * mainFrame.add(listholder); listholder.setVisible(true);
         * listholder.setSize(500,400);
         */

    }

    private JPanel createViewActPanel() {
        JPanel analogM = new JPanel(new BorderLayout());
        analogM.setBackground(new Color(224, 255, 255));

        scrollpane = new JScrollPane(listAct);
        scrollpane.setPreferredSize(new Dimension(400, 200));

        analogM.add(scrollpane, BorderLayout.WEST);

        return analogM;
    }

    private JPanel createViewDiagramPanel() {

        JPanel panel = new JPanel(new GridLayout(4, 1));

        if( activity.getData().size() > 0) {
            panel.add(new PlotView("HR", activity, tp -> tp.getHeartRate()));
            panel.add(new PlotView("Altitude", activity, tp -> tp.getAltitude()));
            panel.add(new PlotView("Speed", activity, tp -> tp.getSpeed()));
            panel.add(new PlotView("Cadence", activity, tp -> tp.getCadence()));
            panel.setVisible(true);
        }

        return panel;
    }

    private JPanel createViewStatisticsPanel() {
        stats.calculateStatistics();
        JPanel statPanel = new JPanel(new GridLayout(2, 3));
        statPanel.setPreferredSize(new Dimension(1000, 500));
        // statPanel.setBorder(BorderFactory.createEmptyBorder(2,2,2,2));

        JPanel timePanel = new JPanel();
        timePanel.setBorder(BorderFactory.createTitledBorder("Tid/Distans"));
        timePanel.setBackground(new Color(224, 255, 255));
        JTextArea tdp = new JTextArea("\n Starttid: " + stats.getStartTime() + "\n Slutlig tid: " + stats.getEndTime()
                + "\n Total tid: " + stats.getTotalTime() + "\n Total distans" + stats.getTotalDistance());
        tdp.setBackground(new Color(224, 255, 255));
        timePanel.add(tdp);
        statPanel.add(timePanel);

        JPanel startTimepanel = new JPanel();
        startTimepanel.setBorder(BorderFactory.createTitledBorder("Altitud"));
        startTimepanel.setBackground(new Color(224, 255, 255));
        JTextArea stp = new JTextArea("\n Lägsta altitud: " + stats.getMinAltitude() + "\n Högsta altitud : "
                + stats.getMaxAltitude() + "\n Genomsnittlig altitud: " + stats.getAvgAltitude());
        stp.setBackground(new Color(224, 255, 255));
        startTimepanel.add(stp);
        statPanel.add(startTimepanel);

        JPanel startTimepanel1 = new JPanel();
        startTimepanel1.setBorder(BorderFactory.createTitledBorder("Hastighet"));
        startTimepanel1.setBackground(new Color(224, 255, 255));
        JTextArea stp1 = new JTextArea("\n Lägsta hastighet: " + stats.getMinSpeed() + "\n Högsta hastighet : "
                + stats.getMaxSpeed() + "\n Genomsnittlig hastighet: " + stats.getAvgSpeed());
        stp1.setBackground(new Color(224, 255, 255));
        startTimepanel1.add(stp1);
        statPanel.add(startTimepanel1);

        JPanel startTimepanel2 = new JPanel();
        startTimepanel2.setBorder(BorderFactory.createTitledBorder("Puls"));
        startTimepanel2.setBackground(new Color(224, 255, 255));
        JTextArea stp2 = new JTextArea("\n Lägsta puls: " + stats.getMinHeartrate() + "\n Högsta puls : "
                + stats.getMaxHeartrate() + "\n Genomsnittlig puls: " + stats.getAvgHeartrate());
        stp2.setBackground(new Color(224, 255, 255));
        startTimepanel2.add(stp2);
        statPanel.add(startTimepanel2);

        JPanel startTimepanel3 = new JPanel();
        startTimepanel3.setBorder(BorderFactory.createTitledBorder("Kadens"));
        startTimepanel3.setBackground(new Color(224, 255, 255));
        JTextArea stp3 = new JTextArea("\n Lägsta kadens: " + stats.getMinCandence() + "\n Högsta kadens : "
                + stats.getMaxCandence() + "\n Genomsnittlig kadens: " + stats.getAvgCandence());
        stp3.setBackground(new Color(224, 255, 255));
        startTimepanel3.add(stp3);
        statPanel.add(startTimepanel3);

        JPanel startTimepanel4 = new JPanel();
        startTimepanel4.setBorder(BorderFactory.createTitledBorder("Lutning"));
        startTimepanel4.setBackground(new Color(224, 255, 255));
        JTextArea stp4 = new JTextArea("\n Lägsta lutning: " + stats.getMinTilt() + "\n Högsta lutning : "
                + stats.getMaxTilt() + "\n Genomsnittlig lutning: " + stats.getAvgTilt());
        stp4.setBackground(new Color(224, 255, 255));
        startTimepanel4.add(stp4);
        statPanel.add(startTimepanel4);

        return statPanel;
    }

    private JPanel createViewMapPanel() {
        JPanel mapPane = new JPanel();
        if(listOfDataPoints.size() > 0) {
            mapPane.add(new PlotMap(listOfDataPoints));
        }
        mapPane.setBackground(new Color(224, 255, 255));
        mapPane.setVisible(true);       

        return mapPane;
    }

    ActionListener importActionListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            int returnValue = fc.showOpenDialog(mainFrame);
            if(returnValue == JFileChooser.APPROVE_OPTION)
            {
                File file = fc.getSelectedFile();
                if(file != null)
                {   
                    activity.clear();
                    String fileName = file.getAbsolutePath();
                    activity.csvFileReader(fileName);
                    listOfDataPoints = activity.getData();
                    activityList.add(activity);
                    listAct.setListData(new Vector<Activity>(activityList));


                    tabbedPane.removeAll();


                    tabbedPane.add("Dina Aktiviteter", createViewActPanel());
                    tabbedPane.add("Diagram för vald aktivitet", createViewDiagramPanel());
                    tabbedPane.add("Statistik för vald aktivitet", createViewStatisticsPanel());
                    tabbedPane.add("Kartbild över vald aktivitet", createViewMapPanel());
                    mainFrame.getContentPane().add(tabbedPane, BorderLayout.CENTER);


                }

            }
        }

    };

    ActionListener exitActionListener = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent e) {
            System.exit(0);
        }

    };


    public static void main(String[] args) throws IOException {
        new LoginGUI();

    }

}
kwlk17
  • 13
  • 4
  • That's a lot of code, most of it not related to the problem at hand. Please consider creating a new separate [mre] program for your question, one that compiles and runs, but that pares down the code to the essentials to illustrate your problem for us. Remove any database or file dependencies for this program and instead hard-code a small sampling of the data into the program. Please read this important link given above. – Hovercraft Full Of Eels Nov 02 '19 at 12:49
  • @HovercraftFullOfEels I've edited my question to only contain the GUI and the Activity, I've also removed the methods inside the GUI that are irrelevant to the issue. – kwlk17 Nov 02 '19 at 12:54
  • Nah, please read or re-read the link that I've given. Again, the program needs to be runnable and useable by us. Your code still shows database dependencies and such. Again, the link will tell you what you need to do. Please comment back if any of it is confusing. – Hovercraft Full Of Eels Nov 02 '19 at 12:58
  • And what is `PlotView`? -- more dependencies that we don't have – Hovercraft Full Of Eels Nov 02 '19 at 12:59
  • Plotview is a class that plots the datapoints into a diagram, didn't want to post it because that would add even more code to the question, which is what you said there's shouldnt be. – kwlk17 Nov 02 '19 at 13:02
  • No, I didn't say that, please re-read. I recommended that you create a new minimal program as fully explained in the link. If you take the time to read the link, you wouldn't have posted what you just did. Please, again, read it as it is there to *help you*. – Hovercraft Full Of Eels Nov 02 '19 at 13:03
  • The problem is that I don't know how to compile this into one minal program, nor do I have the time. The problems im facing in the GUI is that I want to add a mouselistener to the JList so that the imported activity is updated, and the other issue is that the imported activity writes over the old one, so that the JList contains a duplicate of the activities imported. – kwlk17 Nov 02 '19 at 13:12
  • I agree, that it would be time-consuming, not easy, and certainly not absolutely required. But then it would make it much easier to answer this question, and so *may* be time worth spending. It's up to you. If you get a decent answer to the question without an [mre], then great, but if not, then consider creating one today, or in the next few days. I know that if I were considering answering this question, I'd have to create one of these myself, but then since it is your question, my thinking is that this effort really should be yours. Others may think different. – Hovercraft Full Of Eels Nov 02 '19 at 13:14
  • In fact, I *did* consider answering and uploaded your original code into my IDE, but I couldn't tweak it easily into any runnable form. I do wish you the best of luck, whichever way you decide to go – Hovercraft Full Of Eels Nov 02 '19 at 13:17
  • I do see where you're coming from, and I will absolutely take it into consideration when creating another project, but it's just to time consuming for me at this place, so I hope that one of you guys maybe could take a look at just the GUI and tell me what the issue is. I'm pretty sure the duplicate import has something to do with the list in the importActionListener() method, but I can't wrap my head around why. – kwlk17 Nov 02 '19 at 13:17
  • And one more thing (I'll probably delete most of these comments later): best to create your code from the beginning to be individually testable in isolation just in a general sense, using mock classes or a formal mocking system. This will make it so much easier for you to enhance, debug, or change your pograms, or failing that, asking questions here with complete small testable code units. In other words, create your code to be testable. – Hovercraft Full Of Eels Nov 02 '19 at 13:19
  • I will consider that in the future, I just started programming this year, hence my bad structured code. – kwlk17 Nov 02 '19 at 13:25
  • @p18wisa02 can you debug your code? How many times is actionPerformed being called? – Lajos Arpad Nov 02 '19 at 14:16

0 Answers0