Custom tooltip for JFreeChart Gantt chart in Java

94 Views Asked by At

I am new to JFreeChart, and I don't understand how all the classes work together yet. I am trying to create a Gantt chart with custom labels and custom tooltip. The custom labels work (though I don't think I did it the proper clean way), but I don't get the custom tooltip to work.

After pressing on a button in another panel I send the required data (a date) I get from the database to the class that generates the gantt chart. With the date I got as a variable I get all the information for this date from the database and put it in the gantt chart.

This is how my gantt chart looks right now: enter image description here

my main class looks like that:

import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.Connection;
import java.util.Calendar;
import javax.swing.*;

import info.clearthought.layout.TableLayout;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;

public class Schichtplanner extends JFrame {
    private static final long serialVersionUID = 1L;
    double busX[] = new double[]{SchichtplannerConstants.GUI_BORDER, 250, TableLayout.FILL, TableLayout.FILL};
    double busY[] = new double[]{SchichtplannerConstants.GUI_BORDER, 35, SchichtplannerConstants.DISTANCE_BUTTONS, 35, SchichtplannerConstants.DISTANCE_BUTTONS, 35, SchichtplannerConstants.DISTANCE_BUTTONS, 35};

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            public void run() {
                //System.setProperty("https.protocols", "TLSv1");
                try {
                    Schichtplanner frame = new Schichtplanner();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    public Schichtplanner() {
        //JFrame frame = new JFrame("Schichtplanner");
        this.setTitle("Schichtplanungs-App");
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setExtendedState(JFrame.MAXIMIZED_BOTH);

        JPanel panelMain = new JPanel();
        add(panelMain);

        panelMain.setLayout(new TableLayout(new double[][]{busX, busY}));

        JButton buttonMitarbeiterVerwalten = new JButton("Mitarbeiter verwalten");
        panelMain.add(buttonMitarbeiterVerwalten, "1,1,1,1"); // Adds Button to content pane of frame
        buttonMitarbeiterVerwalten.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                //MitarbeiterVerwalten mitarbeiterVerwaltenFrame = new MitarbeiterVerwalten();
            }
        });

        JButton buttonAuftragVerwalten = new JButton("Auftrag verwalten");
        panelMain.add(buttonAuftragVerwalten, "1,3,1,3"); // Adds Button to content pane of frame
        buttonAuftragVerwalten.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                //AuftragVerwalten auftragVerwaltenFrame = new AuftragVerwalten();
            }
        });

        JButton buttonSucheAuftrag = new JButton("Auftrag suchen");
        panelMain.add(buttonSucheAuftrag, "1,5,1,5"); // Adds Button to content pane of frame

        JButton buttonKalenderAnsicht = new JButton("Kalenderansicht");
        panelMain.add(buttonKalenderAnsicht, "1,7,1,7"); // Adds Button to content pane of frame
        buttonKalenderAnsicht.addActionListener( new ActionListener()
        {
            public void actionPerformed(ActionEvent e)
            {
                try {
                    AuftragsÜbersicht auftragsÜbersicht = new AuftragsÜbersicht("2023-08-17");
                } catch (ParseException ex) {
                    ex.printStackTrace();
                }
            }
        });

        setVisible(true);
        panelMain.setVisible(true);
    }
}  

And my gantt chart class is like that:

import com.github.lgooddatepicker.components.DatePicker;
import info.clearthought.layout.TableLayout;
import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.block.BlockBorder;
import org.jfree.chart.labels.*;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.renderer.category.CategoryItemRenderer;
import org.jfree.chart.renderer.category.StandardBarPainter;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.IntervalCategoryDataset;
import org.jfree.data.gantt.Task;
import org.jfree.data.gantt.TaskSeries;
import org.jfree.data.gantt.TaskSeriesCollection;
import org.jfree.ui.RectangleInsets;
import org.jfree.ui.TextAnchor;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.*;
import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.List;

import org.jfree.chart.renderer.category.StandardBarPainter;

