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:
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.