forked from IF-LK-2020/stundenplan
setup
This commit is contained in:
148
Stundenplan/src/DatabaseConnector.java
Normal file
148
Stundenplan/src/DatabaseConnector.java
Normal file
@@ -0,0 +1,148 @@
|
||||
import java.sql.*;
|
||||
|
||||
/**
|
||||
* <p>
|
||||
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||
* </p>
|
||||
* <p>
|
||||
* Klasse DatabaseConnector
|
||||
* </p>
|
||||
* <p>
|
||||
* Ein Objekt der Klasse DatabaseConnector ermoeglicht die Abfrage und Manipulation
|
||||
* einer SQLite-Datenbank.
|
||||
* Beim Erzeugen des Objekts wird eine Datenbankverbindung aufgebaut, so dass
|
||||
* anschließend SQL-Anweisungen an diese Datenbank gerichtet werden koennen.
|
||||
* </p>
|
||||
*
|
||||
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||
* @version 2016-01-24
|
||||
*/
|
||||
public class DatabaseConnector{
|
||||
private Connection connection;
|
||||
private QueryResult currentQueryResult = null;
|
||||
private String message = null;
|
||||
|
||||
/**
|
||||
* Ein Objekt vom Typ DatabaseConnector wird erstellt, und eine Verbindung zur Datenbank
|
||||
* wird aufgebaut. Mit den Parametern pIP und pPort werden die IP-Adresse und die
|
||||
* Port-Nummer uebergeben, unter denen die Datenbank mit Namen pDatabase zu erreichen ist.
|
||||
* Mit den Parametern pUsername und pPassword werden Benutzername und Passwort fuer die
|
||||
* Datenbank uebergeben.
|
||||
*/
|
||||
public DatabaseConnector(String pIP, int pPort, String pDatabase, String pUsername, String pPassword){
|
||||
//Eine Impementierung dieser Schnittstelle fuer SQLite ignoriert pID und pPort, da die Datenbank immer lokal ist.
|
||||
//Auch pUsername und pPassword werden nicht verwendet, da SQLite sie nicht unterstuetzt.
|
||||
try {
|
||||
//Laden der Treiberklasse
|
||||
Class.forName("org.sqlite.JDBC");
|
||||
|
||||
//Verbindung herstellen
|
||||
connection = DriverManager.getConnection("jdbc:sqlite:"+pDatabase);
|
||||
|
||||
} catch (Exception e) {
|
||||
message = e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Der Auftrag schickt den im Parameter pSQLStatement enthaltenen SQL-Befehl an die
|
||||
* Datenbank ab.
|
||||
* Handelt es sich bei pSQLStatement um einen SQL-Befehl, der eine Ergebnismenge
|
||||
* liefert, so kann dieses Ergebnis anschließend mit der Methode getCurrentQueryResult
|
||||
* abgerufen werden.
|
||||
*/
|
||||
public void executeStatement(String pSQLStatement){
|
||||
//Altes Ergebnis loeschen
|
||||
currentQueryResult = null;
|
||||
message = null;
|
||||
|
||||
try {
|
||||
//Neues Statement erstellen
|
||||
Statement statement = connection.createStatement();
|
||||
|
||||
//SQL Anweisung an die DB schicken.
|
||||
if (statement.execute(pSQLStatement)) { //Fall 1: Es gibt ein Ergebnis
|
||||
|
||||
//Resultset auslesen
|
||||
ResultSet resultset = statement.getResultSet();
|
||||
|
||||
//Spaltenanzahl ermitteln
|
||||
int columnCount = resultset.getMetaData().getColumnCount();
|
||||
|
||||
//Spaltennamen und Spaltentypen in Felder uebertragen
|
||||
String[] resultColumnNames = new String[columnCount];
|
||||
String[] resultColumnTypes = new String[columnCount];
|
||||
for (int i = 0; i < columnCount; i++){
|
||||
resultColumnNames[i] = resultset.getMetaData().getColumnLabel(i+1);
|
||||
resultColumnTypes[i] = resultset.getMetaData().getColumnTypeName(i+1);
|
||||
}
|
||||
|
||||
//Queue fuer die Zeilen der Ergebnistabelle erstellen
|
||||
Queue<String[]> rows = new Queue<String[]>();
|
||||
|
||||
//Daten in Queue uebertragen und Zeilen zaehlen
|
||||
int rowCount = 0;
|
||||
while (resultset.next()){
|
||||
String[] resultrow = new String[columnCount];
|
||||
for (int s = 0; s < columnCount; s++){
|
||||
resultrow[s] = resultset.getString(s+1);
|
||||
}
|
||||
rows.enqueue(resultrow);
|
||||
rowCount = rowCount + 1;
|
||||
}
|
||||
|
||||
//Ergebnisfeld erstellen und Zeilen aus Queue uebertragen
|
||||
String[][] resultData = new String[rowCount][columnCount];
|
||||
int j = 0;
|
||||
while (!rows.isEmpty()){
|
||||
resultData[j] = rows.front();
|
||||
rows.dequeue();
|
||||
j = j + 1;
|
||||
}
|
||||
|
||||
//Statement schließen und Ergebnisobjekt erstellen
|
||||
statement.close();
|
||||
currentQueryResult = new QueryResult(resultData, resultColumnNames, resultColumnTypes);
|
||||
|
||||
} else { //Fall 2: Es gibt kein Ergebnis.
|
||||
//Statement ohne Ergebnisobjekt schliessen
|
||||
statement.close();
|
||||
}
|
||||
|
||||
} catch (Exception e) {
|
||||
//Fehlermeldung speichern
|
||||
message = e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert das Ergebnis des letzten mit der Methode executeStatement an
|
||||
* die Datenbank geschickten SQL-Befehls als Ob-jekt vom Typ QueryResult zurueck.
|
||||
* Wurde bisher kein SQL-Befehl abgeschickt oder ergab der letzte Aufruf von
|
||||
* executeStatement keine Ergebnismenge (z.B. bei einem INSERT-Befehl oder einem
|
||||
* Syntaxfehler), so wird null geliefert.
|
||||
*/
|
||||
public QueryResult getCurrentQueryResult(){
|
||||
return currentQueryResult;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert null oder eine Fehlermeldung, die sich jeweils auf die letzte zuvor ausgefuehrte
|
||||
* Datenbankoperation bezieht.
|
||||
*/
|
||||
public String getErrorMessage(){
|
||||
return message;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Datenbankverbindung wird geschlossen.
|
||||
*/
|
||||
public void close(){
|
||||
try{
|
||||
connection.close();
|
||||
} catch (Exception e) {
|
||||
message = e.getMessage();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
76
Stundenplan/src/QueryResult.java
Normal file
76
Stundenplan/src/QueryResult.java
Normal file
@@ -0,0 +1,76 @@
|
||||
/**
|
||||
* <p>
|
||||
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||
* </p>
|
||||
* <p>
|
||||
* Klasse QueryResult
|
||||
* </p>
|
||||
* <p>
|
||||
* Ein Objekt der Klasse QueryResult stellt die Ergebnistabelle einer Datenbankanfrage mit Hilfe
|
||||
* der Klasse DatabaseConnector dar. Objekte dieser Klasse werden nur von der Klasse DatabaseConnector erstellt.
|
||||
* Die Klasse verfuegt ueber keinen oeffentlichen Konstruktor.
|
||||
* </p>
|
||||
*
|
||||
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||
* @version 2015-01-31
|
||||
*/
|
||||
public class QueryResult{
|
||||
private String[][] data;
|
||||
private String[] columnNames;
|
||||
private String[] columnTypes;
|
||||
|
||||
/**
|
||||
* Paketinterner Konstruktor.
|
||||
*/
|
||||
QueryResult(String[][] pData, String[] pColumnNames, String[] pColumnTypes){
|
||||
data = pData;
|
||||
columnNames = pColumnNames;
|
||||
columnTypes = pColumnTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert die Eintraege der Ergebnistabelle als zweidimensionales Feld
|
||||
* vom Typ String. Der erste Index des Feldes stellt die Zeile und der zweite die
|
||||
* Spalte dar (d.h. Object[zeile][spalte]).
|
||||
*/
|
||||
public String[][] getData(){
|
||||
return data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert die Bezeichner der Spalten der Ergebnistabelle als Feld vom
|
||||
* Typ String zurueck.
|
||||
*/
|
||||
public String[] getColumnNames(){
|
||||
return columnNames;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert die Typenbezeichnung der Spalten der Ergebnistabelle als Feld
|
||||
* vom Typ String zurueck. Die Bezeichnungen entsprechen den Angaben in der MySQL-Datenbank.
|
||||
*/
|
||||
public String[] getColumnTypes(){
|
||||
return columnTypes;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert die Anzahl der Zeilen der Ergebnistabelle als Integer.
|
||||
*/
|
||||
public int getRowCount(){
|
||||
if (data != null )
|
||||
return data.length;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert die Anzahl der Spalten der Ergebnistabelle als Integer.
|
||||
*/
|
||||
public int getColumnCount(){
|
||||
if (data != null && data.length > 0 && data[0] != null)
|
||||
return data[0].length;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
142
Stundenplan/src/Queue.java
Normal file
142
Stundenplan/src/Queue.java
Normal file
@@ -0,0 +1,142 @@
|
||||
/**
|
||||
* <p>
|
||||
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||
* </p>
|
||||
* <p>
|
||||
* Generische Klasse Queue<ContentType>
|
||||
* </p>
|
||||
* <p>
|
||||
* Objekte der generischen Klasse Queue (Warteschlange) verwalten beliebige
|
||||
* Objekte vom Typ ContentType nach dem First-In-First-Out-Prinzip, d.h., das
|
||||
* zuerst abgelegte Objekt wird als erstes wieder entnommen. Alle Methoden haben
|
||||
* eine konstante Laufzeit, unabhaengig von der Anzahl der verwalteten Objekte.
|
||||
* </p>
|
||||
*
|
||||
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||
* @version Generisch_02 2014-02-21
|
||||
*/
|
||||
public class Queue<ContentType> {
|
||||
|
||||
/* --------- Anfang der privaten inneren Klasse -------------- */
|
||||
|
||||
private class QueueNode {
|
||||
|
||||
private ContentType content = null;
|
||||
private QueueNode nextNode = null;
|
||||
|
||||
/**
|
||||
* Ein neues Objekt vom Typ QueueNode<ContentType> wird erschaffen.
|
||||
* Der Inhalt wird per Parameter gesetzt. Der Verweis ist leer.
|
||||
*
|
||||
* @param pContent das Inhaltselement des Knotens vom Typ ContentType
|
||||
*/
|
||||
public QueueNode(ContentType pContent) {
|
||||
content = pContent;
|
||||
nextNode = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Der Verweis wird auf das Objekt, das als Parameter uebergeben wird,
|
||||
* gesetzt.
|
||||
*
|
||||
* @param pNext der Nachfolger des Knotens
|
||||
*/
|
||||
public void setNext(QueueNode pNext) {
|
||||
nextNode = pNext;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das naechste Element des aktuellen Knotens.
|
||||
*
|
||||
* @return das Objekt vom Typ QueueNode, auf das der aktuelle Verweis zeigt
|
||||
*/
|
||||
public QueueNode getNext() {
|
||||
return nextNode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Inhaltsobjekt des Knotens vom Typ ContentType.
|
||||
*
|
||||
* @return das Inhaltsobjekt des Knotens
|
||||
*/
|
||||
public ContentType getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ----------- Ende der privaten inneren Klasse -------------- */
|
||||
|
||||
private QueueNode head;
|
||||
private QueueNode tail;
|
||||
|
||||
/**
|
||||
* Eine leere Schlange wird erzeugt.
|
||||
* Objekte, die in dieser Schlange verwaltet werden, muessen vom Typ
|
||||
* ContentType sein.
|
||||
*/
|
||||
public Queue() {
|
||||
head = null;
|
||||
tail = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert den Wert true, wenn die Schlange keine Objekte enthaelt,
|
||||
* sonst liefert sie den Wert false.
|
||||
*
|
||||
* @return true, falls die Schlange leer ist, sonst false
|
||||
*/
|
||||
public boolean isEmpty() {
|
||||
return head == null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Das Objekt pContentType wird an die Schlange angehaengt.
|
||||
* Falls pContentType gleich null ist, bleibt die Schlange unveraendert.
|
||||
*
|
||||
* @param pContent
|
||||
* das anzuhaengende Objekt vom Typ ContentType
|
||||
*/
|
||||
public void enqueue(ContentType pContent) {
|
||||
if (pContent != null) {
|
||||
QueueNode newNode = new QueueNode(pContent);
|
||||
if (this.isEmpty()) {
|
||||
head = newNode;
|
||||
tail = newNode;
|
||||
} else {
|
||||
tail.setNext(newNode);
|
||||
tail = newNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Das erste Objekt wird aus der Schlange entfernt.
|
||||
* Falls die Schlange leer ist, wird sie nicht veraendert.
|
||||
*/
|
||||
public void dequeue() {
|
||||
if (!this.isEmpty()) {
|
||||
head = head.getNext();
|
||||
if (this.isEmpty()) {
|
||||
head = null;
|
||||
tail = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Anfrage liefert das erste Objekt der Schlange.
|
||||
* Die Schlange bleibt unveraendert.
|
||||
* Falls die Schlange leer ist, wird null zurueckgegeben.
|
||||
*
|
||||
* @return das erste Objekt der Schlange vom Typ ContentType oder null,
|
||||
* falls die Schlange leer ist
|
||||
*/
|
||||
public ContentType front() {
|
||||
if (this.isEmpty()) {
|
||||
return null;
|
||||
} else {
|
||||
return head.getContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
13
Stundenplan/src/SelectionListener.java
Normal file
13
Stundenplan/src/SelectionListener.java
Normal file
@@ -0,0 +1,13 @@
|
||||
/**
|
||||
* Listener-INterface, um auf Änderungen der Auswahlboxen im GUI zu reagieren.
|
||||
*/
|
||||
public interface SelectionListener {
|
||||
|
||||
/**
|
||||
* Wird aufgerufen, wenn sich die Auswahl ändert.
|
||||
* @param pList Name der Auswahlbox
|
||||
* @param pNewValue Neuer Wert
|
||||
*/
|
||||
public void selectionChanged(String pList, String pNewValue );
|
||||
|
||||
}
|
||||
101
Stundenplan/src/Stundenplan.java
Normal file
101
Stundenplan/src/Stundenplan.java
Normal file
@@ -0,0 +1,101 @@
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
|
||||
public class Stundenplan implements SelectionListener {
|
||||
|
||||
/**
|
||||
* Main-Methode um das Programm (außerhalb von BlueJ) zu starten.
|
||||
*
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
// Setzen des "Look & Feel" des Programms
|
||||
try {
|
||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||
} catch (Exception e) {
|
||||
}
|
||||
|
||||
// Programm starten
|
||||
new Stundenplan();
|
||||
}
|
||||
|
||||
// Instanz des GUI des Programms
|
||||
private StundenplanGUI gui;
|
||||
|
||||
// Instanz der Datenbankverbindung
|
||||
private DatabaseConnector dbc;
|
||||
|
||||
/**
|
||||
* Konstruktor des Hauptprogramms
|
||||
*/
|
||||
public Stundenplan() {
|
||||
// Erstellen des GUIs
|
||||
gui = new StundenplanGUI();
|
||||
|
||||
// Aufbau der Datenbankverbindung
|
||||
dbc = new DatabaseConnector("", 0, "stundenplan.db", "", "");
|
||||
QueryResult r;
|
||||
|
||||
// Lehrer abfragen und ein Auswahlfeld erstellen, dass in der
|
||||
// GUI angezeigt wird, um den angezeigten Stundenplan anzupassen
|
||||
dbc.executeStatement("SELECT kuerzel FROM lehrer");
|
||||
System.out.println(dbc.getErrorMessage());
|
||||
r = dbc.getCurrentQueryResult();
|
||||
String[] teachers = new String[r.getRowCount()];
|
||||
for (int i = 0; i < r.getRowCount(); i++) {
|
||||
teachers[i] = r.getData()[i][0];
|
||||
}
|
||||
gui.addFilter("Lehrer", teachers);
|
||||
|
||||
// GUI anzeigen und Verhalten bei Interaktion festlegen
|
||||
gui.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||
gui.addSelectionListener(this); // GUI ruft Methode selectionChanged auf, wenn sich eine Auswahlbox ändert.
|
||||
gui.setLocationRelativeTo(null);
|
||||
gui.setVisible(true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Methode um auf Änderungen in der GUi zu reagieren. Sobald der nutzer die
|
||||
* Auswahl ändert, wird diese Methode aufgerufen. Der erste Parameter ist der
|
||||
* Name der Auswahlliste, die sich geändert hat (erster Parameter von
|
||||
* {@link StundenplanGUI#addFilter(String, String[])} oben) und der zweite ist
|
||||
* der neue Wert der Auswahl.
|
||||
*
|
||||
* @param pList Name der Auswahlliste
|
||||
* @param pNewValue Neuer Wert der Auswahl
|
||||
*/
|
||||
@Override
|
||||
public void selectionChanged(String pList, String pNewValue) {
|
||||
if (pList == "Lehrer") {
|
||||
// Zuerst alle bisherigen Stunden aus der GUI entfernen
|
||||
gui.removeAllLessons();
|
||||
|
||||
// Neue Daten aus der Datenbank abfragen.
|
||||
// Hier gefakte Daten, die Struktur der Datenbank ist nicht vorgegeben.
|
||||
dbc.executeStatement("SELECT 0,'Q2','405',kuerzel,0,0,'Informatik',-16711936 FROM lehrer WHERE kuerzel = '" + pNewValue + "'");
|
||||
QueryResult r = dbc.getCurrentQueryResult();
|
||||
|
||||
// Falls es ein Ergebnis gibt ...
|
||||
if (r != null) {
|
||||
String[][] data = r.getData();
|
||||
|
||||
// Neue Stunden in die GUI schreiben
|
||||
for (int i = 0; i < data.length; i++) {
|
||||
gui.addLesson(
|
||||
Integer.parseInt(data[i][4]), // Spalte im Plan (0=Montag, ... ,4=Freitag)
|
||||
Integer.parseInt(data[i][5]), // Zeile im Plan (0=1. Stunde, ... ,9=10. Stunde)
|
||||
data[i][6], // Titel
|
||||
"Raum " + data[i][2], // Untertitel
|
||||
data[i][1], // Beschreibungstext
|
||||
data[i][3], // Fußzeile
|
||||
new Color(Integer.parseInt(data[i][7])) // Farbe (Objekt der Klasse Color)
|
||||
);
|
||||
}
|
||||
|
||||
// GUI-Fenster neu zeichnen, um neue Elemente anzuzeigen.
|
||||
gui.revalidate();
|
||||
gui.repaint();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
265
Stundenplan/src/StundenplanGUI.java
Normal file
265
Stundenplan/src/StundenplanGUI.java
Normal file
@@ -0,0 +1,265 @@
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.LineBorder;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.util.Hashtable;
|
||||
|
||||
/**
|
||||
* 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 < 10; i++) {
|
||||
for (int j = 0; j < 5; 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());
|
||||
|
||||
// Ü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;
|
||||
jpPlan.add(makeLabel("Montag", fHeader), c);
|
||||
c.gridx++;
|
||||
jpPlan.add(makeLabel("Dienstag", fHeader), c);
|
||||
c.gridx++;
|
||||
jpPlan.add(makeLabel("Mittwoch", fHeader), c);
|
||||
c.gridx++;
|
||||
jpPlan.add(makeLabel("Donnerstag", fHeader), c);
|
||||
c.gridx++;
|
||||
jpPlan.add(makeLabel("Freitag", fHeader), 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;
|
||||
for (int i = 0; i < 10; i++) {
|
||||
c.gridy = i + 1;
|
||||
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);
|
||||
}
|
||||
|
||||
/**
|
||||
* 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;
|
||||
}
|
||||
|
||||
}
|
||||
BIN
Stundenplan/src/stundenplan.db
Normal file
BIN
Stundenplan/src/stundenplan.db
Normal file
Binary file not shown.
Reference in New Issue
Block a user