public class AuftragsÜbersicht extends JFrame {

private ArrayList<Calendar> auftragsBeginn, auftragsEnde;
private ArrayList<String> auftragsAdresse, auftragsPLZ, mitarbeiterVorname, mitarbeiterNachname;
private ArrayList<Integer> liegenschaftsnummer;

public AuftragsÜbersicht(String date) throws ParseException {
    double busX[] = new double[]{SchichtplannerConstants.GUI_BORDER, 250, TableLayout.FILL, TableLayout.FILL, SchichtplannerConstants.GUI_BORDER};
    double busY[] = new double[]{SchichtplannerConstants.GUI_BORDER, 35, 40, 35, SchichtplannerConstants.DISTANCE_BUTTONS, 35, 35, SchichtplannerConstants.DISTANCE_BUTTONS, 35, 35};
    auftragsBeginn = new ArrayList<>();
    auftragsEnde = new ArrayList<>();
    auftragsAdresse = new ArrayList<>();
    auftragsPLZ = new ArrayList<>();
    mitarbeiterVorname = new ArrayList<>();
    mitarbeiterNachname = new ArrayList<>();
    liegenschaftsnummer = new ArrayList<>();

    this.setTitle("Tagesübersicht Aufträge");
    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
    this.setSize(screenSize.width, screenSize.height);
    setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);

    try
    {
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
    } catch (Exception e) {
        e.printStackTrace();
    }

    /********************************/
    // Create dataset
    IntervalCategoryDataset dataset = getCategoryDataset(date);

    // Create chart
    JFreeChart chart = ChartFactory.createGanttChart(date, "Mitarbeiter", "Zeitachse", dataset, false, true, false);
    chart.setBackgroundPaint(Color.white);

    //chart.setBorderVisible(false);
    CategoryPlot plot = (CategoryPlot) chart.getPlot();
    plot.setDomainGridlinePaint(Color.white);
    plot.setOutlinePaint(Color.white);
    plot.setBackgroundPaint(Color.white);
    //plot.setOutlineVisible(false);

    plot.getRenderer().setBaseToolTipGenerator( new MyToolTipGenerator( "{0}, {1}: ", DateFormat.getTimeInstance(DateFormat.SHORT)));

    ChartPanel panel = new ChartPanel(chart);
    setContentPane(panel);
    setVisible(true);

    /*******************************/
    setResizable(false);
}

private IntervalCategoryDataset getCategoryDataset(String date) throws ParseException {
    date = date + " 00:00:00.00000";
    Timestamp timestamp = Timestamp.valueOf(date);
    Timestamp timestamp2 = addDays(timestamp,1);

    /*try {
        Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3307/schichtplanung", "root", "admin");

        PreparedStatement st = (PreparedStatement) connection.prepareStatement("SELECT schichtplanung.auftrag.auftragsbeginn, schichtplanung.auftrag.auftragsende, schichtplanung.auftrag.auftragsadresse, schichtplanung.auftrag.auftragsplz, schichtplanung.auftrag.liegenschaftsnummer, schichtplanung.mitarbeiter.vorname, schichtplanung.mitarbeiter.nachname FROM schichtplanung.auftrag INNER JOIN schichtplanung.mitarbeiter ON schichtplanung.auftrag.mitarbeiterid=schichtplanung.mitarbeiter.mitarbeiterid WHERE schichtplanung.auftrag.auftragsbeginn >= ? AND schichtplanung.auftrag.auftragsbeginn < ?");
        st.setTimestamp(1, timestamp);
        st.setTimestamp(2, timestamp2);
        ResultSet rs = st.executeQuery();
        while (rs.next()) {
            Calendar calendar1 = Calendar.getInstance();
            calendar1.setTimeInMillis(rs.getTimestamp(1).getTime());
            getAuftragsBeginnList().add(calendar1);

            Calendar calendar2 = Calendar.getInstance();
            calendar2.setTimeInMillis(rs.getTimestamp(2).getTime());
            getAuftragsEndeList().add(calendar2);

            getAuftragsAdresseList().add(rs.getString(3));
            getAuftragsPLZList().add(rs.getString(4));
            getLiegenschaftsnummerList().add(rs.getInt(5));
            getMitarbeiterVornameList().add(rs.getString(6));
            getMitarbeiterNachnameList().add(rs.getString(7));
        }
        rs.close();
        st.close();
    } catch (SQLException sqlException) {
        sqlException.printStackTrace();
    }*/

    Calendar cal = Calendar.getInstance();
    SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    cal.setTime(sdf.parse("2023-08-17 07:30:00"));// all done
    auftragsBeginn.add(cal);

    Calendar cal1 = Calendar.getInstance();
    SimpleDateFormat sdf1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    cal1.setTime(sdf1.parse("2023-08-17 15:30:00"));// all done
    auftragsEnde.add(cal1);

    auftragsAdresse.add("Ohmstraße 32");
    auftragsPLZ.add("45711");
    liegenschaftsnummer.add(1);
    mitarbeiterVorname.add("Michael");
    mitarbeiterNachname.add("Thompson");

    Calendar cal2 = Calendar.getInstance();
    SimpleDateFormat sdf2 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    cal2.setTime(sdf2.parse("2023-08-17 09:00:00"));// all done
    auftragsBeginn.add(cal2);

    Calendar cal3 = Calendar.getInstance();
    SimpleDateFormat sdf3 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    cal3.setTime(sdf3.parse("2023-08-17 16:30:00"));// all done
    auftragsEnde.add(cal3);

    auftragsAdresse.add("Fegestraße 5");
    auftragsPLZ.add("44623");
    liegenschaftsnummer.add(2);
    mitarbeiterVorname.add("Hasan");
    mitarbeiterNachname.add("Sekici");

    Calendar cal4 = Calendar.getInstance();
    SimpleDateFormat sdf4 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    cal4.setTime(sdf4.parse("2023-08-17 08:00:00"));// all done
    auftragsBeginn.add(cal4);

    Calendar cal5 = Calendar.getInstance();
    SimpleDateFormat sdf5 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    cal5.setTime(sdf5.parse("2023-08-17 17:30:00"));// all done
    auftragsEnde.add(cal5);

    auftragsAdresse.add("Sambaweg 10");
    auftragsPLZ.add("44141");
    liegenschaftsnummer.add(3);
    mitarbeiterVorname.add("Jon");
    mitarbeiterNachname.add("Schnee");

    TaskSeries series1 = new TaskSeries("Aufträge");
    for (int i = 0; i < auftragsAdresse.size(); i++) {
        series1.add(new Task(getMitarbeiterVornameList().get(i) + " " + getMitarbeiterNachnameList().get(i), getAuftragsBeginnList().get(i).getTime(), getAuftragsEndeList().get(i).getTime()));
        System.out.println(getMitarbeiterVornameList().get(i) + " " + getMitarbeiterNachnameList().get(i) + " BeginnZeit: " + getAuftragsBeginnList().get(i).getTime() + " EndeZeit: " + getAuftragsEndeList().get(i).getTime());
    }

    TaskSeriesCollection dataset = new TaskSeriesCollection();
    dataset.add(series1);
    return dataset;
}

