Files
stundenplan/StundenplanGUI.java
2021-10-26 11:57:27 +02:00

346 lines
11 KiB
Java

import javax.swing.*;
import javax.swing.border.Border;
import javax.swing.border.LineBorder;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.sql.SQLOutput;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* GUI für das Stundenplanprogramm.
*/
public class StundenplanGUI extends JFrame implements ActionListener {
// Initiale Größe des Fensters
public static final int FRAME_WIDTH = 800;
public static final int FRAME_HEIGHT = 600;
// Schriftarten
public static Font fHeader = new Font(Font.SANS_SERIF, Font.BOLD, 12);
public static Font fTitle = new Font(Font.SANS_SERIF, Font.BOLD, 11);
public static Font fSubtitle = new Font(Font.SANS_SERIF, Font.PLAIN, 8);
public static Font fText = new Font(Font.SANS_SERIF, Font.PLAIN, 9);
public static Font fFooter = new Font(Font.SANS_SERIF, Font.ITALIC, 8);
// Der Listener, der bei Änderungen informiert wird.
private SelectionListener selectionListener;
// Caches für Stunden und Filter
private Hashtable<String, JPanel> filters;
private Hashtable<Point, JPanel> lessons;
// Panels für die Bereiche des GUIs
private JPanel jpPlan, jpSidebar;
/**
* Erstellt ein neues GUI, zeigt es aber noch nicht an. Das Hauptprogramm
* muss dies explizit mit {@link #setVisible(boolean)} tun.
*/
public StundenplanGUI() {
filters = new Hashtable<>();
lessons = new Hashtable<>();
this.setSize(FRAME_WIDTH, FRAME_HEIGHT);
this.addComponents();
}
/**
* Fügt der Seitenleister eine neue Auswahlbox hinzu. Der Name wird bei
* Änderungen an den {@link SelectionListener} übergeben, um verschiedene
* Boxen unterscheiden zu können.
* @param pName Name des Filters
* @param pOptions Mögliche Optionen
*/
public void addFilter(String pName, String[] pOptions) {
JPanel jpFilter = new JPanel();
jpFilter.setLayout(new BorderLayout());
jpFilter.setBackground(jpSidebar.getBackground());
jpFilter.setPreferredSize(new Dimension(jpSidebar.getPreferredSize().width, 50));
jpFilter.add(makeLabel(pName, fHeader), BorderLayout.NORTH);
JComboBox<String> jcbFilter = new JComboBox<String>(pOptions);
jcbFilter.setName(pName);
jcbFilter.addActionListener(this);
jpFilter.add(jcbFilter, BorderLayout.CENTER);
filters.put(pName, jpFilter);
jpSidebar.add(jpFilter);
}
/**
* Entfernt die Auswahlbox mit dem angegebnen Namen aus der Seitenleiste.
* @param pName
*/
public void removeFilter(String pName) {
if (filters.containsKey(pName)) {
JPanel jpFilter = filters.get(pName);
jpSidebar.remove(jpFilter);
filters.remove(pName);
}
}
/**
* Entfernt alle Auswahlboxen aus der Seitenleiste.
*/
public void removeAllFilters() {
jpSidebar.removeAll();
}
/**
* Fügt eine neue Stunde in den Plan ein. Exisitiert in der angegebenen Zelle
* schon eine Stunde, wird diese entfernt und durch die neue ersetzt.
*
* Eine Stunde in der GUI hat verschiedene Bereiche, in denen Informationen
* (Text) untergebracht werden können, sowie eine Farbe.
*
* Nachdem eine oder mehrere Stunden hinzugefügt wurden, sollte das Fenster mit
* {@link JFrame#revalidate()} und {@link JFrame#repaint()} neu gezeichnet werden.
*
* @param pCol Spaltenindex (0=Montag, ..., 4=Freitag)
* @param pRow Zeilenindex (0=1. Stunde, ..., 9=10. Stunde)
* @param pTitle Überschrift
* @param pSubtitle Untertitel
* @param pText Beschreibung
* @param pFooter Fußzeile
* @param pColor Farbe der Stunde im Plan
*/
public void addLesson(int pCol, int pRow, String pTitle, String pSubtitle, String pText, String pFooter, Color pColor) {
removeLesson(pCol, pRow);
Color bg = new Color(pColor.getRed(), pColor.getGreen(), pColor.getBlue(), 128);
JPanel jpLesson = new JPanel();
jpLesson.setBackground(bg);
jpLesson.setForeground(pColor);
jpLesson.setBorder(new LineBorder(pColor, 2, true));
jpLesson.setLayout(new BoxLayout(jpLesson, BoxLayout.Y_AXIS));
JLabel jlTitle = new JLabel(pTitle);
jlTitle.setFont(fTitle);
jpLesson.add(jlTitle);
JLabel jlSubtitle = new JLabel(pSubtitle);
jlSubtitle.setFont(fSubtitle);
jpLesson.add(jlSubtitle);
JLabel jlText = new JLabel(pText);
jlText.setFont(fText);
jpLesson.add(jlText);
JLabel jlFooter = new JLabel(pFooter);
jlFooter.setFont(fFooter);
jpLesson.add(jlFooter);
GridBagConstraints c = new GridBagConstraints();
c.gridx = pCol + 1;
c.gridy = pRow + 1;
c.weightx = 0.5;
c.weighty = 0.5;
c.insets = new Insets(2, 4, 2, 4);
c.fill = GridBagConstraints.BOTH;
lessons.put(new Point(pCol, pRow), jpLesson);
jpPlan.add(jpLesson, c);
}
/**
* Entfernt die Stunde aus der angebenen Zelle.
* @param pCol Spaltenindex (0=Montag, ..., 4=Freitag)
* @param pRow Zeilenindex (0=1. Stunde, ..., 9=10. Stunde)
*/
public void removeLesson(int pCol, int pRow) {
Point key = new Point(pCol, pRow);
JPanel jpLesson = lessons.get(key);
if (jpLesson != null) {
jpPlan.remove(jpLesson);
lessons.remove(key);
}
}
/**
* Entfernt alle derzeit angezeigten Stunden aus dem GUI.
*/
public void removeAllLessons() {
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 30; j++) {
removeLesson(i, j);
}
}
}
/**
* Setzt den Listener, der über Änderungen der Auswahlboxen informiert wird.
* @param pSelectionListener
*/
public void addSelectionListener(SelectionListener pSelectionListener) {
this.selectionListener = pSelectionListener;
}
/**
* Leitet die Änderungen der Auswahlboxen an den {@link SelectionListener}
* weiter.
* @param pActionEvent
*/
public void actionPerformed(ActionEvent pActionEvent) {
if (this.selectionListener != null) {
JComboBox<String> source = ((JComboBox<String>) pActionEvent.getSource());
String newValue = (String) source.getSelectedItem();
String sourceName = source.getName();
this.selectionListener.selectionChanged(sourceName, newValue);
}
}
/**
* Fügt dem GUI die Standard-Komponenten hinzu.
*/
private void addComponents() {
this.setLayout(new BorderLayout());
// Seitenleiste für Filter (Auswahlboxen)
jpSidebar = new JPanel();
jpSidebar.setBackground(Color.LIGHT_GRAY);
jpSidebar.setPreferredSize(new Dimension(100, FRAME_HEIGHT));
this.add(jpSidebar, BorderLayout.LINE_START);
// Hauptbereich für den Stundenplan
jpPlan = new JPanel();
this.add(jpPlan, BorderLayout.CENTER);
jpPlan.setLayout(new GridBagLayout());
jpPlan.add(new JPanel());
//Datum
GregorianCalendar [] tage = new GregorianCalendar[7];
GregorianCalendar g = new GregorianCalendar();
System.out.println("asd " + g.getTimeZone());
Date d = new Date();
SimpleDateFormat datum = new SimpleDateFormat("dd.MM.yyyy");
SimpleDateFormat tag = new SimpleDateFormat("dd");
SimpleDateFormat wochentag = new SimpleDateFormat("EEEEEEEEEEEE");
SimpleDateFormat uhrzeit = new SimpleDateFormat("HH:mm:ss");
String heute = wochentag.format(d);
System.out.println("current Date: " + datum.format(d));
System.out.println("current Day: " + wochentag.format(d));
/*
for (int j = 0; j < 7; j++) {
tage[j]= new GregorianCalendar();
}
for(int i = g.get(Calendar.DAY_OF_WEEK); i<0;i--){
tage[i]= new GregorianCalendar();
tage[i] = tage[i].roll(Calendar.DAY_OF_WEEK,-i+1);
}
*/
// Überschriften für die Spalten (Wochentage)
GridBagConstraints c = new GridBagConstraints();
c.gridx = 1;
c.gridy = 0;
c.fill = GridBagConstraints.NONE;
c.weightx = 0.5;
c.weighty = 0.2;
Color color = new Color(0xf24e5e);
JLabel mo = makeLabel("Montag ", fHeader);
if(heute.equals("Montag")) {
mo.setForeground(color);
}
jpPlan.add(mo, c);
c.gridx++;
JLabel di = makeLabel("Dienstag ", fHeader);
if(heute.equals("Dienstag")) {
di.setForeground(color);
}
jpPlan.add(di, c);
c.gridx++;
JLabel mi = makeLabel("Mittwoch ", fHeader);
if(heute.equals("Mittwoch")) {
mi.setForeground(color);
}
jpPlan.add(mi, c);
c.gridx++;
JLabel don = makeLabel("Donnerstag ", fHeader);
if(heute.equals("Donnerstag")) {
don.setForeground(color);
}
jpPlan.add(don, c);
c.gridx++;
JLabel fr = makeLabel("Freitag ", fHeader);
if(heute.equals("Freitag")) {
fr.setForeground(color);
}
jpPlan.add(fr, c);
// Überschriften für die Zeilen (Stunden)
c = new GridBagConstraints();
c.gridx = 0;
c.fill = GridBagConstraints.NONE;
c.weightx = 0.2;
c.weighty = 0.5;
// Code um den Tag und die Aktuelle Stunde rot hervorzuheben
String[][] blocks = getTagesblocks();
GregorianCalendar beginn = new GregorianCalendar();
GregorianCalendar ende = new GregorianCalendar();
for (int i = 0; i < 10; i++) {
beginn.set(beginn.HOUR_OF_DAY,Integer.parseInt(blocks[i][1].substring(0,2)));
beginn.set(beginn.MINUTE,Integer.parseInt(blocks[i][1].substring(3,5)));
ende.set(beginn.HOUR_OF_DAY,Integer.parseInt(blocks[i][2].substring(0,2)));
ende.set(beginn.MINUTE,Integer.parseInt(blocks[i][2].substring(3,5)));
c.gridy = i + 1;
if(g.after(beginn) && g.before(ende)) {
JLabel current = makeLabel((i + 1) + ". Stunde", fHeader);
current.setForeground(color);
jpPlan.add(current, c);
} else {
jpPlan.add(makeLabel((i + 1) + ". Stunde", fHeader), c);
}
}
}
/**
* Erzeugt ein Text-Label mit der Standard-Schrift und dem angegebenen Text.
* @param pLabel
* @return
*/
private JLabel makeLabel(String pLabel) {
return makeLabel(pLabel, fText);
}
/**
* Gibt die Tabelle Tagesblocks aus
* @return
*/
private String[][] getTagesblocks(){
DatabaseConnector dbc = new DatabaseConnector("", 0, "stundenplan.db", "", "");
dbc.executeStatement("SELECT * FROM tagesblocks");
QueryResult r = dbc.getCurrentQueryResult();
System.out.println(r);
if(r == null) return new String[0][0];
return r.getData();
}
/**
* Erzeugt ein Text-Label mit der angegebenen Schrift und dem Text.
* @param pLabel
* @param pFont
* @return
*/
private JLabel makeLabel(String pLabel, Font pFont) {
JLabel jlLabel = new JLabel(pLabel);
jlLabel.setFont(pFont);
return jlLabel;
}
}