Initial commit
25
.gitignore
vendored
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
# ---> Java
|
||||||
|
# Compiled class file
|
||||||
|
*.class
|
||||||
|
|
||||||
|
# Log file
|
||||||
|
*.log
|
||||||
|
|
||||||
|
# BlueJ files
|
||||||
|
*.ctxt
|
||||||
|
Dokumente*
|
||||||
|
|
||||||
|
# Mobile Tools for Java (J2ME)
|
||||||
|
.mtj.tmp/
|
||||||
|
|
||||||
|
# Package Files #
|
||||||
|
*.jar
|
||||||
|
*.war
|
||||||
|
*.nar
|
||||||
|
*.ear
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.rar
|
||||||
|
|
||||||
|
# virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml
|
||||||
|
hs_err_pid*
|
||||||
90
Connection.java
Normal file
@@ -0,0 +1,90 @@
|
|||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Klasse Connection
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Objekte der Klasse Connection ermoeglichen eine Netzwerkverbindung zu einem
|
||||||
|
* Server mittels TCP/IP-Protokoll. Nach Verbindungsaufbau koennen Zeichenketten
|
||||||
|
* (Strings) zum Server gesendet und von diesem empfangen werden. Zur
|
||||||
|
* Vereinfachung geschieht dies zeilenweise, d. h., beim Senden einer
|
||||||
|
* Zeichenkette wird ein Zeilentrenner ergaenzt und beim Empfang wird dieser
|
||||||
|
* entfernt. Es findet nur eine rudimentaere Fehlerbehandlung statt, so dass z.B.
|
||||||
|
* der Zugriff auf unterbrochene oder bereits getrennte Verbindungen nicht zu
|
||||||
|
* einem Programmabbruch fuehrt. Eine einmal getrennte Verbindung kann nicht
|
||||||
|
* reaktiviert werden.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||||
|
* @version 30.08.2016
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.net.*;
|
||||||
|
import java.io.*;
|
||||||
|
|
||||||
|
public class Connection
|
||||||
|
{
|
||||||
|
private Socket socket;
|
||||||
|
private BufferedReader fromServer;
|
||||||
|
private PrintWriter toServer;
|
||||||
|
|
||||||
|
public Connection(String pServerIP, int pServerPort)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket = new Socket(pServerIP, pServerPort);
|
||||||
|
toServer = new PrintWriter(socket.getOutputStream(), true);
|
||||||
|
fromServer = new BufferedReader(new InputStreamReader(socket.getInputStream()));
|
||||||
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
|
//Erstelle eine nicht-verbundene Instanz von Socket, wenn die avisierte
|
||||||
|
//Verbindung nicht hergestellt werden kann
|
||||||
|
socket = null;
|
||||||
|
toServer = null;
|
||||||
|
fromServer = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public String receive()
|
||||||
|
{
|
||||||
|
if(fromServer != null)
|
||||||
|
try
|
||||||
|
{
|
||||||
|
return fromServer.readLine();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
return(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void send(String pMessage)
|
||||||
|
{
|
||||||
|
if(toServer != null)
|
||||||
|
{
|
||||||
|
toServer.println(pMessage);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void close()
|
||||||
|
{
|
||||||
|
|
||||||
|
if(socket != null && !socket.isClosed())
|
||||||
|
try
|
||||||
|
{
|
||||||
|
socket.close();
|
||||||
|
}
|
||||||
|
catch (IOException e)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Falls eine Verbindung geschlossen werden soll, deren Endpunkt nicht
|
||||||
|
* mehr existiert bzw. seinerseits bereits geschlossen worden ist oder
|
||||||
|
* die nicht korrekt instanziiert werden konnte (socket == null), geschieht
|
||||||
|
* nichts.
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
345
List.java
Normal file
@@ -0,0 +1,345 @@
|
|||||||
|
/**
|
||||||
|
* <p>
|
||||||
|
* Materialien zu den zentralen NRW-Abiturpruefungen im Fach Informatik ab 2018
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Generische Klasse List<ContentType>
|
||||||
|
* </p>
|
||||||
|
* <p>
|
||||||
|
* Objekt der generischen Klasse List verwalten beliebig viele linear
|
||||||
|
* angeordnete Objekte vom Typ ContentType. Auf hoechstens ein Listenobjekt,
|
||||||
|
* aktuellesObjekt genannt, kann jeweils zugegriffen werden.<br />
|
||||||
|
* Wenn eine Liste leer ist, vollstaendig durchlaufen wurde oder das aktuelle
|
||||||
|
* Objekt am Ende der Liste geloescht wurde, gibt es kein aktuelles Objekt.<br />
|
||||||
|
* Das erste oder das letzte Objekt einer Liste koennen durch einen Auftrag zum
|
||||||
|
* aktuellen Objekt gemacht werden. Ausserdem kann das dem aktuellen Objekt
|
||||||
|
* folgende Listenobjekt zum neuen aktuellen Objekt werden. <br />
|
||||||
|
* Das aktuelle Objekt kann gelesen, veraendert oder geloescht werden. Ausserdem
|
||||||
|
* kann vor dem aktuellen Objekt ein Listenobjekt eingefuegt werden.
|
||||||
|
* </p>
|
||||||
|
*
|
||||||
|
* @author Qualitaets- und UnterstuetzungsAgentur - Landesinstitut fuer Schule
|
||||||
|
* @version Generisch_06 2015-10-25
|
||||||
|
*/
|
||||||
|
public class List<ContentType> {
|
||||||
|
|
||||||
|
/* --------- Anfang der privaten inneren Klasse -------------- */
|
||||||
|
|
||||||
|
private class ListNode {
|
||||||
|
|
||||||
|
private ContentType contentObject;
|
||||||
|
private ListNode next;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ein neues Objekt wird erschaffen. Der Verweis ist leer.
|
||||||
|
*
|
||||||
|
* @param pContent das Inhaltsobjekt vom Typ ContentType
|
||||||
|
*/
|
||||||
|
private ListNode(ContentType pContent) {
|
||||||
|
contentObject = pContent;
|
||||||
|
next = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Inhalt des Knotens wird zurueckgeliefert.
|
||||||
|
*
|
||||||
|
* @return das Inhaltsobjekt des Knotens
|
||||||
|
*/
|
||||||
|
public ContentType getContentObject() {
|
||||||
|
return contentObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Inhalt dieses Kontens wird gesetzt.
|
||||||
|
*
|
||||||
|
* @param pContent das Inhaltsobjekt vom Typ ContentType
|
||||||
|
*/
|
||||||
|
public void setContentObject(ContentType pContent) {
|
||||||
|
contentObject = pContent;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Nachfolgeknoten wird zurueckgeliefert.
|
||||||
|
*
|
||||||
|
* @return das Objekt, auf das der aktuelle Verweis zeigt
|
||||||
|
*/
|
||||||
|
public ListNode getNextNode() {
|
||||||
|
return this.next;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Verweis wird auf das Objekt, das als Parameter uebergeben
|
||||||
|
* wird, gesetzt.
|
||||||
|
*
|
||||||
|
* @param pNext der Nachfolger des Knotens
|
||||||
|
*/
|
||||||
|
public void setNextNode(ListNode pNext) {
|
||||||
|
this.next = pNext;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ----------- Ende der privaten inneren Klasse -------------- */
|
||||||
|
|
||||||
|
// erstes Element der Liste
|
||||||
|
ListNode first;
|
||||||
|
|
||||||
|
// letztes Element der Liste
|
||||||
|
ListNode last;
|
||||||
|
|
||||||
|
// aktuelles Element der Liste
|
||||||
|
ListNode current;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Eine leere Liste wird erzeugt.
|
||||||
|
*/
|
||||||
|
public List() {
|
||||||
|
first = null;
|
||||||
|
last = null;
|
||||||
|
current = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Anfrage liefert den Wert true, wenn die Liste keine Objekte enthaelt,
|
||||||
|
* sonst liefert sie den Wert false.
|
||||||
|
*
|
||||||
|
* @return true, wenn die Liste leer ist, sonst false
|
||||||
|
*/
|
||||||
|
public boolean isEmpty() {
|
||||||
|
// Die Liste ist leer, wenn es kein erstes Element gibt.
|
||||||
|
return first == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Die Anfrage liefert den Wert true, wenn es ein aktuelles Objekt gibt,
|
||||||
|
* sonst liefert sie den Wert false.
|
||||||
|
*
|
||||||
|
* @return true, falls Zugriff moeglich, sonst false
|
||||||
|
*/
|
||||||
|
public boolean hasAccess() {
|
||||||
|
// Es gibt keinen Zugriff, wenn current auf kein Element verweist.
|
||||||
|
return current != null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls die Liste nicht leer ist, es ein aktuelles Objekt gibt und dieses
|
||||||
|
* nicht das letzte Objekt der Liste ist, wird das dem aktuellen Objekt in
|
||||||
|
* der Liste folgende Objekt zum aktuellen Objekt, andernfalls gibt es nach
|
||||||
|
* Ausfuehrung des Auftrags kein aktuelles Objekt, d.h. hasAccess() liefert
|
||||||
|
* den Wert false.
|
||||||
|
*/
|
||||||
|
public void next() {
|
||||||
|
if (this.hasAccess()) {
|
||||||
|
current = current.getNextNode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls die Liste nicht leer ist, wird das erste Objekt der Liste aktuelles
|
||||||
|
* Objekt. Ist die Liste leer, geschieht nichts.
|
||||||
|
*/
|
||||||
|
public void toFirst() {
|
||||||
|
if (!isEmpty()) {
|
||||||
|
current = first;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls die Liste nicht leer ist, wird das letzte Objekt der Liste
|
||||||
|
* aktuelles Objekt. Ist die Liste leer, geschieht nichts.
|
||||||
|
*/
|
||||||
|
public void toLast() {
|
||||||
|
if (!isEmpty()) {
|
||||||
|
current = last;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das
|
||||||
|
* aktuelle Objekt zurueckgegeben, andernfalls (hasAccess() == false) gibt
|
||||||
|
* die Anfrage den Wert null zurueck.
|
||||||
|
*
|
||||||
|
* @return das aktuelle Objekt (vom Typ ContentType) oder null, wenn es
|
||||||
|
* kein aktuelles Objekt gibt
|
||||||
|
*/
|
||||||
|
public ContentType getContent() {
|
||||||
|
if (this.hasAccess()) {
|
||||||
|
return current.getContentObject();
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls es ein aktuelles Objekt gibt (hasAccess() == true) und pContent
|
||||||
|
* ungleich null ist, wird das aktuelle Objekt durch pContent ersetzt. Sonst
|
||||||
|
* geschieht nichts.
|
||||||
|
*
|
||||||
|
* @param pContent
|
||||||
|
* das zu schreibende Objekt vom Typ ContentType
|
||||||
|
*/
|
||||||
|
public void setContent(ContentType pContent) {
|
||||||
|
// Nichts tun, wenn es keinen Inhalt oder kein aktuelles Element gibt.
|
||||||
|
if (pContent != null && this.hasAccess()) {
|
||||||
|
current.setContentObject(pContent);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird ein neues
|
||||||
|
* Objekt vor dem aktuellen Objekt in die Liste eingefuegt. Das aktuelle
|
||||||
|
* Objekt bleibt unveraendert. <br />
|
||||||
|
* Wenn die Liste leer ist, wird pContent in die Liste eingefuegt und es
|
||||||
|
* gibt weiterhin kein aktuelles Objekt (hasAccess() == false). <br />
|
||||||
|
* Falls es kein aktuelles Objekt gibt (hasAccess() == false) und die Liste
|
||||||
|
* nicht leer ist oder pContent gleich null ist, geschieht nichts.
|
||||||
|
*
|
||||||
|
* @param pContent
|
||||||
|
* das einzufuegende Objekt vom Typ ContentType
|
||||||
|
*/
|
||||||
|
public void insert(ContentType pContent) {
|
||||||
|
if (pContent != null) { // Nichts tun, wenn es keinen Inhalt gibt.
|
||||||
|
if (this.hasAccess()) { // Fall: Es gibt ein aktuelles Element.
|
||||||
|
|
||||||
|
// Neuen Knoten erstellen.
|
||||||
|
ListNode newNode = new ListNode(pContent);
|
||||||
|
|
||||||
|
if (current != first) { // Fall: Nicht an erster Stelle einfuegen.
|
||||||
|
ListNode previous = this.getPrevious(current);
|
||||||
|
newNode.setNextNode(previous.getNextNode());
|
||||||
|
previous.setNextNode(newNode);
|
||||||
|
} else { // Fall: An erster Stelle einfuegen.
|
||||||
|
newNode.setNextNode(first);
|
||||||
|
first = newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
} else { //Fall: Es gibt kein aktuelles Element.
|
||||||
|
|
||||||
|
if (this.isEmpty()) { // Fall: In leere Liste einfuegen.
|
||||||
|
|
||||||
|
// Neuen Knoten erstellen.
|
||||||
|
ListNode newNode = new ListNode(pContent);
|
||||||
|
|
||||||
|
first = newNode;
|
||||||
|
last = newNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls pContent gleich null ist, geschieht nichts.<br />
|
||||||
|
* Ansonsten wird ein neues Objekt pContent am Ende der Liste eingefuegt.
|
||||||
|
* Das aktuelle Objekt bleibt unveraendert. <br />
|
||||||
|
* Wenn die Liste leer ist, wird das Objekt pContent in die Liste eingefuegt
|
||||||
|
* und es gibt weiterhin kein aktuelles Objekt (hasAccess() == false).
|
||||||
|
*
|
||||||
|
* @param pContent
|
||||||
|
* das anzuhaengende Objekt vom Typ ContentType
|
||||||
|
*/
|
||||||
|
public void append(ContentType pContent) {
|
||||||
|
if (pContent != null) { // Nichts tun, wenn es keine Inhalt gibt.
|
||||||
|
|
||||||
|
if (this.isEmpty()) { // Fall: An leere Liste anfuegen.
|
||||||
|
this.insert(pContent);
|
||||||
|
} else { // Fall: An nicht-leere Liste anfuegen.
|
||||||
|
|
||||||
|
// Neuen Knoten erstellen.
|
||||||
|
ListNode newNode = new ListNode(pContent);
|
||||||
|
|
||||||
|
last.setNextNode(newNode);
|
||||||
|
last = newNode; // Letzten Knoten aktualisieren.
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Falls es sich bei der Liste und pList um dasselbe Objekt handelt,
|
||||||
|
* pList null oder eine leere Liste ist, geschieht nichts.<br />
|
||||||
|
* Ansonsten wird die Liste pList an die aktuelle Liste angehaengt.
|
||||||
|
* Anschliessend wird pList eine leere Liste. Das aktuelle Objekt bleibt
|
||||||
|
* unveraendert. Insbesondere bleibt hasAccess identisch.
|
||||||
|
*
|
||||||
|
* @param pList
|
||||||
|
* die am Ende anzuhaengende Liste vom Typ List<ContentType>
|
||||||
|
*/
|
||||||
|
public void concat(List<ContentType> pList) {
|
||||||
|
if (pList != this && pList != null && !pList.isEmpty()) { // Nichts tun,
|
||||||
|
// wenn pList und this identisch, pList leer oder nicht existent.
|
||||||
|
|
||||||
|
if (this.isEmpty()) { // Fall: An leere Liste anfuegen.
|
||||||
|
this.first = pList.first;
|
||||||
|
this.last = pList.last;
|
||||||
|
} else { // Fall: An nicht-leere Liste anfuegen.
|
||||||
|
this.last.setNextNode(pList.first);
|
||||||
|
this.last = pList.last;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Liste pList loeschen.
|
||||||
|
pList.first = null;
|
||||||
|
pList.last = null;
|
||||||
|
pList.current = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wenn die Liste leer ist oder es kein aktuelles Objekt gibt (hasAccess()
|
||||||
|
* == false), geschieht nichts.<br />
|
||||||
|
* Falls es ein aktuelles Objekt gibt (hasAccess() == true), wird das
|
||||||
|
* aktuelle Objekt geloescht und das Objekt hinter dem geloeschten Objekt
|
||||||
|
* wird zum aktuellen Objekt. <br />
|
||||||
|
* Wird das Objekt, das am Ende der Liste steht, geloescht, gibt es kein
|
||||||
|
* aktuelles Objekt mehr.
|
||||||
|
*/
|
||||||
|
public void remove() {
|
||||||
|
// Nichts tun, wenn es kein aktuelle Element gibt oder die Liste leer ist.
|
||||||
|
if (this.hasAccess() && !this.isEmpty()) {
|
||||||
|
|
||||||
|
if (current == first) {
|
||||||
|
first = first.getNextNode();
|
||||||
|
} else {
|
||||||
|
ListNode previous = this.getPrevious(current);
|
||||||
|
if (current == last) {
|
||||||
|
last = previous;
|
||||||
|
}
|
||||||
|
previous.setNextNode(current.getNextNode());
|
||||||
|
}
|
||||||
|
|
||||||
|
ListNode temp = current.getNextNode();
|
||||||
|
current.setContentObject(null);
|
||||||
|
current.setNextNode(null);
|
||||||
|
current = temp;
|
||||||
|
|
||||||
|
//Beim loeschen des letzten Elements last auf null setzen.
|
||||||
|
if (this.isEmpty()) {
|
||||||
|
last = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Liefert den Vorgaengerknoten des Knotens pNode. Ist die Liste leer, pNode
|
||||||
|
* == null, pNode nicht in der Liste oder pNode der erste Knoten der Liste,
|
||||||
|
* wird null zurueckgegeben.
|
||||||
|
*
|
||||||
|
* @param pNode
|
||||||
|
* der Knoten, dessen Vorgaenger zurueckgegeben werden soll
|
||||||
|
* @return der Vorgaenger des Knotens pNode oder null, falls die Liste leer ist,
|
||||||
|
* pNode == null ist, pNode nicht in der Liste ist oder pNode der erste Knoten
|
||||||
|
* der Liste ist
|
||||||
|
*/
|
||||||
|
private ListNode getPrevious(ListNode pNode) {
|
||||||
|
if (pNode != null && pNode != first && !this.isEmpty()) {
|
||||||
|
ListNode temp = first;
|
||||||
|
while (temp != null && temp.getNextNode() != pNode) {
|
||||||
|
temp = temp.getNextNode();
|
||||||
|
}
|
||||||
|
return temp;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
116
Mail.java
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
/**
|
||||||
|
* Speicher für die Informationen einer Mail. Dies umfasst
|
||||||
|
* den Textkörper und einige der Header-Daten, sowie die Nummer,
|
||||||
|
* die der Mail auf dem Server zugeordnet ist.
|
||||||
|
*/
|
||||||
|
public class Mail {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Laufende Nummer auf dem Server.
|
||||||
|
*/
|
||||||
|
private int number;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Empfangsdatum der Mail.
|
||||||
|
* <p>
|
||||||
|
* Wird aus dem Header-Feld "Date:" gelesen.
|
||||||
|
*/
|
||||||
|
private String date;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sender der Mail.
|
||||||
|
* <p>
|
||||||
|
* Wird aus dem Header-Feld "From:" gelesen.
|
||||||
|
*/
|
||||||
|
private String sender;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Betreff der Mail.
|
||||||
|
* <p>
|
||||||
|
* Wird aus dem Header-Feld "Subject:" gelesen.
|
||||||
|
*/
|
||||||
|
private String subject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Textkörper der Mail ohen Header-Felder.
|
||||||
|
*/
|
||||||
|
private String text;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Erstellt ein neues Mail-Objekt mit allen nötigen Werten.
|
||||||
|
*
|
||||||
|
* @param pNumber
|
||||||
|
* @param pDate
|
||||||
|
* @param pSender
|
||||||
|
* @param pSubject
|
||||||
|
* @param pText
|
||||||
|
*/
|
||||||
|
public Mail( int pNumber, String pDate, String pSender, String pSubject, String pText ) {
|
||||||
|
this.number = pNumber;
|
||||||
|
this.date = pDate;
|
||||||
|
this.sender = pSender;
|
||||||
|
this.subject = pSubject;
|
||||||
|
this.text = pText;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gibt die laufende Nummer der Mail, die diese beim Laden auf dem
|
||||||
|
* POP3-Server hatte, zurück.
|
||||||
|
* <p>
|
||||||
|
* Die laufende Nummer kann sich seit dem Laden verändert haben, falls
|
||||||
|
* noch andere Mail-Clients zugriff auf den Server haben und in der
|
||||||
|
* Zwischenzeit Mails gelöscht haben.
|
||||||
|
*
|
||||||
|
* @return Laufende Nummer der Mail beginnend ab {@code 1}.
|
||||||
|
*/
|
||||||
|
public int getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Datum der Mail als String.
|
||||||
|
* <p>
|
||||||
|
* In zukünftigen Versionen könnte das Datum als {@link java.util.Date}-Objekt
|
||||||
|
* gespeichert werden, um mit {@link java.text.DateFormat} das Datumsformat
|
||||||
|
* anpassen zu können.
|
||||||
|
*
|
||||||
|
* @return Emfangsdatum der Mail aus dem "Date:" Header
|
||||||
|
*/
|
||||||
|
public String getDate() {
|
||||||
|
return date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Absender der Mail.
|
||||||
|
* <p>
|
||||||
|
* Die Absenderdaten können in unterschiedlichen Formaten vorliegen (siehe
|
||||||
|
* dazu die Spezifikation in RFC2822 "Internet Message Format", Section 3.4).
|
||||||
|
* Die Absender Information könnte in zukünftigen Versionen in Name und
|
||||||
|
* Mail-Adresse geparsed werden.
|
||||||
|
*
|
||||||
|
* @return Absender der Mail aus dem "From:" Header
|
||||||
|
* @url https://datatracker.ietf.org/doc/html/rfc2822#section-3.4
|
||||||
|
*/
|
||||||
|
public String getSender() {
|
||||||
|
return sender;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Betreff der Mail.
|
||||||
|
*
|
||||||
|
* @return Betreff der Mail aus dem "Subject:" Header
|
||||||
|
*/
|
||||||
|
public String getSubject() {
|
||||||
|
return subject;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Der Textkörper der Mail.
|
||||||
|
*
|
||||||
|
* @return Textkörper der Mail
|
||||||
|
*/
|
||||||
|
public String getText() {
|
||||||
|
return text;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
252
MyMail.java
Normal file
@@ -0,0 +1,252 @@
|
|||||||
|
public class MyMail {
|
||||||
|
|
||||||
|
public static final String POP3_SERVER = "127.0.0.1";
|
||||||
|
|
||||||
|
public static final int POP3_PORT = 110;
|
||||||
|
|
||||||
|
public static final String POP3_USER = "user1";
|
||||||
|
|
||||||
|
public static final String POP3_PASS = "user1";
|
||||||
|
|
||||||
|
|
||||||
|
public static void main( String[] args ) {
|
||||||
|
new MyMail();
|
||||||
|
//new MyMail("pop3.neugebauer.cc", 110, "informatik@neugebauer.cc", "ifq2_user1");
|
||||||
|
}
|
||||||
|
|
||||||
|
private String ip;
|
||||||
|
|
||||||
|
private int port;
|
||||||
|
|
||||||
|
private Connection con;
|
||||||
|
|
||||||
|
private MyMailGUI gui;
|
||||||
|
|
||||||
|
private String user;
|
||||||
|
|
||||||
|
private String password;
|
||||||
|
|
||||||
|
private String lastError;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Verbindet zu einem lokalen POP3-Server.
|
||||||
|
*/
|
||||||
|
public MyMail() {
|
||||||
|
this(POP3_SERVER, POP3_PORT, POP3_USER, POP3_PASS);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyMail( String pIP, String pUser, String pPassword ) {
|
||||||
|
this(pIP, 110, pUser, pPassword);
|
||||||
|
}
|
||||||
|
|
||||||
|
public MyMail( String pIP, int pPort, String pUser, String pPassword ) {
|
||||||
|
ip = pIP;
|
||||||
|
port = pPort;
|
||||||
|
user = pUser;
|
||||||
|
password = pPassword;
|
||||||
|
|
||||||
|
// GUI erstellen und Status setzen.
|
||||||
|
gui = new MyMailGUI(this);
|
||||||
|
gui.setStatus("App gestartet");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Stellt die Verbindung zum POP3-Server her.
|
||||||
|
* <p>
|
||||||
|
* Erstellt ein {@link Connection}-Objekt für die Verbindung zum Server
|
||||||
|
* mit der IP {@link #ip} und dem Port {@link #port}. Laut RFC1939 sendet
|
||||||
|
* der POP3-Server als Erstes eine Begrüßungsnachricht zur Bestätigung der
|
||||||
|
* Verbindung:
|
||||||
|
*
|
||||||
|
* <blockquote>
|
||||||
|
* Once the TCP connection has been opened by a POP3 client, the POP3
|
||||||
|
* server issues a one line greeting. This can be any positive
|
||||||
|
* response. An example might be:
|
||||||
|
* S: +OK POP3 server ready
|
||||||
|
* </blockquote>
|
||||||
|
* <p>
|
||||||
|
* Gibt es beim Verbindungsaufbau einen Fehler, gibt die Methode {@code false}
|
||||||
|
* zurück und setzt {@link #lastError} auf eine sinnvolle Fehlermeldung.
|
||||||
|
* <p>
|
||||||
|
* Das {@code Connection}-Objekt wird in {@link #con} gespeichert.
|
||||||
|
*
|
||||||
|
* @return {@code true} oder {@code false}
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc1939#section-4
|
||||||
|
*/
|
||||||
|
private boolean connectToServer() {
|
||||||
|
// TODO: Connection-Objekt initialisieren
|
||||||
|
con = null;
|
||||||
|
|
||||||
|
// Begrüssungsnachricht des Servers empfangen und prüfen
|
||||||
|
String mes = con.receive();
|
||||||
|
if( mes == null || mes.startsWith("-ERR") ) {
|
||||||
|
// Keine "positive response" :-(
|
||||||
|
// Setze einen Fehler und gib "false" zurück.
|
||||||
|
lastError = "Der POP3-Server reagiert nicht!";
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verbindung erfolgreich
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Authentifiziert den Nutzer beim POP3-Server.
|
||||||
|
* <p>
|
||||||
|
* Die Methode nutzt die {@code USER} / {@code PASS} Befehle zur
|
||||||
|
* Anmeldung mit dem {@link #user} und {@link #password}. Sie erwartet, dass
|
||||||
|
* zuvor erfolgreich eine Verbindung mit {@link #connectToServer()}
|
||||||
|
* hergestellt wurde.
|
||||||
|
* <p>
|
||||||
|
* Hat die Anmeldung Erfolg, wird {@code true} zurückgegeben. Andernfalls
|
||||||
|
* {@code false} und {@link #lastError} wird auf eine sinnvolle Fehler-
|
||||||
|
* meldung gesetzt.
|
||||||
|
*
|
||||||
|
* @return {@code true} oder {@code false}
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc1939#page-13
|
||||||
|
*/
|
||||||
|
private boolean login() {
|
||||||
|
String mes = ""; // Speicher für die Antworten des Servers
|
||||||
|
|
||||||
|
// TODO: Implementieren
|
||||||
|
// USER Kommando senden und Antwort prüfen
|
||||||
|
|
||||||
|
// PASS Kommando senden und Antwort prüfen
|
||||||
|
|
||||||
|
// Anmeldung war erfolgreich
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ermittelt die Anzahl an Nachrichten auf dem Server.
|
||||||
|
* <p>
|
||||||
|
* Die Methode erwartet, dass zuvor erfolgreich eine Verbindung mit
|
||||||
|
* {@link #connectToServer()} hergestellt wurde und nutzt dann den
|
||||||
|
* {@code STAT} Befehl, um die Anzahl der Mails zu ermitteln.
|
||||||
|
*
|
||||||
|
* @return Die Anzahl an Mails auf dem Server
|
||||||
|
* @link https://datatracker.ietf.org/doc/html/rfc1939#page-6
|
||||||
|
*/
|
||||||
|
public int getMessageCount() {
|
||||||
|
String mes = "";
|
||||||
|
|
||||||
|
// TODO: Implementieren
|
||||||
|
// Sende den STAT Befehl
|
||||||
|
// Prüfe, ob die Antwort ein Fehler ist
|
||||||
|
// Schneide den Teil zwischen den Leerzeichen aus
|
||||||
|
// Finde die Leerzeichen mit indexOf(" ")
|
||||||
|
// Ermittele den Text mit substring(von, bis)
|
||||||
|
// Wandele mit Integer.parseInt() in eine Zahl um
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruft alle vorhandenen Mails vom Server ab und fügt sie der {@link #gui}
|
||||||
|
* hinzu.
|
||||||
|
*/
|
||||||
|
public void getAllMails() {
|
||||||
|
gui.setStatus("Rufe Mails vom Server ab..");
|
||||||
|
gui.clearAllMails(); // Gui leeren
|
||||||
|
lastError = null; // Zu Beginn gibt es noch keinen Fehler
|
||||||
|
|
||||||
|
// Verbindung erstellen und prüfen
|
||||||
|
boolean connected = connectToServer();
|
||||||
|
if( !connected ) {
|
||||||
|
// Letzten Fehler anzeigen (wird in connectToServer gesetzt).
|
||||||
|
gui.setError(lastError);
|
||||||
|
return; // Abbrechen
|
||||||
|
}
|
||||||
|
|
||||||
|
// Anmeldung durchführen und prüfen
|
||||||
|
// Hinweis: Nutze die login() Methode
|
||||||
|
|
||||||
|
// Anzahl Mails auf dem Server abfragen
|
||||||
|
int mailCount = 0;
|
||||||
|
|
||||||
|
// Abruf der Mails nach fortlaufender Nummer
|
||||||
|
for( int i = 1; i <= mailCount; i++ ) {
|
||||||
|
// Mail abrufen (nutze getMail(int))
|
||||||
|
// Mail der GUI hinzufügen (nutze gui.addMailToLost(Mail))
|
||||||
|
}
|
||||||
|
|
||||||
|
// Verbindung beenden
|
||||||
|
con.send("QUIT");
|
||||||
|
con.close();
|
||||||
|
|
||||||
|
if( lastError != null ) {
|
||||||
|
// Es gab einen Fehler
|
||||||
|
gui.setError(lastError);
|
||||||
|
} else {
|
||||||
|
// Kein Fehler
|
||||||
|
gui.setStatus("Liste der Mails erfolgreich geladen.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ruft die Mail mit der Nummer <var>pNumber</var> vom Server ab und
|
||||||
|
* gibt sie als {@link Mail}-Objekt zurück.
|
||||||
|
* <p>
|
||||||
|
* Die Methode erwartet, dass zuvor erfolgreich eine Verbindung mit
|
||||||
|
* {@link #connectToServer()} hergestellt wurde.
|
||||||
|
* <p>
|
||||||
|
* Tritt ein Fehler auf, gibt die Methode {@code null} zurück und setzt
|
||||||
|
* {@link #lastError} auf eine sinnvolle Nachricht.
|
||||||
|
*
|
||||||
|
* @param pNumber Die Nummer einer E-Mail auf dem Server
|
||||||
|
* @return Ein Mail-Objekt oder {@code null}.
|
||||||
|
*/
|
||||||
|
public Mail getMail( int pNumber ) {
|
||||||
|
String mes = ""; // Speicher für Antworten des Servers
|
||||||
|
|
||||||
|
// Prüfen, ob es eine Mail mit der Nummer pNumber gibt
|
||||||
|
|
||||||
|
// Mail abrufen (RETR)
|
||||||
|
|
||||||
|
while( !mes.equals(".") ) {
|
||||||
|
// Text der Mail parsen
|
||||||
|
// Verarbeite die Metadaten, vor allem:
|
||||||
|
// - Nummer der Mail
|
||||||
|
// - Subject
|
||||||
|
// - From
|
||||||
|
// - Date
|
||||||
|
// Wenn der Textkörper anfängt, speichere alle Zeilen in einen String
|
||||||
|
//
|
||||||
|
// Hinweis: Denke daran die Maskierung des Enzeichens "." rückgängig zu machen.
|
||||||
|
// Tipp: Merk dir in einem boolean, ob du im Textkörper oder im Header bist.
|
||||||
|
} // end of while
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Löscht eine Mail vom Server.
|
||||||
|
* <p>
|
||||||
|
* Die Methode stellt eine Verbindung zum Server her, markiert die
|
||||||
|
* übergebene Mail als gelöscht und beendet die Verbindung.
|
||||||
|
* <p>
|
||||||
|
* Tritt ein Fehler auf, bricht die Methode ab und setzt
|
||||||
|
* den Status der GUI auf eine sinnvolle Fehlermeldung.
|
||||||
|
*
|
||||||
|
* <b>Achtung</b>: Es wird die Mail mit derselben Nummer wie <var>pMail</var>
|
||||||
|
* gelöscht. Es wird nicht garantiert, dass dies auch dieselbe Mail ist.
|
||||||
|
*
|
||||||
|
* @param pMail Das Mailobjekt, das gelöscht werden soll.
|
||||||
|
* @todo Vor Löschen prüfen, ob die Mail auf dem Server dieselbe wie pMail ist.
|
||||||
|
*/
|
||||||
|
public void deleteMail( Mail pMail ) {
|
||||||
|
// Verbindung erstellen und prüfen
|
||||||
|
|
||||||
|
// Anmeldung durchführen und prüfen
|
||||||
|
|
||||||
|
// Prüfen, ob eine Mail mit der Nummer vorhanden ist
|
||||||
|
// Hinweis: Die Nummer der Mail ist über pMail.getNumber() abrufbar
|
||||||
|
|
||||||
|
// Mail als gelöscht markieren
|
||||||
|
|
||||||
|
// Löschung ausführen und Verbindung beenden.
|
||||||
|
|
||||||
|
// Mail aus der GUI entfernen und neu aufbauen.s
|
||||||
|
gui.removeMailFromList(pMail);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
251
MyMailGUI.java
Normal file
@@ -0,0 +1,251 @@
|
|||||||
|
import javax.swing.*;
|
||||||
|
import javax.swing.border.BevelBorder;
|
||||||
|
import javax.swing.border.EtchedBorder;
|
||||||
|
import javax.swing.event.ListSelectionEvent;
|
||||||
|
import javax.swing.event.ListSelectionListener;
|
||||||
|
import javax.swing.table.AbstractTableModel;
|
||||||
|
import java.awt.BorderLayout;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Dimension;
|
||||||
|
import java.awt.FlowLayout;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
|
import java.awt.event.ActionListener;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
public class MyMailGUI extends JFrame implements ActionListener, ListSelectionListener {
|
||||||
|
|
||||||
|
private MyMail app;
|
||||||
|
|
||||||
|
private java.util.List<Mail> mails = new ArrayList<>(20);
|
||||||
|
|
||||||
|
private JPanel jpStatus, jpSidebar, jpMain;
|
||||||
|
|
||||||
|
private JLabel jlStatusText;
|
||||||
|
|
||||||
|
private JButton jbReload, jbDelete, jbNew, jbReply, jbSettings;
|
||||||
|
|
||||||
|
private JTable jtMaillist;
|
||||||
|
|
||||||
|
private JTextArea jtaMailtext;
|
||||||
|
|
||||||
|
public MyMailGUI( MyMail pClientApp ) {
|
||||||
|
super("MyMail: POP3 Client");
|
||||||
|
app = pClientApp;
|
||||||
|
|
||||||
|
createComponents();
|
||||||
|
|
||||||
|
// Methoden der Klasse JFrame
|
||||||
|
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
|
||||||
|
setSize(800, 600);
|
||||||
|
setLocationRelativeTo(null);
|
||||||
|
setVisible(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatus( String pStatusText ) {
|
||||||
|
jlStatusText.setText(pStatusText);
|
||||||
|
jlStatusText.setIcon(loadImageIcon("information.png"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setError( String pStatusText ) {
|
||||||
|
jlStatusText.setText(pStatusText);
|
||||||
|
jlStatusText.setIcon(loadImageIcon("error.png"));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clearAllMails() {
|
||||||
|
mails.clear();
|
||||||
|
updateMailList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeMailFromList( Mail pMail ) {
|
||||||
|
if( pMail != null ) {
|
||||||
|
mails.remove(pMail);
|
||||||
|
updateMailList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMailToList( Mail pNewMail ) {
|
||||||
|
if( pNewMail != null ) {
|
||||||
|
mails.add(pNewMail);
|
||||||
|
updateMailList();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMailsToList( Mail[] pNewMails ) {
|
||||||
|
for( int i = 0; i < pNewMails.length; i++ ) {
|
||||||
|
if( pNewMails[i] != null ) {
|
||||||
|
mails.add(pNewMails[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
updateMailList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addMailsToList( List<Mail> pNewMails ) {
|
||||||
|
pNewMails.toFirst();
|
||||||
|
while( pNewMails.hasAccess() ) {
|
||||||
|
if( pNewMails.getContent() != null ) {
|
||||||
|
mails.add(pNewMails.getContent());
|
||||||
|
}
|
||||||
|
pNewMails.next();
|
||||||
|
}
|
||||||
|
updateMailList();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateMailList() {
|
||||||
|
((MailTableModel) jtMaillist.getModel()).fireTableDataChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed( ActionEvent e ) {
|
||||||
|
if( e.getActionCommand().equals("load") ) {
|
||||||
|
app.getAllMails();
|
||||||
|
} else if( e.getActionCommand().equals("delete") ) {
|
||||||
|
//app.deleteMail(jtMaillist.getSelectedRow()+1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void valueChanged( ListSelectionEvent e ) {
|
||||||
|
int selectedRow = jtMaillist.getSelectedRow();
|
||||||
|
if( selectedRow >= 0 && selectedRow < mails.size() ) {
|
||||||
|
Mail selectedMail = mails.get(jtMaillist.getSelectedRow());
|
||||||
|
jtaMailtext.setText(selectedMail.getText());
|
||||||
|
jbDelete.setEnabled(true);
|
||||||
|
} else {
|
||||||
|
jtaMailtext.setText("Wähle oben ein Mail aus ..");
|
||||||
|
jbDelete.setEnabled(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createComponents() {
|
||||||
|
jpStatus = new JPanel();
|
||||||
|
jpStatus.setLayout(new FlowLayout(FlowLayout.LEADING));
|
||||||
|
jpStatus.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
|
||||||
|
this.add(jpStatus, BorderLayout.SOUTH);
|
||||||
|
|
||||||
|
jlStatusText = new JLabel("Starte App..");
|
||||||
|
jpStatus.add(jlStatusText);
|
||||||
|
|
||||||
|
jpSidebar = new JPanel();
|
||||||
|
jpSidebar.setLayout(new FlowLayout(FlowLayout.CENTER));
|
||||||
|
jpSidebar.setBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED));
|
||||||
|
jpSidebar.setBackground(Color.DARK_GRAY);
|
||||||
|
jpSidebar.setPreferredSize(new Dimension(160, 600));
|
||||||
|
this.add(jpSidebar, BorderLayout.WEST);
|
||||||
|
|
||||||
|
jbReload = new JButton("Neu laden");
|
||||||
|
jbReload.setActionCommand("load");
|
||||||
|
jbReload.addActionListener(this);
|
||||||
|
jbReload.setIcon(loadImageIcon("arrow_refresh.png"));
|
||||||
|
jpSidebar.add(jbReload);
|
||||||
|
|
||||||
|
jbDelete = new JButton("Löschen");
|
||||||
|
jbDelete.setEnabled(false);
|
||||||
|
jbDelete.setActionCommand("delete");
|
||||||
|
jbDelete.addActionListener(this);
|
||||||
|
jbDelete.setIcon(loadImageIcon("email_delete.png"));
|
||||||
|
jpSidebar.add(jbDelete);
|
||||||
|
|
||||||
|
jbSettings = new JButton("Einstellungen");
|
||||||
|
jbSettings.setActionCommand("settings");
|
||||||
|
jbSettings.addActionListener(this);
|
||||||
|
jbSettings.setIcon(loadImageIcon("setting.png"));
|
||||||
|
//jpSidebar.add(jbSettings);
|
||||||
|
|
||||||
|
jpMain = new JPanel();
|
||||||
|
jpMain.setLayout(new BorderLayout());
|
||||||
|
this.add(jpMain, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
jtMaillist = new JTable(new MailTableModel());
|
||||||
|
jtMaillist.setShowGrid(true);
|
||||||
|
jtMaillist.setFillsViewportHeight(true);
|
||||||
|
jtMaillist.setCellSelectionEnabled(false);
|
||||||
|
jtMaillist.setColumnSelectionAllowed(false);
|
||||||
|
jtMaillist.setRowSelectionAllowed(true);
|
||||||
|
jtMaillist.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
|
||||||
|
jtMaillist.setShowHorizontalLines(true);
|
||||||
|
jtMaillist.getSelectionModel().addListSelectionListener(this);
|
||||||
|
jtMaillist.getColumnModel().getColumn(0).setPreferredWidth(200);
|
||||||
|
jtMaillist.getColumnModel().getColumn(1).setPreferredWidth(200);
|
||||||
|
jtMaillist.getColumnModel().getColumn(2).setPreferredWidth(400);
|
||||||
|
|
||||||
|
JScrollPane spMaillistContainer = new JScrollPane(jtMaillist);
|
||||||
|
spMaillistContainer.setPreferredSize(new Dimension(640, 200));
|
||||||
|
jpMain.add(spMaillistContainer, BorderLayout.NORTH);
|
||||||
|
|
||||||
|
jtaMailtext = new JTextArea();
|
||||||
|
jtaMailtext.setEditable(false);
|
||||||
|
jtaMailtext.setLineWrap(true);
|
||||||
|
jtaMailtext.setBorder(BorderFactory.createBevelBorder(BevelBorder.LOWERED));
|
||||||
|
jtaMailtext.setText("Wähle oben ein Mail aus ..");
|
||||||
|
|
||||||
|
JScrollPane spMailtextContainer = new JScrollPane(jtaMailtext);
|
||||||
|
spMailtextContainer.setPreferredSize(new Dimension(640, 400));
|
||||||
|
spMailtextContainer.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
|
||||||
|
jpMain.add(spMailtextContainer, BorderLayout.CENTER);
|
||||||
|
|
||||||
|
this.pack();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Icon loadImageIcon( String pImageName ) {
|
||||||
|
return new ImageIcon(MyMailGUI.class.getResource("images/" + pImageName));
|
||||||
|
}
|
||||||
|
|
||||||
|
class MailTableModel extends AbstractTableModel {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getColumnName( int columnIndex ) {
|
||||||
|
switch( columnIndex ) {
|
||||||
|
case 0:
|
||||||
|
return "Datum";
|
||||||
|
case 1:
|
||||||
|
return "Absender";
|
||||||
|
case 2:
|
||||||
|
return "Betreff";
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
@Override
|
||||||
|
public Class<?> getColumnClass( int columnIndex ) {
|
||||||
|
switch( columnIndex ) {
|
||||||
|
case 0:
|
||||||
|
return Date.class;
|
||||||
|
default:
|
||||||
|
return String.class;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRowCount() {
|
||||||
|
return mails.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getColumnCount() {
|
||||||
|
return 3;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Object getValueAt( int rowIndex, int columnIndex ) {
|
||||||
|
if( rowIndex < mails.size() ) {
|
||||||
|
switch( columnIndex ) {
|
||||||
|
case 0:
|
||||||
|
return mails.get(rowIndex).getDate();
|
||||||
|
case 1:
|
||||||
|
return mails.get(rowIndex).getSender();
|
||||||
|
case 2:
|
||||||
|
return mails.get(rowIndex).getSubject();
|
||||||
|
default:
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
8
README.TXT
Executable file
@@ -0,0 +1,8 @@
|
|||||||
|
# Projektvorlage: MyMail
|
||||||
|
|
||||||
|
Einfacher Mail-Client mit GUI, der Mails von einem POP3-Server abruft und
|
||||||
|
in einer Liste darstellt. Die GUI ist schon vollständig implementiert.
|
||||||
|
|
||||||
|
Verwendet die Abiturklasse Connection, um eine Verbindung herzustellen.
|
||||||
|
|
||||||
|
#rechnernetze #vorlage #pop3 #connection #gui #mvc
|
||||||
BIN
images/arrow_refresh.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
images/email_delete.png
Normal file
|
After Width: | Height: | Size: 1.7 KiB |
BIN
images/email_edit.png
Normal file
|
After Width: | Height: | Size: 1.8 KiB |
BIN
images/error.png
Normal file
|
After Width: | Height: | Size: 1.6 KiB |
BIN
images/information.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
images/mail_server_exim.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
images/mail_server_setting.png
Normal file
|
After Width: | Height: | Size: 1.9 KiB |
BIN
images/setting.png
Normal file
|
After Width: | Height: | Size: 2.0 KiB |
42
package.bluej
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
#BlueJ package file
|
||||||
|
dependency1.from=MailClient
|
||||||
|
dependency1.to=Connection
|
||||||
|
dependency1.type=UsesDependency
|
||||||
|
editor.fx.0.height=777
|
||||||
|
editor.fx.0.width=804
|
||||||
|
editor.fx.0.x=36
|
||||||
|
editor.fx.0.y=23
|
||||||
|
objectbench.height=101
|
||||||
|
objectbench.width=776
|
||||||
|
package.divider.horizontal=0.6
|
||||||
|
package.divider.vertical=0.8007380073800738
|
||||||
|
package.editor.height=427
|
||||||
|
package.editor.width=662
|
||||||
|
package.editor.x=40
|
||||||
|
package.editor.y=172
|
||||||
|
package.frame.height=600
|
||||||
|
package.frame.width=800
|
||||||
|
package.numDependencies=1
|
||||||
|
package.numTargets=2
|
||||||
|
package.showExtends=true
|
||||||
|
package.showUses=true
|
||||||
|
project.charset=UTF-8
|
||||||
|
readme.height=58
|
||||||
|
readme.name=@README
|
||||||
|
readme.width=47
|
||||||
|
readme.x=10
|
||||||
|
readme.y=10
|
||||||
|
target1.height=50
|
||||||
|
target1.name=Connection
|
||||||
|
target1.showInterface=false
|
||||||
|
target1.type=ClassTarget
|
||||||
|
target1.width=90
|
||||||
|
target1.x=350
|
||||||
|
target1.y=40
|
||||||
|
target2.height=50
|
||||||
|
target2.name=MailClient
|
||||||
|
target2.showInterface=false
|
||||||
|
target2.type=ClassTarget
|
||||||
|
target2.width=80
|
||||||
|
target2.x=110
|
||||||
|
target2.y=150
|
||||||