public ArrayList<Calendar> getAuftragsBeginnList() {
    return auftragsBeginn;
}

public ArrayList<Calendar> getAuftragsEndeList() {
    return auftragsEnde;
}

public ArrayList<String> getAuftragsAdresseList() {
    return auftragsAdresse;
}

public ArrayList<String> getAuftragsPLZList() {
    return auftragsPLZ;
}

public ArrayList<String> getMitarbeiterVornameList() {
    return mitarbeiterVorname;
}

public ArrayList<String> getMitarbeiterNachnameList() {
    return mitarbeiterNachname;
}

public ArrayList<Integer> getLiegenschaftsnummerList() {
    return liegenschaftsnummer;
}

public Timestamp addDays(Timestamp date, int days) {
    Calendar cal = Calendar.getInstance();
    cal.setTime(date);// w ww.  j ava  2  s  .co m
    cal.add(Calendar.DATE, days); //minus number would decrement the days
    return new Timestamp(cal.getTime().getTime());

}
}

class MyToolTipGenerator extends IntervalCategoryToolTipGenerator {

DateFormat format;

public MyToolTipGenerator(String value, DateFormat format) {
    super(value, format);
    this.format = format;
}

@Override
public String generateToolTip(CategoryDataset cds, int row, int col) {
    final String s = super.generateToolTip(cds, row, col);
    TaskSeriesCollection tsc = (TaskSeriesCollection) cds;
    StringBuilder sb = new StringBuilder(s);
    for (int i = 0; i < tsc.getSubIntervalCount(row, col); i++) {
        sb.append(format.format(tsc.getStartValue(row, col, i)));
        sb.append("-");
        sb.append(format.format(tsc.getEndValue(row, col, i)));
        sb.append(",");
    }
    sb.deleteCharAt(sb.length() - 1);
    return sb.toString();
}
}

I already tried some of the examples and solutions that were posted here but neither of them worked. Since I get several data from the db and store them all in an ArrayList, I want to show the specific related begin and end time (getAuftragsBeginnList and getAuftragsEndeList) in relation to the hovered datapoint.

0

There are 0 best solutions below