Version 1.0.0 (2024-12-29): Material ZPG (2019)
This commit is contained in:
parent
7835d8e99a
commit
67d0889188
825 changed files with 391265 additions and 3 deletions
|
|
@ -0,0 +1,50 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* Balkendiagramm für int-Array.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
public class Balkendiagramm extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten
|
||||
int[] zahlen={45, 23, 123, 87, 98, 2, 1, 23, 23, 34};;
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public Balkendiagramm() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
zeichneBalken();
|
||||
}
|
||||
|
||||
public void zeichneBalken() {
|
||||
clear();
|
||||
// Überschrift
|
||||
fill(255,255,255);
|
||||
textFont(grosseSchrift);
|
||||
text("Balkendiagramm", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
for (int i = 0; i< zahlen.length; i++) {
|
||||
|
||||
fill(20,30,170);
|
||||
|
||||
// Balkendiagramm zeichnen
|
||||
rect(120, 25+i*15, zahlen[i]+1, 13);
|
||||
|
||||
// Beschriftung
|
||||
fill(255,255,255);
|
||||
text("i="+i, 2, 35+i*15);
|
||||
text("zahlen["+i+"]="+zahlen[i], 30, 35+i*15);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class BalkendiagrammGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bZeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
// Ende Attribute
|
||||
|
||||
public BalkendiagrammGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bZeichnen.setBounds(256, 456, 273, 33);
|
||||
bZeichnen.setText("Balkendiagramm zeichnen");
|
||||
bZeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bZeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bZeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bZeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bZeichnen_ActionPerformed(ActionEvent evt) {
|
||||
Balkendiagramm bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
imagePanel1.getViewport().repaint();
|
||||
imagePanel1.getVerticalScrollBar().setValue(1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
} // end of bZeichnen_ActionPerformed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new BalkendiagrammGUI("BalkendiagrammGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
object BalkendiagrammGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'BalkendiagrammGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bOptischeTauschungzeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 256
|
||||
Top = 456
|
||||
Width = 273
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bOptischeTauschungzeichnen_ActionPerformed'
|
||||
Text = 'Optische T'#228'uschung zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
637
04_loesungen/03_javaeditor/alg10_balkendiagramm_loesung/XML.java
Normal file
637
04_loesungen/03_javaeditor/alg10_balkendiagramm_loesung/XML.java
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,70 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* Balkendiagramm für int-Array, Zahlen werden zufällig erzeugt.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
public class Balkendiagramm extends Picture
|
||||
{
|
||||
// Liste mit allen Werten
|
||||
int[] zahlen;
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public Balkendiagramm() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// Zufallszahlen erzeugen und anzeigen
|
||||
erzeugeZufallsarray(20);
|
||||
|
||||
zeichneBalken();
|
||||
}
|
||||
|
||||
public int getZufallszahl(int min, int max) {
|
||||
java.util.Random r = new java.util.Random();
|
||||
return r.nextInt(max-min+1)+min;
|
||||
}
|
||||
|
||||
public void erzeugeZufallsarray(int laenge) {
|
||||
// Neues Array der richtigen Länge erzeugen
|
||||
zahlen = new int[laenge];
|
||||
|
||||
// Jedes Element mit einer Zufallszahl belegen
|
||||
for(int i= 0; i< laenge; i++) {
|
||||
zahlen[i] = getZufallszahl(1, 300);
|
||||
}
|
||||
}
|
||||
|
||||
public void zeichneBalken() {
|
||||
clear();
|
||||
|
||||
// Überschrift
|
||||
fill(255,255,255);
|
||||
textFont(grosseSchrift);
|
||||
text("Balkendiagramm", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
for (int i = 0; i< zahlen.length; i++) {
|
||||
|
||||
fill(20,30,170);
|
||||
|
||||
// Balkendiagramm zeichnen
|
||||
rect(120, 25+i*15, zahlen[i]+1, 13);
|
||||
|
||||
// Beschriftung
|
||||
fill(255,255,255);
|
||||
text("i="+i, 2, 35+i*15);
|
||||
text("zahlen["+i+"]="+zahlen[i], 30, 35+i*15);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class BalkendiagrammGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bZeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
// Ende Attribute
|
||||
|
||||
public BalkendiagrammGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bZeichnen.setBounds(256, 456, 273, 33);
|
||||
bZeichnen.setText("Balkendiagramm zeichnen");
|
||||
bZeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bZeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bZeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bZeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bZeichnen_ActionPerformed(ActionEvent evt) {
|
||||
Balkendiagramm bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
imagePanel1.getViewport().repaint();
|
||||
imagePanel1.getVerticalScrollBar().setValue(1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
} // end of bZeichnen_ActionPerformed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new BalkendiagrammGUI("BalkendiagrammGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
object BalkendiagrammGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'BalkendiagrammGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bOptischeTauschungzeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 256
|
||||
Top = 456
|
||||
Width = 273
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bOptischeTauschungzeichnen_ActionPerformed'
|
||||
Text = 'Optische T'#228'uschung zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,74 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* Balkendiagramm für int-Array, Zahlen werden aus CSV-Datei gelesen.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
public class Balkendiagramm extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten //<>//
|
||||
int[] zahlen;
|
||||
String[] namen;
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public Balkendiagramm() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// CSV-Datei laden und anzeigen
|
||||
ladeTabelle("punkte.csv");
|
||||
|
||||
zeichneBalken();
|
||||
}
|
||||
|
||||
public void ladeTabelle(String name) {
|
||||
// Tabelle aus CSV-Datei laden
|
||||
Table csv = new Table(name,"header",',','"');
|
||||
|
||||
// Initialisiere Arrays, in die alle Zeilen der Tabelle passen
|
||||
zahlen = new int[csv.getRowCount()];
|
||||
namen = new String[csv.getRowCount()];
|
||||
|
||||
// Fülle die Arrays mit Werten aus der Tabelle
|
||||
for (int i = 0; i < zahlen.length; i++) {
|
||||
// Lies Wert aus der i. Zeile und der Spalte "Punkte" bzw. "Name"
|
||||
zahlen[i] = csv.getInt(i,"Punkte");
|
||||
namen[i] = csv.getString(i,"Name");
|
||||
}
|
||||
}
|
||||
|
||||
public void zeichneBalken() {
|
||||
clear();
|
||||
|
||||
// Überschrift
|
||||
fill(255,255,255);
|
||||
textFont(grosseSchrift);
|
||||
text("Punkte", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
|
||||
for (int i = 0; i< zahlen.length; i++) {
|
||||
|
||||
fill(20,30,170);
|
||||
|
||||
// Balkendiagramm zeichnen
|
||||
rect(120, 25+i*15, zahlen[i]+1, 13);
|
||||
|
||||
// Beschriftung
|
||||
fill(255,255,255);
|
||||
text(namen[i], 2, 35+i*15);
|
||||
text(""+zahlen[i], 70, 35+i*15);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class BalkendiagrammGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bZeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
// Ende Attribute
|
||||
|
||||
public BalkendiagrammGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bZeichnen.setBounds(256, 456, 273, 33);
|
||||
bZeichnen.setText("Balkendiagramm zeichnen");
|
||||
bZeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bZeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bZeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bZeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bZeichnen_ActionPerformed(ActionEvent evt) {
|
||||
Balkendiagramm bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
imagePanel1.getViewport().repaint();
|
||||
imagePanel1.getVerticalScrollBar().setValue(1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
} // end of bZeichnen_ActionPerformed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new BalkendiagrammGUI("BalkendiagrammGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
object BalkendiagrammGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'BalkendiagrammGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bOptischeTauschungzeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 256
|
||||
Top = 456
|
||||
Width = 273
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bOptischeTauschungzeichnen_ActionPerformed'
|
||||
Text = 'Optische T'#228'uschung zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
|||
"Name","Punkte"
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
|
|
|
@ -0,0 +1,176 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* Balkendiagramm für int-Array, Zahlen werden aus CSV-Datei gelesen, Maximum der Werte wird bestimmt.
|
||||
* Hinweis zur Benutzung:
|
||||
* Start des Algorithmus: Klicke den Button Maximumsuche an.
|
||||
* Start des automatischen Tests: Klicke den Button Testen an. Die Ausgabe erfolgt in der Konsole.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
public class Balkendiagramm extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten
|
||||
int[] zahlen;
|
||||
String[] namen;
|
||||
|
||||
|
||||
// Hilfsvariablen für die Suche
|
||||
int akt_maximum=-1; // aktuell groesstes Element
|
||||
int akt=-1; // aktuell untersuchtes Element
|
||||
int verzoegerung=100; // Geschwindigkeit der Ausführung
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public Balkendiagramm() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// Deaktiviere die automatische Neudarstellung nach einem Zeichenbefehl
|
||||
setAutoRefresh(false);
|
||||
|
||||
// CSV-Datei laden und anzeigen
|
||||
ladeTabelle("punkte.csv");
|
||||
|
||||
zeichneBalken();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ladeTabelle(String name) {
|
||||
// Tabelle aus CSV-Datei laden //<>//
|
||||
Table csv = new Table(name, "header", ',', '"');
|
||||
|
||||
if (csv != null && csv.getColumnCount()==2) {
|
||||
|
||||
// Initialisiere Arrays, in die alle Zeilen der Tabelle passen
|
||||
zahlen = new int[csv.getRowCount()];
|
||||
namen = new String[csv.getRowCount()];
|
||||
|
||||
// Fülle die Arrays mit Werten aus der Tabelle
|
||||
for (int i = 0; i < zahlen.length; i++) {
|
||||
// Lies Wert aus der i. Zeile und der Spalte "Punkte" bzw. "Name"
|
||||
zahlen[i] = csv.getInt(i, "Punkte");
|
||||
namen[i] = csv.getString(i, "Name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void zeichneBalken() {
|
||||
|
||||
clear();
|
||||
|
||||
// Überschrift
|
||||
fill(255,255,255);
|
||||
textFont(grosseSchrift);
|
||||
text("Punkte", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
if (zahlen != null) {
|
||||
for (int i = 0; i< zahlen.length; i++) {
|
||||
|
||||
fill(20,25,165);
|
||||
// aktuelle Elemente farblich hervorheben
|
||||
if (i == akt) {
|
||||
fill(140,230,20);
|
||||
}
|
||||
if (i == akt_maximum) {
|
||||
fill(230,60,140);
|
||||
}
|
||||
|
||||
// Balkendiagramm zeichnen
|
||||
if (zahlen[i]>=0) rect(120, 25+i*15, zahlen[i]+1, 13);
|
||||
|
||||
// Beschriftung
|
||||
fill(255,255,255);
|
||||
text(namen[i], 2, 35+i*15);
|
||||
text(""+zahlen[i], 70, 35+i*15);
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
public int maximumsuche() {
|
||||
// Sind überhaupt Daten da?
|
||||
if(zahlen.length==0 ) { //<>//
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Startwerte setzen
|
||||
akt_maximum = 0;
|
||||
akt = 1;
|
||||
|
||||
// Alle Arrayelemente untersuchen
|
||||
while (akt < zahlen.length) {
|
||||
// Neu zeichnen, da akt neu gesetzt wurde
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
// Neues größtes Element??
|
||||
if (zahlen[akt]> zahlen[akt_maximum]) {
|
||||
// Dann merke dir das neue
|
||||
akt_maximum = akt;
|
||||
// Zeichne Balken neu, da neues größtes Element
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
}
|
||||
akt = akt + 1;
|
||||
}
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
akt = -1;
|
||||
zeichneBalken();
|
||||
// Gib Position des größten Elements zurück
|
||||
return akt_maximum;
|
||||
}
|
||||
|
||||
public void testen() {
|
||||
|
||||
|
||||
// Testfall 1
|
||||
verzoegerung = 0; //<>//
|
||||
ladeTabelle("testfall1.csv");
|
||||
int m1 = maximumsuche();
|
||||
if (m1 == 12) {
|
||||
System.out.println("Maximum korrekt gefunden. In Datei testfall1.csv ist der größte Wert "+ zahlen[m1]+" von "+namen[m1]+" an Position "+m1);
|
||||
} else {
|
||||
System.out.println("Maximum in testfall.csv nicht gefunden. Du ermittelst "+m1+" richtig wäre 12");
|
||||
}
|
||||
// Testfall 2: negative Zahlen
|
||||
ladeTabelle("testfall2.csv");
|
||||
int m2 = maximumsuche();
|
||||
if (m2 == 3) {
|
||||
System.out.println("Maximum korrekt gefunden. In Datei testfall2.csv ist der größte Wert "+ zahlen[m2]+" von "+namen[m2]+" an Position "+m2);
|
||||
} else {
|
||||
System.out.println("Maximum in testfall2.csv nicht gefunden. Du ermittelst "+m2+" richtig wäre 3");
|
||||
}
|
||||
// Testfall 3: Nur 1 Element
|
||||
ladeTabelle("testfall3.csv");
|
||||
int m3 = maximumsuche();
|
||||
if (m3 == 0) {
|
||||
System.out.println("Maximum korrekt gefunden. In Datei testfall3.csv ist der größte Wert "+ zahlen[m3]+" von "+namen[m3]+" an Position "+m3);
|
||||
} else {
|
||||
System.out.println("Maximum in testfall3.csv nicht gefunden. Du ermittelst "+m3+" richtig wäre 0");
|
||||
}
|
||||
// Testfall 4: Leere Liste
|
||||
ladeTabelle("testfall4.csv");
|
||||
int m4 = maximumsuche();
|
||||
if (m4 == -1) {
|
||||
System.out.println("Maximum korrekt gefunden. Da die Datei keine Spieler enthält wird -1 zurückgegeben.");
|
||||
} else {
|
||||
System.out.println("Maximum in testfall4.csv nicht gefunden. Du ermittelst "+m4+" richtig wäre -1, da die Datei leer ist.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class BalkendiagrammGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bZeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
private JButton bMaximumsuche = new JButton();
|
||||
private JButton bTesten = new JButton();
|
||||
private Balkendiagramm bild;
|
||||
private Picture b;
|
||||
private Timer timer1 = new Timer(1000, null);
|
||||
// Ende Attribute
|
||||
|
||||
public BalkendiagrammGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bZeichnen.setBounds(24, 456, 209, 33);
|
||||
bZeichnen.setText("Balkendiagramm zeichnen");
|
||||
bZeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bZeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bZeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bZeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
bMaximumsuche.setBounds(280, 456, 201, 33);
|
||||
bMaximumsuche.setText("Maximumsuche");
|
||||
bMaximumsuche.setMargin(new Insets(2, 2, 2, 2));
|
||||
bMaximumsuche.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bMaximumsuche_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bMaximumsuche);
|
||||
bTesten.setBounds(512, 456, 185, 33);
|
||||
bTesten.setText("Testen");
|
||||
bTesten.setMargin(new Insets(2, 2, 2, 2));
|
||||
bTesten.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bTesten_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bTesten);
|
||||
timer1.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
timer1_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
b = new Picture(700,800);
|
||||
imagePanel1.setImage(b);
|
||||
b.setObserver(imagePanel1);
|
||||
timer1.setRepeats(true);
|
||||
timer1.setInitialDelay(0);
|
||||
timer1.setDelay(100);
|
||||
timer1.start();
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosed(WindowEvent evt) {
|
||||
BalkendiagrammGUI_WindowClosed(evt);
|
||||
}
|
||||
});
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bZeichnen_ActionPerformed(ActionEvent evt) {
|
||||
bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
} // end of bZeichnen_ActionPerformed
|
||||
|
||||
public void bMaximumsuche_ActionPerformed(ActionEvent evt) {
|
||||
bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
new Thread( new Runnable() {
|
||||
@Override public void run() {
|
||||
bild.maximumsuche();
|
||||
}
|
||||
} ).start();
|
||||
} // end of bMaximumsuche_ActionPerformed
|
||||
|
||||
public void bTesten_ActionPerformed(ActionEvent evt) {
|
||||
bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
bild.testen();
|
||||
} // end of bTesten_ActionPerformed
|
||||
|
||||
public void timer1_ActionPerformed(ActionEvent evt) {
|
||||
imagePanel1.getViewport().repaint();
|
||||
|
||||
} // end of timer1_ActionPerformed
|
||||
|
||||
public void BalkendiagrammGUI_WindowClosed(WindowEvent evt) {
|
||||
timer1.stop();
|
||||
|
||||
} // end of BalkendiagrammGUI_WindowClosed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new BalkendiagrammGUI("BalkendiagrammGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
object BalkendiagrammGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'BalkendiagrammGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
windowClosed = 'BalkendiagrammGUI_WindowClosed'
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bZeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 24
|
||||
Top = 456
|
||||
Width = 209
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bZeichnen_ActionPerformed'
|
||||
Text = 'Balkendiagramm zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object bMaximumsuche: TJButton
|
||||
Tag = 4
|
||||
Left = 280
|
||||
Top = 456
|
||||
Width = 201
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bMaximumsuche_ActionPerformed'
|
||||
Text = 'Maximumsuche'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object bTesten: TJButton
|
||||
Tag = 4
|
||||
Left = 512
|
||||
Top = 456
|
||||
Width = 185
|
||||
Height = 33
|
||||
Hint = 'jButton2'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bTesten_ActionPerformed'
|
||||
Text = 'Testen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object timer1: TTimer
|
||||
Tag = 49
|
||||
Left = 712
|
||||
Top = 456
|
||||
Width = 33
|
||||
Height = 28
|
||||
Hint = 'timer1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'timer1_ActionPerformed'
|
||||
Coalesce = False
|
||||
Delay = 100
|
||||
InitialDelay = 0
|
||||
LogTimers = False
|
||||
Repeats = True
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
894
04_loesungen/03_javaeditor/alg13_maximumsuche_loesung/Table.java
Normal file
894
04_loesungen/03_javaeditor/alg13_maximumsuche_loesung/Table.java
Normal file
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
637
04_loesungen/03_javaeditor/alg13_maximumsuche_loesung/XML.java
Normal file
637
04_loesungen/03_javaeditor/alg13_maximumsuche_loesung/XML.java
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,36 @@
|
|||
"Name","Punkte"
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,0
|
||||
Spieler1,6
|
||||
Spieler2,19
|
||||
Spieler6,1
|
||||
Spieler4,45
|
||||
Spieler3,23
|
||||
Spieler3,12
|
||||
Spieler2,44
|
||||
Spieler1,72
|
||||
Spieler5,12
|
||||
Spieler6,4
|
||||
Spieler7,2
|
||||
Spieler4,98
|
||||
Spieler3,21
|
||||
Spieler3,12
|
||||
Spieler2,32
|
||||
Spieler1,12
|
||||
Spieler5,44
|
||||
Spieler3,12
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,-5
|
||||
Spieler1,-6
|
||||
Spieler2,-19
|
||||
Spieler6,-1
|
||||
Spieler4,-45
|
||||
Spieler3,-23
|
||||
Spieler3,-12
|
||||
Spieler2,-44
|
||||
Spieler1,-72
|
||||
Spieler5,-12
|
||||
Spieler6,-4
|
||||
Spieler7,-2
|
||||
Spieler4,-98
|
||||
Spieler3,-21
|
||||
Spieler3,-12
|
||||
Spieler2,-32
|
||||
Spieler1,-12
|
||||
Spieler5,-44
|
||||
Spieler3,-12
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,45
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"Name","Punkte"
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* Balkendiagramm für int-Array, Zahlen werden aus CSV-Datei gelesen, Minimum der Werte wird bestimmt.
|
||||
* Hinweis zur Benutzung:
|
||||
* Start des Algorithmus: Klicke den Button Maximumsuche an.
|
||||
* Start des automatischen Tests: Klicke den Button Testen an. Die Ausgabe erfolgt in der Konsole.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
public class Balkendiagramm extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten
|
||||
int[] zahlen;
|
||||
String[] namen;
|
||||
|
||||
|
||||
// Hilfsvariablen für die Suche
|
||||
int akt_minimum=-1; // aktuell kleinstes Element
|
||||
int akt=-1; // aktuell untersuchtes Element
|
||||
int verzoegerung=1000; // Geschwindigkeit der Ausführung
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public Balkendiagramm() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// Deaktiviere die automatische Neudarstellung nach einem Zeichenbefehl
|
||||
setAutoRefresh(false);
|
||||
|
||||
// CSV-Datei laden und anzeigen
|
||||
ladeTabelle("punkte.csv");
|
||||
|
||||
zeichneBalken();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ladeTabelle(String name) {
|
||||
// Tabelle aus CSV-Datei laden //<>//
|
||||
Table csv = new Table(name, "header", ',', '"');
|
||||
|
||||
if (csv != null && csv.getColumnCount()==2) {
|
||||
|
||||
// Initialisiere Arrays, in die alle Zeilen der Tabelle passen
|
||||
zahlen = new int[csv.getRowCount()];
|
||||
namen = new String[csv.getRowCount()];
|
||||
|
||||
// Fülle die Arrays mit Werten aus der Tabelle
|
||||
for (int i = 0; i < zahlen.length; i++) {
|
||||
// Lies Wert aus der i. Zeile und der Spalte "Punkte" bzw. "Name"
|
||||
zahlen[i] = csv.getInt(i, "Punkte");
|
||||
namen[i] = csv.getString(i, "Name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void zeichneBalken() {
|
||||
|
||||
clear();
|
||||
|
||||
// Überschrift
|
||||
fill(255,255,255);
|
||||
textFont(grosseSchrift);
|
||||
text("Punkte", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
if (zahlen != null) {
|
||||
for (int i = 0; i< zahlen.length; i++) {
|
||||
|
||||
fill(20,25,165);
|
||||
// aktuelle Elemente farblich hervorheben
|
||||
if (i == akt) {
|
||||
fill(140,230,20);
|
||||
}
|
||||
if (i == akt_minimum) {
|
||||
fill(230,60,140);
|
||||
}
|
||||
|
||||
// Balkendiagramm zeichnen
|
||||
if (zahlen[i]>=0) rect(120, 25+i*15, zahlen[i]+1, 13);
|
||||
|
||||
// Beschriftung
|
||||
fill(255,255,255);
|
||||
text(namen[i], 2, 35+i*15);
|
||||
text(""+zahlen[i], 70, 35+i*15);
|
||||
}
|
||||
}
|
||||
refresh();
|
||||
}
|
||||
|
||||
|
||||
public int minimumsuche() {
|
||||
// Sind überhaupt Daten da?
|
||||
if(zahlen.length==0 ) { //<>//
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Startwerte setzen
|
||||
akt_minimum = 0;
|
||||
akt = 1;
|
||||
|
||||
// Alle Arrayelemente untersuchen
|
||||
while (akt < zahlen.length) {
|
||||
// Neu zeichnen, da akt neu gesetzt wurde
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
// Neues kleinstes Element??
|
||||
if (zahlen[akt] < zahlen[akt_minimum]) {
|
||||
// Dann merke dir das neue
|
||||
akt_minimum = akt;
|
||||
// Zeichne Balken neu, da neues kleinstes Element
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
}
|
||||
akt = akt + 1;
|
||||
}
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
akt=-1;
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
// Gib Position des kleinsten Elements zurück
|
||||
return akt_minimum;
|
||||
}
|
||||
|
||||
public boolean testen() {
|
||||
boolean allesBestanden = true;
|
||||
// Testfall 1
|
||||
verzoegerung = 0; //<>//
|
||||
ladeTabelle("testfall1.csv");
|
||||
int m1 = minimumsuche();
|
||||
if (m1 == 0) {
|
||||
System.out.println("Minimum korrekt gefunden. In Datei testfall1.csv ist der größte Wert "+ zahlen[m1]+" von "+namen[m1]+" an Position "+m1);
|
||||
|
||||
} else {
|
||||
System.out.println("Minimum in testfall.csv nicht gefunden. Du ermittelst "+m1+" richtig wäre 12");
|
||||
allesBestanden = false;
|
||||
}
|
||||
// Testfall 2: negative Zahlen
|
||||
ladeTabelle("testfall2.csv");
|
||||
int m2 = minimumsuche();
|
||||
if (m2 == 12) {
|
||||
System.out.println("Minimum korrekt gefunden. In Datei testfall2.csv ist der größte Wert "+ zahlen[m2]+" von "+namen[m2]+" an Position "+m2);
|
||||
} else {
|
||||
System.out.println("Minimum in testfall2.csv nicht gefunden. Du ermittelst "+m2+" richtig wäre 3");
|
||||
allesBestanden = false;
|
||||
}
|
||||
// Testfall 3: Nur 1 Element
|
||||
ladeTabelle("testfall3.csv");
|
||||
int m3 = minimumsuche();
|
||||
if (m3 == 0) {
|
||||
System.out.println("Minimum korrekt gefunden. In Datei testfall3.csv ist der größte Wert "+ zahlen[m3]+" von "+namen[m3]+" an Position "+m3);
|
||||
} else {
|
||||
System.out.println("Minimum in testfall3.csv nicht gefunden. Du ermittelst "+m3+" richtig wäre 0");
|
||||
allesBestanden = false;
|
||||
}
|
||||
// Testfall 4: Leere Liste
|
||||
ladeTabelle("testfall4.csv");
|
||||
int m4 = minimumsuche();
|
||||
if (m4 == -1) {
|
||||
System.out.println("Minimum korrekt gefunden. Da die Datei keine Spieler enthält wird -1 zurückgegeben.");
|
||||
} else {
|
||||
System.out.println("Minimum in testfall4.csv nicht gefunden. Du ermittelst "+m4+" richtig wäre -1, da die Datei leer ist.");
|
||||
allesBestanden = false;
|
||||
}
|
||||
return allesBestanden;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class BalkendiagrammGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bZeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
private JButton bMaximumsuche = new JButton();
|
||||
private JButton bTesten = new JButton();
|
||||
private Balkendiagramm bild;
|
||||
private Picture b;
|
||||
private Timer timer1 = new Timer(1000, null);
|
||||
// Ende Attribute
|
||||
|
||||
public BalkendiagrammGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bZeichnen.setBounds(24, 456, 209, 33);
|
||||
bZeichnen.setText("Balkendiagramm zeichnen");
|
||||
bZeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bZeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bZeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bZeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
bMaximumsuche.setBounds(280, 456, 201, 33);
|
||||
bMaximumsuche.setText("Minimumsuche");
|
||||
bMaximumsuche.setMargin(new Insets(2, 2, 2, 2));
|
||||
bMaximumsuche.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bMaximumsuche_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bMaximumsuche);
|
||||
bTesten.setBounds(512, 456, 185, 33);
|
||||
bTesten.setText("Testen");
|
||||
bTesten.setMargin(new Insets(2, 2, 2, 2));
|
||||
bTesten.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bTesten_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bTesten);
|
||||
timer1.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
timer1_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
b = new Picture(700,800);
|
||||
imagePanel1.setImage(b);
|
||||
b.setObserver(imagePanel1);
|
||||
timer1.setRepeats(true);
|
||||
timer1.setInitialDelay(0);
|
||||
timer1.setDelay(100);
|
||||
timer1.start();
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosed(WindowEvent evt) {
|
||||
BalkendiagrammGUI_WindowClosed(evt);
|
||||
}
|
||||
});
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bZeichnen_ActionPerformed(ActionEvent evt) {
|
||||
bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
} // end of bZeichnen_ActionPerformed
|
||||
|
||||
public void bMaximumsuche_ActionPerformed(ActionEvent evt) {
|
||||
bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
new Thread( new Runnable() {
|
||||
@Override public void run() {
|
||||
bild.minimumsuche();
|
||||
}
|
||||
} ).start();
|
||||
} // end of bMaximumsuche_ActionPerformed
|
||||
|
||||
public void bTesten_ActionPerformed(ActionEvent evt) {
|
||||
bild = new Balkendiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
bild.testen();
|
||||
} // end of bTesten_ActionPerformed
|
||||
|
||||
public void timer1_ActionPerformed(ActionEvent evt) {
|
||||
imagePanel1.getViewport().repaint();
|
||||
|
||||
} // end of timer1_ActionPerformed
|
||||
|
||||
public void BalkendiagrammGUI_WindowClosed(WindowEvent evt) {
|
||||
timer1.stop();
|
||||
|
||||
} // end of BalkendiagrammGUI_WindowClosed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new BalkendiagrammGUI("BalkendiagrammGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,213 @@
|
|||
object BalkendiagrammGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'BalkendiagrammGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
windowClosed = 'BalkendiagrammGUI_WindowClosed'
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bZeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 24
|
||||
Top = 456
|
||||
Width = 209
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bZeichnen_ActionPerformed'
|
||||
Text = 'Balkendiagramm zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object bMaximumsuche: TJButton
|
||||
Tag = 4
|
||||
Left = 280
|
||||
Top = 456
|
||||
Width = 201
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bMaximumsuche_ActionPerformed'
|
||||
Text = 'Maximumsuche'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object bTesten: TJButton
|
||||
Tag = 4
|
||||
Left = 512
|
||||
Top = 456
|
||||
Width = 185
|
||||
Height = 33
|
||||
Hint = 'jButton2'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bTesten_ActionPerformed'
|
||||
Text = 'Testen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object timer1: TTimer
|
||||
Tag = 49
|
||||
Left = 712
|
||||
Top = 456
|
||||
Width = 33
|
||||
Height = 28
|
||||
Hint = 'timer1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'timer1_ActionPerformed'
|
||||
Coalesce = False
|
||||
Delay = 100
|
||||
InitialDelay = 0
|
||||
LogTimers = False
|
||||
Repeats = True
|
||||
end
|
||||
end
|
||||
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
637
04_loesungen/03_javaeditor/alg13_variante_minimumsuche/XML.java
Normal file
637
04_loesungen/03_javaeditor/alg13_variante_minimumsuche/XML.java
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
|||
"Name","Punkte"
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,0
|
||||
Spieler1,6
|
||||
Spieler2,19
|
||||
Spieler6,1
|
||||
Spieler4,45
|
||||
Spieler3,23
|
||||
Spieler3,12
|
||||
Spieler2,44
|
||||
Spieler1,72
|
||||
Spieler5,12
|
||||
Spieler6,4
|
||||
Spieler7,2
|
||||
Spieler4,98
|
||||
Spieler3,21
|
||||
Spieler3,12
|
||||
Spieler2,32
|
||||
Spieler1,12
|
||||
Spieler5,44
|
||||
Spieler3,12
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,-5
|
||||
Spieler1,-6
|
||||
Spieler2,-19
|
||||
Spieler6,-1
|
||||
Spieler4,-45
|
||||
Spieler3,-23
|
||||
Spieler3,-12
|
||||
Spieler2,-44
|
||||
Spieler1,-72
|
||||
Spieler5,-12
|
||||
Spieler6,-4
|
||||
Spieler7,-2
|
||||
Spieler4,-98
|
||||
Spieler3,-21
|
||||
Spieler3,-12
|
||||
Spieler2,-32
|
||||
Spieler1,-12
|
||||
Spieler5,-44
|
||||
Spieler3,-12
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,45
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"Name","Punkte"
|
||||
|
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,139 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* Automatische Zeitungsmeldung mit Maximum und Durchschnitt, Zahlen werden aus CSV-Datei gelesen.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
|
||||
public class Zeitungsmeldung extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten //<>//
|
||||
int[] punkte;
|
||||
String[] namen;
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public Zeitungsmeldung() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// CSV-Datei laden und anzeigen
|
||||
ladeTabelle("punkte.csv");
|
||||
int summe = berechneSumme(punkte);
|
||||
System.out.println("Summe: "+summe);
|
||||
schreibeZeitungsmeldung();
|
||||
}
|
||||
|
||||
public void ladeTabelle(String name) {
|
||||
// Tabelle aus CSV-Datei laden
|
||||
Table csv = new Table(name, "header",',','"');
|
||||
|
||||
if (csv != null && csv.getColumnCount()==2) {
|
||||
|
||||
// Initialisiere Arrays, in die alle Zeilen der Tabelle passen
|
||||
punkte = new int[csv.getRowCount()];
|
||||
namen = new String[csv.getRowCount()];
|
||||
|
||||
// Fülle die Arrays mit Werten aus der Tabelle
|
||||
for (int i = 0; i < punkte.length; i++) {
|
||||
// Lies Wert aus der i. Zeile und der Spalte "Punkte" bzw. "Name"
|
||||
punkte[i] = csv.getInt(i, "Punkte");
|
||||
namen[i] = csv.getString(i, "Name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void schreibeZeitungsmeldung() {
|
||||
|
||||
clear();
|
||||
|
||||
// Überschrift
|
||||
fill(225,225,255);
|
||||
stroke(155,155,255);
|
||||
textFont(grosseSchrift);
|
||||
text("BREAKING NEWS",5,32);
|
||||
strokeWeight(3);
|
||||
line(2,4,400,4);
|
||||
line(2,45,400,45);
|
||||
strokeWeight(2);
|
||||
line(2,7,400,7);
|
||||
line(2,42,400,42);
|
||||
strokeWeight(1);
|
||||
textFont(kleineSchrift);
|
||||
fill(240);
|
||||
|
||||
int anzahlSpieler = anzahlSpieler(namen);;
|
||||
int anzahlSpiele = punkte.length;
|
||||
int summe = berechneSumme(punkte);
|
||||
double durchschnitt = berechneDurchschnitt(punkte);
|
||||
|
||||
text("Großartiges Ergebnis - Klasse XY nimmt an Binärwettbewerb teil.", 2, 60);
|
||||
text("Die Klasse XY hat beim diesjährigen Binärwettbewerb teilgenommen", 2, 82);
|
||||
text("und ein großartiges Ergebnis erzielt. Die "+anzahlSpieler+" Schülerinnen und", 2, 94);
|
||||
text("Schüler der Klasse erreichten in "+anzahlSpiele+" Spielen eine Gesamtpunktzahl",2,106);
|
||||
text("von "+summe+". Das ist ein Durchschnitt von "+durchschnitt+" pro Spiel.",2,118);
|
||||
|
||||
}
|
||||
|
||||
public int berechneSumme(int[] zahlen) {
|
||||
int summe;
|
||||
|
||||
// Sind überhaupt Daten da?
|
||||
if(zahlen.length==0 ) { //<>//
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Startwerte setzen
|
||||
summe = 0;
|
||||
|
||||
// Alle Arrayelemente untersuchen
|
||||
for (int i=0; i< zahlen.length; i++) {
|
||||
summe = summe + zahlen[i];
|
||||
}
|
||||
// Gib die Summe zurück
|
||||
return summe;
|
||||
}
|
||||
|
||||
public double berechneDurchschnitt(int[] zahlen) {
|
||||
double durchschnitt;
|
||||
|
||||
// Berechne Durchschnitt aus der Summe
|
||||
durchschnitt = (double) berechneSumme(zahlen)/zahlen.length;
|
||||
|
||||
return durchschnitt;
|
||||
}
|
||||
|
||||
public int anzahlSpieler(String[] namen) {
|
||||
int anzahl;
|
||||
boolean gefunden;
|
||||
// Startwerte setzen
|
||||
anzahl = 0;
|
||||
|
||||
// Nach jedem Namen suchen
|
||||
for(int i=0; i< namen.length; i ++) {
|
||||
// Prüfe, ob der i. Name ein neuer Name ist
|
||||
// Kontrolliere dazu alle vorhergehenden, ob ein gleicher Name dabei ist.
|
||||
gefunden = false;
|
||||
for(int j=0; j < i; j++) {
|
||||
// Wenn der Name gleich ist, dann merke dir das
|
||||
if(namen[i].equals(namen[j])) {
|
||||
gefunden = true;
|
||||
}
|
||||
}
|
||||
// Wenn nach Kontrolle aller vorhergehender Namen der aktuelle nicht dabei
|
||||
// ist, dann ist er neu und muss gezählt werden.
|
||||
if (!gefunden) {
|
||||
anzahl++;
|
||||
}
|
||||
}
|
||||
return anzahl;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class ZeitungsmeldungGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bZeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
// Ende Attribute
|
||||
|
||||
public ZeitungsmeldungGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bZeichnen.setBounds(256, 456, 273, 33);
|
||||
bZeichnen.setText("Balkendiagramm zeichnen");
|
||||
bZeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bZeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bZeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bZeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
bZeichnen.setBounds(256, 456, 273, 33);
|
||||
bZeichnen.setText("Zeitungsmeldung generieren");
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bZeichnen_ActionPerformed(ActionEvent evt) {
|
||||
Zeitungsmeldung bild = new Zeitungsmeldung();
|
||||
imagePanel1.setImage(bild);
|
||||
imagePanel1.getViewport().repaint();
|
||||
imagePanel1.getVerticalScrollBar().setValue(1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
} // end of bZeichnen_ActionPerformed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new ZeitungsmeldungGUI("ZeitungsmeldungGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
object ZeitungsmeldungGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'ZeitungsmeldungGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bZeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 256
|
||||
Top = 456
|
||||
Width = 273
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bZeichnen_ActionPerformed'
|
||||
Text = 'Zeitungsmeldung generieren'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
end
|
||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
|||
"Name","Punkte"
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
|
|
|
@ -0,0 +1,127 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* Balkendiagramm für int-Array, Zahlen werden aus CSV-Datei gelesen, Umwandlung in sortierte Tabelle.
|
||||
* Hinweis zur Benutzung:
|
||||
* Start des Algorithmus: Klicke den Button "Was tut es?" an.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
|
||||
public class Highscore extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten //<>//
|
||||
int[] zahlen;
|
||||
String[] namen;
|
||||
|
||||
// Hilfsvariablen für die Suche
|
||||
int akt_maximum=-1; // aktuell groesstes Element
|
||||
int akt=-2; // aktuell untersuchtes Element
|
||||
int verzoegerung=1000; // Geschwindigkeit der Ausführung
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public Highscore() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// CSV-Datei laden und anzeigen
|
||||
ladeTabelle("punkte.csv");
|
||||
zeichneBalken();
|
||||
}
|
||||
|
||||
public void ladeTabelle(String name) {
|
||||
// Tabelle aus CSV-Datei laden
|
||||
Table csv = new Table(name, "header",',','"');
|
||||
|
||||
if (csv != null && csv.getColumnCount()==2) {
|
||||
|
||||
// Initialisiere Arrays, in die alle Zeilen der Tabelle passen
|
||||
zahlen = new int[csv.getRowCount()];
|
||||
namen = new String[csv.getRowCount()];
|
||||
|
||||
// Fülle die Arrays mit Werten aus der Tabelle
|
||||
for (int i = 0; i < zahlen.length; i++) {
|
||||
// Lies Wert aus der i. Zeile und der Spalte "Punkte" bzw. "Name"
|
||||
zahlen[i] = csv.getInt(i, "Punkte");
|
||||
namen[i] = csv.getString(i, "Name");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void zeichneBalken() {
|
||||
|
||||
clear();
|
||||
|
||||
// Überschrift
|
||||
fill(255, 255, 255);
|
||||
textFont(grosseSchrift);
|
||||
text("Punkte", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
if (zahlen != null) {
|
||||
for (int i = 0; i< zahlen.length; i++) {
|
||||
|
||||
fill(20, 25, 165);
|
||||
// aktuelle Elemente farblich hervorheben
|
||||
if (i == akt || i == akt+1 ) {
|
||||
fill(140, 230, 20);
|
||||
}
|
||||
|
||||
// Balkendiagramm zeichnen
|
||||
if (zahlen[i]>=0) rect(120, 25+i*15, zahlen[i]+1, 13);
|
||||
|
||||
// Beschriftung
|
||||
fill(255, 255, 255);
|
||||
text(namen[i], 2, 35+i*15);
|
||||
text(""+zahlen[i], 70, 35+i*15);
|
||||
}
|
||||
}
|
||||
}
|
||||
public void wastutes() {
|
||||
// Sind überhaupt Daten da?
|
||||
if (zahlen.length==0 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Wiederholen den Durchlauf n-1 mal
|
||||
for (int i = 1; i< zahlen.length; i++) {
|
||||
// Durchlaufe alle Array-Elemente
|
||||
for (akt=0; akt+1 < zahlen.length; akt++) {
|
||||
// Neu zeichnen, da akt neu gesetzt wurde
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
// Vergleiche mit Nachbarelement. Falsch sortiert?
|
||||
if (zahlen[akt+1]> zahlen[akt]) {
|
||||
// Dreieckstausch bei Zahlen und Namen
|
||||
int dummy = zahlen[akt];
|
||||
zahlen[akt] = zahlen[akt+1];
|
||||
zahlen[akt+1] = dummy;
|
||||
|
||||
String s = namen[akt];
|
||||
namen[akt] = namen[akt+1];
|
||||
namen[akt+1] = s;
|
||||
|
||||
// Zeichne Balken neu, da getauscht wurde
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Sortierung beendet
|
||||
akt = -2;
|
||||
zeichneBalken();
|
||||
delay(verzoegerung);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class HighscoreGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bZeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
private JButton bWastutes = new JButton();
|
||||
private Highscore bild;
|
||||
private Picture b;
|
||||
private Timer timer1 = new Timer(1000, null);
|
||||
// Ende Attribute
|
||||
|
||||
public HighscoreGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bZeichnen.setBounds(24, 456, 209, 33);
|
||||
bZeichnen.setText("Balkendiagramm zeichnen");
|
||||
bZeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bZeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bZeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bZeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
bWastutes.setBounds(280, 456, 201, 33);
|
||||
bWastutes.setText("Was tut diese Methode?");
|
||||
bWastutes.setMargin(new Insets(2, 2, 2, 2));
|
||||
bWastutes.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bWastutes_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bWastutes);
|
||||
timer1.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
timer1_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
b = new Picture(700,800);
|
||||
imagePanel1.setImage(b);
|
||||
b.setObserver(imagePanel1);
|
||||
timer1.setRepeats(true);
|
||||
timer1.setInitialDelay(0);
|
||||
timer1.setDelay(100);
|
||||
timer1.start();
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosed(WindowEvent evt) {
|
||||
BalkendiagrammGUI_WindowClosed(evt);
|
||||
}
|
||||
});
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bZeichnen_ActionPerformed(ActionEvent evt) {
|
||||
bild = new Highscore();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
} // end of bZeichnen_ActionPerformed
|
||||
|
||||
public void bWastutes_ActionPerformed(ActionEvent evt) {
|
||||
new Thread( new Runnable() {
|
||||
@Override public void run() {
|
||||
bild.wastutes();
|
||||
}
|
||||
} ).start();
|
||||
} // end of bWastutes_ActionPerformed
|
||||
|
||||
public void timer1_ActionPerformed(ActionEvent evt) {
|
||||
imagePanel1.getViewport().repaint();
|
||||
|
||||
} // end of timer1_ActionPerformed
|
||||
|
||||
public void BalkendiagrammGUI_WindowClosed(WindowEvent evt) {
|
||||
timer1.stop();
|
||||
|
||||
} // end of BalkendiagrammGUI_WindowClosed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new HighscoreGUI("HighscoreGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,169 @@
|
|||
object HighscoreGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'HighscoreGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
windowClosed = 'BalkendiagrammGUI_WindowClosed'
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bZeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 24
|
||||
Top = 456
|
||||
Width = 209
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bZeichnen_ActionPerformed'
|
||||
Text = 'Balkendiagramm zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object bWastutes: TJButton
|
||||
Tag = 4
|
||||
Left = 280
|
||||
Top = 456
|
||||
Width = 201
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bWastutes_ActionPerformed'
|
||||
Text = 'Was tut diese Methode?'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object timer1: TTimer
|
||||
Tag = 49
|
||||
Left = 712
|
||||
Top = 456
|
||||
Width = 33
|
||||
Height = 28
|
||||
Hint = 'timer1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'timer1_ActionPerformed'
|
||||
Coalesce = False
|
||||
Delay = 100
|
||||
InitialDelay = 0
|
||||
LogTimers = False
|
||||
Repeats = True
|
||||
end
|
||||
end
|
||||
699
04_loesungen/03_javaeditor/alg14b_highscore_loesung/Picture.java
Normal file
699
04_loesungen/03_javaeditor/alg14b_highscore_loesung/Picture.java
Normal file
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
894
04_loesungen/03_javaeditor/alg14b_highscore_loesung/Table.java
Normal file
894
04_loesungen/03_javaeditor/alg14b_highscore_loesung/Table.java
Normal file
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
637
04_loesungen/03_javaeditor/alg14b_highscore_loesung/XML.java
Normal file
637
04_loesungen/03_javaeditor/alg14b_highscore_loesung/XML.java
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
|||
"Name","Punkte"
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,0
|
||||
Spieler1,6
|
||||
Spieler2,19
|
||||
Spieler6,1
|
||||
Spieler4,45
|
||||
Spieler3,23
|
||||
Spieler3,12
|
||||
Spieler2,44
|
||||
Spieler1,72
|
||||
Spieler5,12
|
||||
Spieler6,4
|
||||
Spieler7,2
|
||||
Spieler4,98
|
||||
Spieler3,21
|
||||
Spieler3,12
|
||||
Spieler2,32
|
||||
Spieler1,12
|
||||
Spieler5,44
|
||||
Spieler3,12
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,-5
|
||||
Spieler1,-6
|
||||
Spieler2,-19
|
||||
Spieler6,-1
|
||||
Spieler4,-45
|
||||
Spieler3,-23
|
||||
Spieler3,-12
|
||||
Spieler2,-44
|
||||
Spieler1,-72
|
||||
Spieler5,-12
|
||||
Spieler6,-4
|
||||
Spieler7,-2
|
||||
Spieler4,-98
|
||||
Spieler3,-21
|
||||
Spieler3,-12
|
||||
Spieler2,-32
|
||||
Spieler1,-12
|
||||
Spieler5,-44
|
||||
Spieler3,-12
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
"Name","Punkte"
|
||||
Spieler1,45
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
"Name","Punkte"
|
||||
|
12219
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a1/Amplitudes.csv
Normal file
12219
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a1/Amplitudes.csv
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
637
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a1/XML.java
Normal file
637
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a1/XML.java
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,115 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* XY-Diagramm für Schalldruckpegel, Zahlen werden aus CSV-Datei gelesen.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
public class XYDiagramm extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten
|
||||
double[] x_werte;
|
||||
double[] y_werte;
|
||||
|
||||
// Hilfsvariablen für die Suche
|
||||
int akt_maximum=-1; // aktuell groesstes Element
|
||||
int akt=-1; // aktuell untersuchtes Element
|
||||
int verzoegerung=0; // Geschwindigkeit der Ausführung
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public XYDiagramm() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// CSV-Datei laden und anzeigen
|
||||
ladeTabelle("Amplitudes.csv");
|
||||
stroke(250,250,200);
|
||||
zeichneBalken();
|
||||
}
|
||||
|
||||
public void ladeTabelle(String name) {
|
||||
// Tabelle aus CSV-Datei laden
|
||||
Table csv = new Table(name, "header",',','"');
|
||||
|
||||
if (csv != null && csv.getColumnCount()==2) {
|
||||
|
||||
// Initialisiere Arrays, in die alle Zeilen der Tabelle passen
|
||||
x_werte = new double[csv.getRowCount()];
|
||||
y_werte = new double[csv.getRowCount()];
|
||||
|
||||
// Fülle die Arrays mit Werten aus der Tabelle
|
||||
for (int i = 0; i < x_werte.length; i++) {
|
||||
// Lies Wert aus der i. Zeile und der Spalte "Punkte" bzw. "Name"
|
||||
x_werte[i] = csv.getDouble(i, "Zeit");
|
||||
y_werte[i] = csv.getDouble(i, "Laerm");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void zeichneBalken() {
|
||||
|
||||
// Überschrift
|
||||
fill(255,255,255);
|
||||
textFont(grosseSchrift);
|
||||
text("Lärmpegel", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
if (x_werte != null) {
|
||||
for (int i = 0; i< 40; i++) {
|
||||
|
||||
fill(20,25,165);
|
||||
// aktuelle Elemente farblich hervorheben
|
||||
if (i == akt) {
|
||||
fill(140,230,20);
|
||||
}
|
||||
if (i == akt_maximum) {
|
||||
fill(230,60,140);
|
||||
}
|
||||
|
||||
// Balkendiagramm zeichnen
|
||||
int breite = (int) y_werte[i];
|
||||
if (breite>=0) rect(160, 25+i*15, breite+1, 13);
|
||||
|
||||
// Beschriftung
|
||||
fill(255,255,255);
|
||||
text(String.format("%.4f", x_werte[i]), 2, 35+i*15);
|
||||
text(String.format("%.4f", y_werte[i]), 70, 35+i*15);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public int sucheMaximum(int[] zahlen) {
|
||||
// Sind überhaupt Daten da?
|
||||
if(zahlen.length==0 ) { //<>//
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Startwerte setzen
|
||||
akt_maximum = 0;
|
||||
akt = 1;
|
||||
|
||||
// Alle Arrayelemente untersuchen
|
||||
while (akt < zahlen.length) {
|
||||
|
||||
// Neues größtes Element??
|
||||
if (zahlen[akt]> zahlen[akt_maximum]) {
|
||||
// Dann merke dir das neue
|
||||
akt_maximum = akt;
|
||||
|
||||
}
|
||||
akt = akt + 1;
|
||||
}
|
||||
// Gib Position des größten Elements zurück
|
||||
return akt_maximum;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,82 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
public class XYDiagrammGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bXYDiagrammzeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
private XYDiagramm bild;
|
||||
private Picture b;
|
||||
// Ende Attribute
|
||||
|
||||
public XYDiagrammGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bXYDiagrammzeichnen.setBounds(280, 456, 209, 33);
|
||||
bXYDiagrammzeichnen.setText("XY-Diagramm zeichnen");
|
||||
bXYDiagrammzeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bXYDiagrammzeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bXYDiagrammzeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bXYDiagrammzeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
b = new Picture(700,800);
|
||||
imagePanel1.setImage(b);
|
||||
b.setObserver(imagePanel1);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosed(WindowEvent evt) {
|
||||
BalkendiagrammGUI_WindowClosed(evt);
|
||||
}
|
||||
});
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bXYDiagrammzeichnen_ActionPerformed(ActionEvent evt) {
|
||||
bild = new XYDiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
} // end of bXYDiagrammzeichnen_ActionPerformed
|
||||
|
||||
public void BalkendiagrammGUI_WindowClosed(WindowEvent evt) {
|
||||
|
||||
|
||||
} // end of BalkendiagrammGUI_WindowClosed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new XYDiagrammGUI("XYDiagrammGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
object XYDiagrammGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'XYDiagrammGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
windowClosed = 'BalkendiagrammGUI_WindowClosed'
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bXYDiagrammzeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 280
|
||||
Top = 456
|
||||
Width = 209
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bXYDiagrammzeichnen_ActionPerformed'
|
||||
Text = 'XY-Diagramm zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
end
|
||||
Binary file not shown.
|
|
@ -0,0 +1,6 @@
|
|||
"Name","Punkte"
|
||||
Niko,216
|
||||
Klaus,591
|
||||
Anna,857
|
||||
Lena,180
|
||||
Winfried,168
|
||||
|
12219
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a2/Amplitudes.csv
Normal file
12219
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a2/Amplitudes.csv
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,699 @@
|
|||
import java.awt.image.*;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.BasicStroke;
|
||||
import java.util.Vector;
|
||||
import javax.imageio.*;
|
||||
import java.io.*;
|
||||
import java.awt.*;
|
||||
import javax.swing.*;
|
||||
import java.util.Random;
|
||||
import java.awt.geom.AffineTransform;
|
||||
/**
|
||||
*
|
||||
* Bildklasse für die Simulation von Processing-Befehlen
|
||||
*
|
||||
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
|
||||
* werden kann.
|
||||
* Zusätzlich kann ein Bildanzeiger über jede Änderung des Bildes informiert werden,
|
||||
* um "Zurück"-Befehle zu ermöglichen. Der Bildanzeiger ist entweder eine normale Java
|
||||
* ScrollPane oder ein Actor aus Greenfoot.
|
||||
* Die Dokumentation der einzelnen Zeichenmethoden ist der Processing-Reference
|
||||
* (https://processing.org/reference/ steht unter CC-Lizenz: https://creativecommons.org/)
|
||||
* entnommen und mit Deepl.com ins Deutsche übersetzt.
|
||||
*
|
||||
* @version 1.0 from 23.01.2019
|
||||
* @author Thomas Schaller (ZPG Informatik Klasse 9)
|
||||
*/
|
||||
|
||||
public class Picture{
|
||||
|
||||
// Einstellungmöglichkeiten für das Zeichnen von Rechtecken und Ellipsen
|
||||
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Höhe wird gegeben,
|
||||
// CORNER = Linke obere Ecke + Breite/Höhe, CORNERS = Linke obere und rechte untere Ecke
|
||||
public static final int RADIUS = 1;
|
||||
public static final int CENTER = 2;
|
||||
public static final int CORNER = 3;
|
||||
public static final int CORNERS = 4;
|
||||
|
||||
// gespeichertes Bild,
|
||||
private BufferedImage image;
|
||||
|
||||
// aktuelle Farbeinstellungen
|
||||
private Color background;
|
||||
private Color pencolor;
|
||||
private Color fillcolor;
|
||||
|
||||
// aktuelle Stiftdicke
|
||||
private double stroke;
|
||||
|
||||
// akkteller Koordinatenmodus von Rechtecken und Ellipsen
|
||||
private int ellipseMode = CENTER;
|
||||
private int rectMode = CORNER;
|
||||
|
||||
// aktueller Font
|
||||
private Font textfont = null;
|
||||
|
||||
// muss ein Bildanzeiger benachrichtigt werden
|
||||
private PictureViewer observer = null;
|
||||
private boolean autorefresh = true;
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild mit Standardgröße 500x400
|
||||
*/
|
||||
public Picture() {
|
||||
this(500,400);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegeben Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public Picture(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild aus einer Datei
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public Picture(String filename) {
|
||||
load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein Bild der angegebenen Größe mit festgelegtem Hintergrund
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds
|
||||
*/
|
||||
public Picture(int width, int height, String background) {
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
this.background = decode(background);
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.stroke = 1;
|
||||
this.fillcolor = null;
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(this.background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, wer das Bild anzeigt.
|
||||
* Diese ermöglicht die Benachrichtung des Observers, wenn sich das Bild ändert.
|
||||
* @param observer Anzeiger des Bildes
|
||||
*/
|
||||
|
||||
public void setObserver(PictureViewer observer) {
|
||||
this.observer= observer;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Setzen des Bildes (für interne Zwecke)
|
||||
* @param b Bild, das gespeichert werden soll.
|
||||
*/
|
||||
public void setImage(BufferedImage b) {
|
||||
image = b;
|
||||
}
|
||||
|
||||
/**
|
||||
* Direktes Abfragen des Bildes (für interne Zwecke)
|
||||
* @return Bild, das gerade gespeichert ist.
|
||||
*/
|
||||
public BufferedImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
pushImage();
|
||||
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,width-1, height-1);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getWidth() {
|
||||
return image.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getHeight() {
|
||||
return image.getHeight();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine Kopie des Bildes und übergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
|
||||
*/
|
||||
private void pushImage() {
|
||||
if(observer != null) {
|
||||
observer.pushImage();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
|
||||
* der Oberfläche aktualisiert wird. Die Einstellung "false" beschleunigt
|
||||
* das Zeichnen aufwändiger Bilder und verhindert "Flackern".
|
||||
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgelöst werden.
|
||||
* @param autorefresh true = nach jedem Zeichenbefehl die Anzeige aktualisieren, false= nur durch die Methode refresh neu zeichnen
|
||||
*/
|
||||
public void setAutoRefresh(boolean autoRefresh) {
|
||||
this.autorefresh = autoRefresh;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
private void repaint() {
|
||||
if(observer != null && autorefresh) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Auch die anzeigenden Klasse wird zum Neuzeichnen aufgefordert.
|
||||
*/
|
||||
public void refresh() {
|
||||
if(observer != null) {
|
||||
observer.repaint();
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
|
||||
public void clear(){
|
||||
pushImage();
|
||||
image = new BufferedImage(image.getWidth(), image.getHeight(), image.getType());
|
||||
Graphics2D g = (Graphics2D) this.image.getGraphics();
|
||||
g.setColor(background);
|
||||
g.fillRect(0,0,image.getWidth()-1, image.getHeight()-1);
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Konvertiert die in einem bestimmten Modus gegebenen Koordinaten in die Java-übliche Links_Oben_Breite_Höhe Version
|
||||
* Die Änderungen werden direkt im Array vorgenommen
|
||||
* @param coord Array mit vier Koordinateneinträgen im gegebenen Modus
|
||||
* @param mode Modus der Koordinaten (CORNER, CORNERS, RADIUS oder CENTER)
|
||||
*/
|
||||
private void convert(int[] coord, int mode) {
|
||||
switch(mode) {
|
||||
case CORNER: break;
|
||||
case CORNERS: coord[2] -= coord[0]; coord[3] -= coord[1]; break;
|
||||
case RADIUS: coord[2] *= 2; coord[3] *=2;
|
||||
case CENTER: coord[0] -= coord[2]/2; coord[1] -= coord[3]/2;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
rectMode = mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
ellipseMode = mode;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
if (stroke > 0) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawLine(x1, y1, x2, y2);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, rectMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawRect(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
int[] coord = {a,b,c,d};
|
||||
convert(coord, ellipseMode);
|
||||
if(fillcolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.fillOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawOval(coord[0], coord[1], coord[2], coord[3]);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
int px[] = {x1, x2, x3};
|
||||
int py[] = {y1, y2, y3};
|
||||
polygon(px, py);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
|
||||
int px[] = {x1, x2, x3, x4};
|
||||
int py[] = {y1, y2, y3, y4};
|
||||
polygon(px, py);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
|
||||
public void polygon(int[] x, int[] y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(fillcolor != null) {
|
||||
|
||||
g.setColor(fillcolor);
|
||||
g.fillPolygon(x,y, y.length);
|
||||
}
|
||||
if(pencolor != null) {
|
||||
g.setColor(pencolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.drawPolygon(x, y, x.length);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
ellipse(x,y,1, 1);
|
||||
|
||||
}
|
||||
|
||||
// ----------------------------------------- Schriftdarstellung -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param s Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String s, int x, int y) {
|
||||
pushImage();
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
|
||||
if(pencolor != null) {
|
||||
g.setColor(fillcolor);
|
||||
g.setStroke(new BasicStroke((float) stroke));
|
||||
g.setFont(textfont);
|
||||
g.drawString(s, x, y);
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
this.textfont = font;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Farbfestlegungen -----------------------------------------------
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(String color) {
|
||||
try{
|
||||
return new Color(
|
||||
Integer.valueOf( color.substring( 0, 2 ), 16 ),
|
||||
Integer.valueOf( color.substring( 2, 4 ), 16 ),
|
||||
Integer.valueOf( color.substring( 4, 6 ), 16 ) );
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zur Interpretation von Farben
|
||||
*/
|
||||
private Color decode(int color) {
|
||||
try{
|
||||
if(color >=0 && color < 256) {
|
||||
return new Color(color,color,color);
|
||||
} else {
|
||||
int r = color / 0x010000 % 0xFF;
|
||||
int g = color / 0x000100 % 0xFF;
|
||||
int b = color % 0xFF;
|
||||
System.out.println(""+r+","+g+","+b);
|
||||
return new Color(r, g, b );
|
||||
}
|
||||
} catch (Exception e) {
|
||||
System.out.println("Falscher Farbcode");
|
||||
return Color.BLACK;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
this.pencolor = decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
this.pencolor=decode(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
this.pencolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
this.pencolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
this.stroke = width;
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
this.fillcolor = decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
this.fillcolor=decode(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
this.fillcolor = new Color(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
this.fillcolor = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
if(c < 256) {
|
||||
this.background=new Color(c,c,c);
|
||||
} else {
|
||||
int r = c / 0x010000;
|
||||
int g = c / 0x000100 % 0xFF;
|
||||
int b = c % 0xFF;
|
||||
this.background= new Color(r, g, b );
|
||||
}
|
||||
|
||||
this.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
this.background=new Color(r,g,b);
|
||||
this.clear();
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Dateioperationen -----------------------------------------------
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
try{
|
||||
this.image = ImageIO.read(new File(filename));
|
||||
this.background = decode("D0D0D0");
|
||||
this.pencolor = new Color(0,0,0);
|
||||
this.fillcolor = null;
|
||||
this.stroke = 1;
|
||||
this.repaint();
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Einlesen der Bilddatei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
try{
|
||||
String[] fn = filename.split("\\.");
|
||||
if (fn.length== 1) {
|
||||
ImageIO.write(image, "PNG", new File(filename+".png"));
|
||||
} else {
|
||||
|
||||
if (fn.length == 2 && (fn[1].toUpperCase().equals("PNG") ||
|
||||
fn[1].toUpperCase().equals("GIF"))){
|
||||
ImageIO.write(image, fn[1], new File(filename));
|
||||
}else {
|
||||
System.out.println("Unbekanntes Bildformat");
|
||||
}
|
||||
}
|
||||
|
||||
} catch(Exception e) {
|
||||
System.out.println("Fehler beim Speichern");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------- Sonstiges -----------------------------------------------
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
|
||||
public Color[][] getPixelArray() {
|
||||
Color[][] pixel = new Color[image.getWidth()][image.getHeight()];
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
pixel[x][y] = new java.awt.Color(image.getRGB(x,y));
|
||||
}
|
||||
}
|
||||
return pixel;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
size(pixel.length,pixel[0].length);
|
||||
Graphics2D g = (Graphics2D) image.getGraphics();
|
||||
for(int x=0; x < image.getWidth(); x++){
|
||||
for(int y=0; y < image.getHeight(); y++) {
|
||||
g.setColor(pixel[x][y]);
|
||||
g.fillRect(x, y, 1, 1);
|
||||
}
|
||||
}
|
||||
repaint();
|
||||
}
|
||||
|
||||
/**
|
||||
* Hilfsfunktion zum Verzögern der Ausgabe
|
||||
* @param millis Wartezeit in Millisekunden
|
||||
*/
|
||||
public void delay(int millis) {
|
||||
try{
|
||||
Thread.sleep(millis);
|
||||
|
||||
} catch(Exception e) {
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,505 @@
|
|||
/**
|
||||
* Zeigt ein Bild in einem Scrollbereich an.
|
||||
* Es ist möglich das Bild zu zoomen und mehrere Versionen des Bildes zu speichern, um eine "Rückgängig" Operation durchzuführen.
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import java.awt.image.*;
|
||||
import java.util.Vector;
|
||||
|
||||
public class PictureViewer extends JScrollPane
|
||||
{
|
||||
|
||||
// das aktuelle Bild
|
||||
private Picture picture;
|
||||
|
||||
// Bilder für den Züruck-Modus speichern
|
||||
private static final int ANZ_BACK = 20;
|
||||
private Vector<BufferedImage> history;
|
||||
|
||||
// Zeichenfläche
|
||||
private ImageIcon scrollImageIcon;
|
||||
private JLabel imageLabel;
|
||||
|
||||
// Zoom Faktor
|
||||
private double zoomFactor;
|
||||
public static final int FIT = -1;
|
||||
public static final int NORMAL = 1;
|
||||
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der Größe 1000x1000
|
||||
*/
|
||||
public PictureViewer() {
|
||||
this(1000,1000);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public PictureViewer(int width, int height) {
|
||||
this(width,height, "D0D0D0");
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild der angegebenen Größe
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
* @param background Farbe des Hintergrunds als HEX-String (z.B. "FF3A45")
|
||||
*/
|
||||
public PictureViewer(int width, int height, String background) {
|
||||
this(new Picture(width,height, background));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel mit integriertem Bild aus einer Bilddatei
|
||||
* @param filename Name des Bildes
|
||||
*/
|
||||
public PictureViewer(String filename) {
|
||||
this(new Picture(filename));
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein ScrollPanel und zeigt das Bild-Objekt an
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public PictureViewer(Picture picture)
|
||||
{
|
||||
this.picture=picture;
|
||||
|
||||
zoomFactor=1;
|
||||
|
||||
scrollImageIcon = new ImageIcon(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
|
||||
imageLabel = new JLabel(scrollImageIcon);
|
||||
imageLabel.setVerticalAlignment(JLabel.CENTER);
|
||||
imageLabel.setHorizontalAlignment(JLabel.CENTER);
|
||||
setViewportView(imageLabel);
|
||||
|
||||
this.setBorder(BorderFactory.createLineBorder(Color.black));
|
||||
picture.setObserver(this);
|
||||
history = new Vector<BufferedImage>();
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das anzuzeigende Bild neu
|
||||
* @param picture anzuzeigendes Bild
|
||||
*/
|
||||
public void setImage(Picture picture) {
|
||||
this.history = new Vector<BufferedImage>();
|
||||
this.picture = picture;
|
||||
setZoom(NORMAL);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das übergebene Bild in der History.
|
||||
* @param b zu speicherndes Bild
|
||||
*/
|
||||
public void pushImage() {
|
||||
if( this.ANZ_BACK > 0) {
|
||||
if(history.size() == this.ANZ_BACK) {
|
||||
history.removeElementAt(0);
|
||||
}
|
||||
|
||||
BufferedImage b = new BufferedImage(picture.getWidth(), picture.getHeight(), picture.getImage().getType());
|
||||
Graphics g = b.getGraphics();
|
||||
g.drawImage(picture.getImage(), 0, 0, null);
|
||||
g.dispose();
|
||||
|
||||
history.add(b);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
private void popImage() {
|
||||
int anz = history.size();
|
||||
if(anz>0) {
|
||||
BufferedImage img = history.get(anz-1);
|
||||
history.removeElementAt(anz-1);
|
||||
picture.setImage(img);
|
||||
setZoom(zoomFactor);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
|
||||
*/
|
||||
public void back() {
|
||||
popImage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
|
||||
*/
|
||||
public void repaint() {
|
||||
if( picture != null) {
|
||||
double factor= zoomFactor;
|
||||
if (zoomFactor == FIT) {
|
||||
double factorw = ((double) getWidth()-2) / picture.getWidth();
|
||||
double factorh = ((double) getHeight()-2) / picture.getHeight();
|
||||
factor = Math.min(factorw, factorh);
|
||||
}
|
||||
int width = (int) (picture.getWidth()*factor);
|
||||
int height = (int) (picture.getHeight()*factor);
|
||||
|
||||
|
||||
|
||||
scrollImageIcon.setImage(picture.getImage().getScaledInstance(width, height, Image.SCALE_DEFAULT));
|
||||
revalidate();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Zoom-Faktor für das Bild.
|
||||
* Als Zoomfaktor sind auch die Konstanten Bildanzeiger.FIT (auf Bildschirmgröße zoomen) und Bildanzeiger.NORMAL (100%) möglich.
|
||||
* @param factor Zoomfaktor (1.0 = 100%).
|
||||
*/
|
||||
public void setZoom(double factor)
|
||||
{
|
||||
zoomFactor = factor;
|
||||
repaint();
|
||||
}
|
||||
|
||||
|
||||
// Wrappermethoden
|
||||
/**
|
||||
* Definiert die Dimension der Breite und Höhe des Anzeigefensters in Pixeleinheiten.
|
||||
* Die eingebauten Variablen Breite und Höhe werden durch die an diese Funktion übergebenen Parameter festgelegt. So weist beispielsweise
|
||||
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Höhe 480 zu.
|
||||
* @param width Breite des Bildes
|
||||
* @param height Höhe des Bildes
|
||||
*/
|
||||
public void size(int width, int height){
|
||||
picture.size(width, height);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Breite des Bildes zurück.
|
||||
* @return Breite des Bildes
|
||||
*/
|
||||
public int getImageWidth() {
|
||||
return picture.getWidth();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Höhe des Bildes zurück.
|
||||
* @return Höhe des Bildes
|
||||
*/
|
||||
public int getImageHeight() {
|
||||
return picture.getHeight();
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param c Farbe für den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void background(int c) {
|
||||
picture.background(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Die Funktion background() setzt die Farbe, die für den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
|
||||
* Es ist nicht möglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberfläche zu verwenden.
|
||||
* @param r Rotanteil (0-255) der Hintergrundfarbe
|
||||
* @param g Grünanteil (0-255) der Hintergrundfarbe
|
||||
* @param b Blauanteil (0-255) der Hintergrundfarbe
|
||||
*/
|
||||
public void background(int r, int g, int b) {
|
||||
picture.background(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Linie (einen direkten Weg zwischen zwei Punkten) auf den Bildschirm.
|
||||
* Um eine Linie einzufärben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefüllt werden, daher hat die Funktion fill() keinen
|
||||
* Einfluss auf die Farbe einer Zeile. Linien werden standardmäßig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
|
||||
* {@link #strokeWeight(double) strokeWeight()} geändert werden.
|
||||
* @param x1 x-Koordinate des 1. Punktes
|
||||
* @param y1 y-Koordinate des 1. Punktes
|
||||
* @param x2 x-Koordinate des 2. Punktes
|
||||
* @param y2 y-Koordinate des 2. Punktes
|
||||
*/
|
||||
public void line(int x1, int y1, int x2, int y2) {
|
||||
picture.line(x1,y1,x2,y2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Rechteck auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch rectMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch rectMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void rect(int a, int b, int c, int d) {
|
||||
picture.rect(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet eine Ellipse/Kreis auf das Bild.
|
||||
* Standardmäßig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Höhe.
|
||||
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geändert werden.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geändert werden).
|
||||
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
* @param d meist die Höhe des Rechtecks (kann durch ellipseMode() geändert werden).
|
||||
*
|
||||
*/
|
||||
public void ellipse(int a, int b, int c, int d) {
|
||||
picture.ellipse(a,b,c,d);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Dreieck auf das Bild.
|
||||
* Ein Dreieck ist eine Ebene, die durch die Verbindung von drei Punkten entsteht. Die ersten beiden Argumente spezifizieren den
|
||||
* ersten Punkt, die mittleren beiden Argumente spezifizieren den zweiten Punkt und die letzten beiden Argumente spezifizieren den dritten Punkt.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void triangle(int x1, int y1, int x2, int y2, int x3, int y3) {
|
||||
picture.triangle(x1,y1,x2,y2,x3,y3);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Viereck auf das Bild.
|
||||
* Ein Viereck ist ein vierseitiges Polygon. Es ist ähnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
|
||||
* sind nicht auf neunzig Grad beschränkt. Das erste Paar von Parametern (x1,y1) setzt den ersten Scheitelpunkt und die nachfolgenden
|
||||
* Paare sollten im Uhrzeigersinn oder gegen den Uhrzeigersinn um die definierte Form herum verlaufen.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x1 meist die x-Koordinate des 1. Punkts.
|
||||
* @param y1 meist die y-Koordinate des 1. Punkts.
|
||||
* @param x2 meist die x-Koordinate des 2. Punkts.
|
||||
* @param y2 meist die y-Koordinate des 2. Punkts.
|
||||
* @param x3 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y3 meist die y-Koordinate des 3. Punkts.
|
||||
* @param x4 meist die x-Koordinate des 3. Punkts.
|
||||
* @param y4 meist die y-Koordinate des 3. Punkts.
|
||||
*/
|
||||
public void quad(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
|
||||
picture.quad(x1,y1,x2,y2,x3,y3,x4,y4);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet ein Polygon auf das Bild.
|
||||
* Gleich lange Listen von x und y-Koordinaten bestimmen die Eckpunkte des Polygons.
|
||||
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Füllfarbe des Rechtecks gewählt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
|
||||
* @param x Liste der x-Koordinaten der Punkte.
|
||||
* @param y Liste der y-Koordinaten der Punkte.
|
||||
*/
|
||||
public void polygon(int[] x, int[] y) {
|
||||
picture.polygon(x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Zeichnet einen Punkt, d.h. einen Kreis in der Dimension eines Pixels.
|
||||
* Der erste Parameter ist der x-Wert für den Punkt, der zweite Wert ist der y-Wert für den Punkt.
|
||||
* @param x x-Koordinate des Punktes
|
||||
* @param y y-Koordinate des Punktes
|
||||
*/
|
||||
public void point(int x, int y) {
|
||||
picture.point(x,y);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Rechtecken.
|
||||
* Ändert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an rect() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von rect() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void rectMode(int mode) {
|
||||
picture.rectMode(mode);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Ändert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
|
||||
* Ändert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise ändert, wie Parameter, die an ellipse() übergeben werden, interpretiert werden.
|
||||
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
|
||||
* während der dritte und vierte Parameter seine Breite und Höhe sind.
|
||||
* ellipseMode(Bild.CORNER) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als Breite und Höhe der Form.
|
||||
* ellipseMode(Bild.CORNERS) interpretiert die ersten beiden Parameter von ellipse() als die Position einer Ecke
|
||||
* und die dritten und vierten Parameter als die Position der gegenüberliegenden Ecke.
|
||||
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
|
||||
* verwendet aber den dritten und vierten Parameter, um die Hälfte der Breite und Höhe der Formen festzulegen.
|
||||
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
|
||||
*/
|
||||
public void ellipseMode(int mode) {
|
||||
picture.ellipseMode(mode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param pencolor Stiftfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void stroke(String pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben
|
||||
* @param pencolor Stiftfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void stroke(int pencolor) {
|
||||
picture.stroke(pencolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Linien und Ränder um Formen gezeichnet werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
|
||||
* @param r Rotanteil (0-255) der Stiftfarbe
|
||||
* @param g Grünanteil (0-255) der Stiftfarbe
|
||||
* @param b Blauanteil (0-255) der Stiftfarbe
|
||||
*/
|
||||
public void stroke(int r, int g, int b) {
|
||||
picture.stroke(r,g,b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt fest, dass keine Linien oder Ränder um Formen gezeichnet werden soll.
|
||||
*/
|
||||
public void noStroke() {
|
||||
picture.noStroke();
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Breite des Strichs für Linien, Punkte und den Rand um Formen fest.
|
||||
* Alle Breiten werden in Pixeleinheiten angegeben.
|
||||
* @param width Breite in Pixel
|
||||
*/
|
||||
public void strokeWeight(double width) {
|
||||
picture.strokeWeight(width);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei für die roten, grünen und blauen Komponenten,
|
||||
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
|
||||
* @param fillcolor Füllfarbe in Hexadezimaldarstellung
|
||||
*/
|
||||
public void fill(String fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
|
||||
* @param fillcolor Füllfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiß, sonst: c wird als 3-Byte RGB-Wert interpretiert)
|
||||
*/
|
||||
public void fill(int fillcolor) {
|
||||
picture.fill(fillcolor);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Farbe fest, mit der Formen gefüllt werden.
|
||||
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
|
||||
* @param r Rotanteil (0-255) der Füllfarbe
|
||||
* @param g Grünanteil (0-255) der Füllfarbe
|
||||
* @param b Blauanteil (0-255) der Füllfarbe
|
||||
*/
|
||||
public void fill(int r, int g, int b) {
|
||||
picture.fill(r,g,b);
|
||||
}
|
||||
|
||||
/** Legt fest, dass die Formen nicht gefüllt werden sollen.
|
||||
*/
|
||||
public void noFill() {
|
||||
picture.noFill();
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht den Inhalt des Bildes.
|
||||
* Der Hintergrund wird mit der Hintergrundfarbe neu gefüllt.
|
||||
*/
|
||||
public void clear(){
|
||||
picture.clear();
|
||||
}
|
||||
|
||||
/**
|
||||
* Lädt ein Bild aus dem Dateisystem.
|
||||
* Lädt ein Bild von einem Datenträger und setzt Stiftfarbe und Füllfarbe auf Standardwerte zurück.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void load(String filename) {
|
||||
picture.load(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert ein Bild.
|
||||
* Speichert ein Bild auf einem Datenträger. Zulässig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
|
||||
* Standardmäßig wird die Dateiendung .png ergänzt, wenn keine angegeben ist.
|
||||
* @param filename Dateiname des Bildes
|
||||
*/
|
||||
public void save(String filename) {
|
||||
picture.save(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gibt einen Text an den gegebenen Koordinaten aus
|
||||
* Zur Ausgabe des Textes wird der ausgewählte Font verwendet. Dieser muss vorher mit {@link #textFont(Font) textFont() } festgelegt.
|
||||
* @param t Text, der angezeigt werden soll
|
||||
* @param x x-Koordinate des Textanfangs
|
||||
* @param y y-Koordinate der Grundlinie des Textes.
|
||||
*/
|
||||
public void text(String t, int x, int y) {
|
||||
picture.text(t,x,y);
|
||||
}
|
||||
|
||||
/**
|
||||
* Legt die Schriftart für Textausgaben fest.
|
||||
* Jeder übliche Java-Font kann verwendet werden. Er kann mit z.B. Font f = new Font( "Arial", Font.PLAIN, 14 ); definiert werden.
|
||||
* @param font ein Font-Objekt
|
||||
*/
|
||||
public void textFont(Font font) {
|
||||
picture.textFont(font);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das Bild als zweidimensionales Pixel-Array.
|
||||
* @return zweidimensionales Array von Color-Objekten, die den Pixeln des Bildes entsprechen.
|
||||
*/
|
||||
public Color[][] getPixelArray() {
|
||||
return picture.getPixelArray();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt das Bild neu auf Basis des Pixel-Arrays.
|
||||
* Die Größe des Bildes wird nicht automatisch an das Array angepasst.
|
||||
* @param pixel zweidimensionales Array von Color-Objekten
|
||||
*/
|
||||
public void setPixelArray(Color[][] pixel) {
|
||||
picture.setPixelArray(pixel);
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,894 @@
|
|||
/**
|
||||
* Die Klasse Table vereinfacht den Zugriff auf CSV-Dateien.
|
||||
* Die Klassen Table und TableRow ermöglichen einen einfachen Zugriff auf tabellenbasierte
|
||||
* Dokumente.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 01.02.2019
|
||||
*/
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class Table
|
||||
{
|
||||
// Standardtrennzeichen für Spalten
|
||||
private static final char DEFAULT_SEPARATOR = ';';
|
||||
// Standardmarkierung für Texte
|
||||
private static final char DEFAULT_QUOTE = '"';
|
||||
// Standardtrennzeichen für Dezimalzahlen
|
||||
private static final char DEFAULT_COMMA = ',';
|
||||
|
||||
// mögliche Spaltentypen
|
||||
private static final String UNKNOWN ="UNKOWN";
|
||||
private static final String INT = "INTEGER";
|
||||
private static final String DOUBLE = "DOUBLE";
|
||||
private static final String FLOAT = "FLOAT";
|
||||
|
||||
// interne Verwaltung des Dokuments als JDOM-Document-Objekt
|
||||
private Document doc;
|
||||
// Verweis auf Element für Kopfzeile
|
||||
private Element header;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt leeres Tabellen-Dokument.
|
||||
*/
|
||||
public Table() {
|
||||
this.doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
this.header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public Table(String filename, String options, char separator, char quote) {
|
||||
loadCSV(filename, options, separator, quote);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public Table(String filename, String options) {
|
||||
loadCSV(filename, options);
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt Tabellen-Dokument aus einer CSV-Datei.
|
||||
* Liest den Inhalt einer Datei ohne Kopfzeile und erstellt ein Tabellenobjekt mit seinen Werten (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public Table(String filename) {
|
||||
loadCSV(filename);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void loadCSV(String filename) {
|
||||
loadCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
*/
|
||||
public void loadCSV(String filename, String options) {
|
||||
loadCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liest den Inhalt einer CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthält, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile hat,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile enthält.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void loadCSV(String filename, String options, char separator, char quote) {
|
||||
doc = new Document();
|
||||
doc.setRootElement(new Element("CSV-Data"));
|
||||
header = new Element("Header");
|
||||
doc.getRootElement().addContent(header);
|
||||
try {
|
||||
File f = new File(filename);
|
||||
Scanner scanner = new Scanner(new File(filename));
|
||||
if(options.toLowerCase().contains("header") && scanner.hasNext()) {
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
for(String s : entries) {
|
||||
Element entry = new Element("Column");
|
||||
header.addContent(entry);
|
||||
entry.setText(s);
|
||||
entry.setAttribute("type", "unknown");
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
List<Element> cols = header.getChildren();
|
||||
|
||||
while (scanner.hasNext()) {
|
||||
Element line = new Element("Row");
|
||||
doc.getRootElement().addContent(line);
|
||||
List<String> entries = parseLine(scanner.nextLine(), separator, quote);
|
||||
int i= 0;
|
||||
|
||||
for(String s : entries) {
|
||||
|
||||
if(i==cols.size()) {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", "unknown");
|
||||
header.addContent(entry);
|
||||
cols = header.getChildren();
|
||||
}
|
||||
|
||||
Element entry = new Element("Entry");
|
||||
entry.setText(s);
|
||||
line.addContent(entry);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
scanner.close();
|
||||
|
||||
} catch (Exception e) {
|
||||
System.out.println("Fehler beim Lesen der CSV-Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei ohne Kopfzeile (Separator = ';', Kennung für Text = '"').
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename) {
|
||||
saveCSV(filename, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei (Separator = ';', Kennung für Text = '"').
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
*/
|
||||
public void saveCSV(String filename, String options) {
|
||||
saveCSV(filename, options, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/**
|
||||
* Speichert das aktuelle Dokument als CSV-Datei.
|
||||
* Wenn die Datei eine Kopfzeile enthalten, fügen Sie "header" in den Parameter options ein. Wenn die Datei keine Kopfzeile haben soll,
|
||||
* dann lassen Sie einfach die Option "header" weg.
|
||||
* @param options Geben Sie hier "header" an, wenn die Datei eine Kopfzeile haben soll.
|
||||
* @param filename Dateiname der CSV-Datei.
|
||||
* @param separator Trennzeichen für Spalten (meist ';' oder ',' oder '\t' für Tab)
|
||||
* @param quote Kennung für Texte (meist '"').
|
||||
*/
|
||||
public void saveCSV(String filename, String options, char separator, char quote){
|
||||
try{
|
||||
File f = new File(filename);
|
||||
PrintStream outputFile = new PrintStream (f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath());
|
||||
List<Element> columns = header.getChildren();
|
||||
String sq = ""+quote;
|
||||
String ss = ""+separator;
|
||||
if(quote =='"') sq = "\"";
|
||||
if(separator =='"') ss = "\"";
|
||||
|
||||
if(options.toLowerCase().contains("header")) {
|
||||
String h = "";
|
||||
for(Element c : columns) {
|
||||
h += ss + sq + c.getText()+sq;
|
||||
}
|
||||
outputFile.println(h.substring(1));
|
||||
}
|
||||
for(int i = 0; i<getRowCount(); i++) {
|
||||
String l = "";
|
||||
for(String s: getStringRow(i)) {
|
||||
|
||||
if(s.contains(""+separator)) {
|
||||
if(quote == '"' && s.contains("\"")) {
|
||||
s = s.replace("\"","\"\"");
|
||||
}
|
||||
l += ss + sq + s+sq;
|
||||
} else {
|
||||
l += ss+s;
|
||||
}
|
||||
|
||||
}
|
||||
outputFile.println(l.substring(1));
|
||||
}
|
||||
outputFile.close();
|
||||
}
|
||||
catch(Exception e) {
|
||||
System.out.println("Fehler beim Schreiben der Datei");
|
||||
}
|
||||
}
|
||||
|
||||
/** Speichert die Tabelle als XML-Dokument.
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine) {
|
||||
return parseLine(cvsLine, DEFAULT_SEPARATOR, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator) {
|
||||
return parseLine(cvsLine, separator, DEFAULT_QUOTE);
|
||||
}
|
||||
|
||||
/** HIlfsfunktion für die Analyse einer Dateizeile
|
||||
* @param cvsLine Zeile aus der Datei
|
||||
* @param sparator Trennzeichen für die Spalten
|
||||
* @param customQuote Kennung für Strings
|
||||
* @return Liste von String für die einzelnen Spalten
|
||||
*/
|
||||
private List<String> parseLine(String cvsLine, char separator, char customQuote) {
|
||||
|
||||
List<String> result = new ArrayList<>();
|
||||
|
||||
//if empty, return!
|
||||
if (cvsLine == null && cvsLine.isEmpty()) {
|
||||
return result;
|
||||
}
|
||||
|
||||
//ggf. Default-Value laden
|
||||
if (customQuote == ' ') {
|
||||
customQuote = DEFAULT_QUOTE;
|
||||
}
|
||||
|
||||
if (separator == ' ') {
|
||||
separator = DEFAULT_SEPARATOR;
|
||||
}
|
||||
|
||||
StringBuffer curVal = new StringBuffer();
|
||||
boolean inQuotes = false;
|
||||
boolean startCollectChar = false;
|
||||
boolean doubleQuotesInColumn = false;
|
||||
|
||||
char[] chars = cvsLine.toCharArray();
|
||||
|
||||
for (char ch : chars) {
|
||||
|
||||
if (inQuotes) { // aktueller Text ist in Quotes eingeschlossen
|
||||
startCollectChar = true;
|
||||
|
||||
if (ch == customQuote) { // Quotes werden beendet, aber Achtung bei "" => Metazeichen
|
||||
inQuotes = false;
|
||||
if (ch == '\"') {
|
||||
doubleQuotesInColumn = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
if (ch == '\"' && !doubleQuotesInColumn) {
|
||||
doubleQuotesInColumn = true;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
doubleQuotesInColumn = false;
|
||||
}
|
||||
|
||||
}
|
||||
} else {
|
||||
if (ch == customQuote) {
|
||||
|
||||
inQuotes = true;
|
||||
|
||||
//Fixed : allow "" in empty quote enclosed
|
||||
if (ch == '\"'){
|
||||
if(doubleQuotesInColumn) {
|
||||
curVal.append('"');
|
||||
doubleQuotesInColumn = false;
|
||||
} else doubleQuotesInColumn = true;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
doubleQuotesInColumn = false;
|
||||
if (ch == separator) {
|
||||
|
||||
result.add(curVal.toString());
|
||||
|
||||
curVal = new StringBuffer();
|
||||
startCollectChar = false;
|
||||
|
||||
} else if (ch == '\r') {
|
||||
//ignore LF characters
|
||||
continue;
|
||||
} else if (ch == '\n') {
|
||||
//the end, break!
|
||||
break;
|
||||
} else {
|
||||
curVal.append(ch);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
result.add(curVal.toString());
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht die Nummer einer durch Namen gegebenen Spalte.
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
|
||||
private int findColumnNumber(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c : columns) {
|
||||
if (c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an.
|
||||
*/
|
||||
public void addColumn() {
|
||||
Element entry = new Element("Column");
|
||||
entry.setAttribute("type", Table.UNKNOWN);
|
||||
header.addContent(entry);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
*/
|
||||
public void addColumn(String title) {
|
||||
addColumn();
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setText(title);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Spalte am Ende der Tabelle an und benennt und typisiert sie.
|
||||
* @param title Bezeichnung der Spalte
|
||||
* @param type Typ der Spalte (UNKNOWN, DOUBLE, INTEGER, FLOAT)
|
||||
*/
|
||||
public void addColumn(String title, String type) {
|
||||
addColumn(title);
|
||||
Element nc = ((List<Element>)(header.getChildren())).get(header.getChildren().size()-1);
|
||||
nc.setAttribute("type", type);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte.
|
||||
* @param i Nummer der Spalte.
|
||||
*/
|
||||
public void removeColumn(int i) {
|
||||
List<Element> lines = doc.getRootElement().getChildren();
|
||||
for(Element l : lines) {
|
||||
if(l.getChildren().size()>i) l.removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Spalte
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
public void removeColumn(String name) {
|
||||
try{
|
||||
removeColumn(findColumnNumber(name));
|
||||
} catch(Exception e) { System.out.println("Unbekannter Spaltenname");}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten in der Tabelle
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Zeilen in der Tabelle
|
||||
* @return Anzahl der Zeilen
|
||||
*/
|
||||
public int getRowCount() {
|
||||
return doc.getRootElement().getChildren().size()-1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht alle Zeilen der Tabelle.
|
||||
* Die Spaltenüberschriften und Typen bleiben erhalten.
|
||||
*/
|
||||
public void clearRows() {
|
||||
doc.getRootElement().removeChildren("Row");
|
||||
}
|
||||
|
||||
/**
|
||||
* Fügt eine neue Zeile an das Ende der Tabelle an.
|
||||
* @return ein TableRow-Objekt für diese neue Zeile
|
||||
*/
|
||||
public TableRow addRow() {
|
||||
Element row = new Element("Row");
|
||||
doc.getRootElement().addContent(row);
|
||||
return new TableRow(doc, row);
|
||||
}
|
||||
|
||||
/**
|
||||
* Löscht eine Zeile
|
||||
* @param i Nummer der Zeile
|
||||
*/
|
||||
public void removeRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
doc.getRootElement().removeContent(i);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert eine Zeile der Tabelle
|
||||
* @param i Nummer der Zeile
|
||||
* @return TableRow-Objekt für diese Zeile
|
||||
*/
|
||||
public TableRow getRow(int i) {
|
||||
if(i<getRowCount()) {
|
||||
List<Element> rows = doc.getRootElement().getChildren();
|
||||
return new TableRow(doc, rows.get(i+1));
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die ganze Tabelle als Array von TableRow-Objekten
|
||||
* @return Array von TableRow-Objekten
|
||||
*/
|
||||
public TableRow[] rows() {
|
||||
TableRow[] rows = new TableRow[getRowCount()];
|
||||
for(int i = 0; i < getRowCount(); i++) {
|
||||
rows[i] = getRow(i);
|
||||
}
|
||||
return rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, int column) {
|
||||
return getRow(row).getInt(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int row, String name) {
|
||||
return getRow(row).getInt(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, int column,int value) {
|
||||
getRow(row).setInt(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Integer-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int row, String name, int value) {
|
||||
getRow(row).setInt(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Integer-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public int[] getIntRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getInt(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
int[] r = new int[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getInt(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Integer-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public int[] getIntColumn(String name) {
|
||||
return getIntColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, int column) {
|
||||
return getRow(row).getFloat(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int row, String name) {
|
||||
return getRow(row).getFloat(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, int column,float value) {
|
||||
getRow(row).setFloat(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int row, String name, float value) {
|
||||
getRow(row).setFloat(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Zeile als Float-Array.
|
||||
* @param row Nummer der Zeile
|
||||
* @return int-Array, dass alle Werte der Zeile enthält
|
||||
*/
|
||||
public float[] getFloatRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getFloat(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
float[] r = new float[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getFloat(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Float-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public float[] getFloatColumn(String name) {
|
||||
return getFloatColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, int column) {
|
||||
return getRow(row).getDouble(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int row, String name) {
|
||||
return getRow(row).getDouble(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, int column,double value) {
|
||||
getRow(row).setDouble(column, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int row, String name, double value) {
|
||||
getRow(row).setDouble(name, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getDouble(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
double[] r = new double[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getDouble(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als Double-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public double[] getDoubleColumn(String name) {
|
||||
return getDoubleColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, int column) {
|
||||
return getRow(row).getString(column);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int row, String name) {
|
||||
return getRow(row).getString(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param column Spaltennummer
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, int column,String text) {
|
||||
getRow(row).setString(column, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param row Zeilennummer
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int row, String name, String text) {
|
||||
getRow(row).setString(name, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param row Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringRow(int row) {
|
||||
try{
|
||||
TableRow trow = getRow(row);
|
||||
int anz = getColumnCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = trow.getString(i);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param column Nummer der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(int column) {
|
||||
try{
|
||||
int anz = getRowCount();
|
||||
String[] r = new String[anz];
|
||||
for(int i=0; i<anz; i++) {
|
||||
r[i] = getString(i, column);
|
||||
}
|
||||
return r;
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Werte einer Spalte als String-Array.
|
||||
* @param name Name der Spalte
|
||||
* @return int-Array, dass alle Werte der Spalte enthält
|
||||
*/
|
||||
public String[] getStringColumn(String name) {
|
||||
return getStringColumn(findColumnNumber(name));
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param column Nummer der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, int column) {
|
||||
for(int i=0; i<getRowCount(); i++) {
|
||||
if(getString(i,column).equals(value)){
|
||||
return getRow(i);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sucht nach einem bestimmtem Wert in einer Zeile.
|
||||
* @param value Wert der gesucht werden soll
|
||||
* @param name Name der Spalte, die durchsucht werden soll
|
||||
* @return TableRow-Objekt der Zeile, wenn der Wert gefunden wurde, sonst null
|
||||
*/
|
||||
public TableRow findRow(String value, String name) {
|
||||
return findRow(value, findColumnNumber(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Kürzt alle Einträge der Tabelle um unnötige Leerzeichen am Anfang oder Ende
|
||||
*/
|
||||
public void trim() {
|
||||
for(int y=0; y<getRowCount(); y++) {
|
||||
for (int x =0; x<getColumnCount(); x++) {
|
||||
setString(y,x,getString(y,x).trim());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,312 @@
|
|||
/**
|
||||
* Repräsentiert eine Zeile eines Table-Objekts.
|
||||
* Erlaubt einen einfachen Zugriff auf die einzelnen Einträge in dieser Zeile.
|
||||
*
|
||||
* @author Thomas Schaller
|
||||
* @version V1.0 vom 01.02.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
import java.util.Scanner;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
public class TableRow
|
||||
{
|
||||
// Verweis auf das ganze Dokument
|
||||
private Document doc;
|
||||
// Verweis auf die Zeile, für die dieses Objekt steht
|
||||
private Element current;
|
||||
// Verweis auf die Kopfzeile
|
||||
private Element header;
|
||||
// Für die Interpretation von Zahlenwerten
|
||||
NumberFormat format = NumberFormat.getInstance();
|
||||
|
||||
// Ende Attribute
|
||||
/**
|
||||
* Erzeugt ein TableRow-Objekt.
|
||||
* Diese Methode ist für den internen Gebraucht. Einige Methode der Table-Klasse erzeugen mit diesem Konstruktor TableRow-Objekte.
|
||||
* @param doc JDOM-Dokument, das für die ganze Tabelle steht.
|
||||
* @param row JDOM-Element, das für die aktuelle Zeile steht.
|
||||
*/
|
||||
public TableRow(Document doc, Element row) {
|
||||
this.doc = doc;
|
||||
this.current = row;
|
||||
this.header = doc.getRootElement().getChild("Header");
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Anzahl der Spalten der Zeile.
|
||||
* @return Anzahl der Spalten
|
||||
*/
|
||||
public int getColumnCount() {
|
||||
return header.getChildren().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Titel einer Spalte
|
||||
* @param i Nummer der Spalte
|
||||
* @return Name der Spalte
|
||||
*/
|
||||
public String getColumnTitle(int i) {
|
||||
if(i< getColumnCount()) {
|
||||
return ((List<Element>) (header.getChildren())).get(i).getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert die Nummer einer Spalte
|
||||
* @param name Name der Spalte
|
||||
* @return Nummer der Spalte
|
||||
*/
|
||||
public int getColumn(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
while (i < columns.size()) {
|
||||
if (columns.get(i).getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return i;
|
||||
}
|
||||
i++;
|
||||
} // end of while
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile mit i Spalten
|
||||
* Wenn bisher nicht genügend Spalten vorhanden sind, werden automatisch neue Spalten hinzugefügt (auch zum Header)
|
||||
* @param i Anzahl der Spalten
|
||||
*/
|
||||
private Element buildRow(int i) {
|
||||
List<Element> columns = header.getChildren();
|
||||
Element entry=null;
|
||||
for(int j=0; j<=i; j++) {
|
||||
|
||||
if(j==columns.size()) {
|
||||
Element h = new Element("Column");
|
||||
h.setAttribute("type", "unknown");
|
||||
header.addContent(h);
|
||||
columns = header.getChildren();
|
||||
}
|
||||
if(j==current.getChildren().size()) {
|
||||
entry = new Element("Entry");
|
||||
current.addContent(entry);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return entry;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt eine neue Zeile.
|
||||
* Es werden genügend Spalten erzeugt, dass ein Wert in Spalte "name" eingetragen werden kann
|
||||
* @param name Name der Spalte
|
||||
*/
|
||||
private Element buildRow(String name) {
|
||||
List<Element> columns = header.getChildren();
|
||||
int i = 0;
|
||||
for(Element c: columns) {
|
||||
|
||||
if(c.getText().toLowerCase().equals(name.toLowerCase())) {
|
||||
return buildRow(i);
|
||||
}
|
||||
i++;
|
||||
}
|
||||
return null;
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(int i) {
|
||||
if(i >= current.getContent().size()) return "";
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
if(e!=null) {
|
||||
return e.getText();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public String getString(String name) {
|
||||
return getString(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param i Nummer der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(int i, String text) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als String
|
||||
* @param name Name der Spalte
|
||||
* @param text neuer Wert der Zelle
|
||||
*/
|
||||
public void setString(String name, String text) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Integer.parseInt(e.getText());
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public int getInt(String name) {
|
||||
return getInt(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(int i,int value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Int-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setInt(String name, int value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Float.parseFloat(e.getText().replace(",","."));
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public float getFloat(String name) {
|
||||
return getFloat(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(int i,float value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Float-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setFloat(String name, float value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(int i) {
|
||||
try{
|
||||
Element e = (Element) current.getContent(i) ;
|
||||
return Double.parseDouble(e.getText().replace(",","."));
|
||||
|
||||
} catch(Exception e) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @return Wert der Zelle
|
||||
*/
|
||||
public double getDouble(String name) {
|
||||
return getDouble(getColumn(name));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param i Nummer der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(int i,double value) {
|
||||
|
||||
Element e = buildRow(i);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Wert einer Zelle als Double-Zahl
|
||||
* @param name Name der Spalte
|
||||
* @param value neuer Wert der Zelle
|
||||
*/
|
||||
public void setDouble(String name, double value) {
|
||||
Element e = buildRow(name);
|
||||
if(e!=null) e.setText(format.format(value));
|
||||
}
|
||||
|
||||
}
|
||||
637
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a2/XML.java
Normal file
637
04_loesungen/03_javaeditor/alg15_xydiagramm_loesung_a2/XML.java
Normal file
|
|
@ -0,0 +1,637 @@
|
|||
/**
|
||||
* Klasse zum Vereinfachten Zugriff auf XML-Dokumente
|
||||
* Diese Klasse ist für den Einsatz in der Schule gedacht und soll den Schülern
|
||||
* einen einfachen Zugriff auf XML-Dokumente ermöglichen. Die zur Verfügung
|
||||
* stehenden Befehle sind wie in Processing realisiert.
|
||||
* Dabei ist jeder Teilbaum des Dokuments wieder als XML-Objekt zugreifbar, das
|
||||
* intern auf die gleiche XML-Dokumentstruktur zugreift.
|
||||
* Dies ermöglicht bei unsachgemäßem Gebrauch die XML-Struktur zu zerstören. Im
|
||||
* normalen Gebrauch sollte dies aber nicht relevant sein.
|
||||
*
|
||||
* Benötigt: jdom-1.1.3.jar
|
||||
|
||||
* @author Thomas Schaller
|
||||
* @version 1.0 vom 31.01.2019
|
||||
*/
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.io.*;
|
||||
|
||||
import org.jdom.Document;
|
||||
import org.jdom.Element;
|
||||
import org.jdom.Attribute;
|
||||
import org.jdom.JDOMException;
|
||||
import org.jdom.input.SAXBuilder;
|
||||
import org.jdom.output.XMLOutputter;
|
||||
import org.jdom.output.Format;
|
||||
|
||||
public class XML {
|
||||
// Anfang Attribute
|
||||
// XML-Dokumentstruktur
|
||||
private Document doc;
|
||||
// Zeiger auf das aktuelle Element
|
||||
private Element current;
|
||||
// Ende Attribute
|
||||
|
||||
/**
|
||||
* Erzeugt ein leeres XMLDokument
|
||||
*/
|
||||
public XML() {
|
||||
this.doc = new Document();
|
||||
this.current = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Erzeugt ein XML-Dokument aus einer Datei
|
||||
* @param filename Dateiname der XML-Datei
|
||||
*/
|
||||
public XML(String filename) {
|
||||
loadXML(filename);
|
||||
}
|
||||
|
||||
/**
|
||||
* interner Konstruktor, um ein XML Objekt zu erzeugen, das auf einen bestimmten Knoten verweist
|
||||
* @param doc die XML-Dokumentstruktur
|
||||
* @param current Zeiger auf das aktuelle Element
|
||||
*/
|
||||
private XML(Document doc, Element current) {
|
||||
this.doc = doc;
|
||||
this.current = current;
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
/** Öffnet das durch den Dateinamen gegebene Dokument
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void loadXML(String filename) {
|
||||
doc = null;
|
||||
File f = new File(filename);
|
||||
|
||||
try {
|
||||
// Das Dokument erstellen
|
||||
SAXBuilder builder = new SAXBuilder();
|
||||
doc = builder.build(f);
|
||||
|
||||
} catch (JDOMException e) {
|
||||
e.printStackTrace();
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
// Zeiger im Baum auf Root-Element
|
||||
current = doc.getRootElement();
|
||||
}
|
||||
|
||||
/** Speichert den XML-Baum im angegebenen Dateinamen
|
||||
* @param filename Dateiname des XML-Files
|
||||
*/
|
||||
public void saveXML(String filename) {
|
||||
try {
|
||||
// new XMLOutputter().output(doc, System.out);
|
||||
XMLOutputter xmlOutput = new XMLOutputter();
|
||||
|
||||
// display nice nice
|
||||
xmlOutput.setFormat(Format.getPrettyFormat());
|
||||
File f = new File(filename);
|
||||
FileOutputStream outputFile = new FileOutputStream(f);
|
||||
System.out.println("Speicher in : "+f.getAbsolutePath() );
|
||||
xmlOutput.output(doc, outputFile);
|
||||
outputFile.close();
|
||||
System.out.println("File Saved!");
|
||||
} catch (IOException io) {
|
||||
System.out.println(io.getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//----------------------------------------------- Zeigerbewegungen --------------------------------------------------
|
||||
/**
|
||||
* liefert ein XML-Objekt, das auf den Vaterknoten des aktuellen Elements zeigt.
|
||||
* @return Vater des aktuellen Objekts.
|
||||
*/
|
||||
public XML getParent() {
|
||||
if(current != null) {
|
||||
Element parent = current.getParentElement();
|
||||
if (parent == null) {
|
||||
return null;
|
||||
} else {
|
||||
return new XML(doc, parent);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Überprüft, ob das Element irgendwelche Kinder hat oder nicht, und gibt das Ergebnis als boolean zurück.
|
||||
* @return true, wenn Kinder vorhanden sind, sonst false
|
||||
*/
|
||||
public boolean hasChildren() {
|
||||
if (current == null) {
|
||||
return doc.hasRootElement();
|
||||
} else {
|
||||
return current.getChildren().size()>0;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ermittelt die Namen aller Kinder des Elements und gibt die Namen als ein Array von Strings zurück.
|
||||
* Dies ist dasselbe wie das Durchlaufen und Aufrufen von getName() auf jedem untergeordneten Element einzeln.
|
||||
* @return Liste aller Namen der Kinder
|
||||
*/
|
||||
public String[] listChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
String[] names = new String[0];
|
||||
names[0] = doc.getRootElement().getName();
|
||||
return names;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
String[] names = new String[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
names[i] = ch_element.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert alle Kinder des Elements als Array von XML-Objekten.
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren() {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert bestimmte Kinder des Elements als Array von XML-Objekten.
|
||||
* Die Methode gibt dabei alle Kinder zurück, die dem angegebenen Namen entsprechen.
|
||||
* @param name Name der gesuchten Kind-Objekte
|
||||
* @return Array der Kinder als XML-Objekte
|
||||
*/
|
||||
public XML[] getChildren(String name) {
|
||||
if (current == null) {
|
||||
if(doc.hasRootElement()) {
|
||||
XML[] ch_xml = new XML[1];
|
||||
ch_xml[0] = new XML(doc, doc.getRootElement());
|
||||
if(doc.getRootElement().getName().equals(name)){
|
||||
return ch_xml;
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren(name);
|
||||
XML[] ch_xml = new XML[ch_element.size()];
|
||||
for(int i=0; i < ch_element.size() ; i++) {
|
||||
ch_xml[i] = new XML(doc, ch_element.get(i));
|
||||
}
|
||||
return ch_xml;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das erste Kind des Elements mit einem bestimmten Namen.
|
||||
* Die Methode gibt das erste Kind zurück, das dem angegebenen Namen entsprechen.
|
||||
* @param name Name des gesuchten Kind-Objektes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
|
||||
public XML getChild(String name) {
|
||||
if (current == null) {
|
||||
Element e = doc.getRootElement();
|
||||
if (e.getName().equals(name)) {
|
||||
return new XML(doc, e);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
} else {
|
||||
String[] names = name.split("/");
|
||||
Element e = current;
|
||||
int i = 0;
|
||||
while(i < names.length) {
|
||||
e = e.getChild(names[i]);
|
||||
if (e==null) return null;
|
||||
i++;
|
||||
}
|
||||
return new XML(doc, e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Liefert das i. Kind des Elements.
|
||||
* Die Methode gibt das i. Kind des aktuellen Elements zurück.
|
||||
* @param i Nummer des Kindes
|
||||
* @return Kind als XML-Objekt
|
||||
*/
|
||||
public XML getChild(int i) {
|
||||
if (current == null) {
|
||||
return new XML(doc, doc.getRootElement());
|
||||
} else {
|
||||
List<Element> ch_element = current.getChildren();
|
||||
if (i>=ch_element.size()) return null;
|
||||
return new XML(doc, ch_element.get(i));
|
||||
}
|
||||
}
|
||||
|
||||
//--------------------------------------------------- Methoden für das aktuelle Element -------------------------------------------------
|
||||
/**
|
||||
* Frage den Namen des aktuellen Elements ab
|
||||
* @return Namen des Elements
|
||||
*/
|
||||
public String getName() {
|
||||
if (current==null) return "";
|
||||
return current.getName();
|
||||
}
|
||||
|
||||
/**
|
||||
* Setze den Namen des aktuellen Elements.
|
||||
* @param name Neuer Name des Elements
|
||||
*/
|
||||
public void setName(String name) {
|
||||
if (current==null) return;
|
||||
current.setName(name);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert die Anzahl der Attribute eines Elements.
|
||||
* @return Anzahl des Attribute
|
||||
*/
|
||||
public int getAttributeCount() {
|
||||
if (current == null) return 0;
|
||||
return current.getAttributes().size();
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert zurück, ob das aktuelle Element Attribute hat .
|
||||
* @return true, wenn es Attribute gibt
|
||||
*/
|
||||
public boolean hasAttribute() {
|
||||
if (current == null) return false;
|
||||
return current.getAttributes().size()>0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Ruft alle Attribute des angegebenen Elements ab und gibt sie als Array von Strings zurück.
|
||||
* @return Liste der Attributnamen
|
||||
*/
|
||||
public String[] listAttributes() {
|
||||
if (current == null) return null;
|
||||
List<Attribute> attr = current.getAttributes();
|
||||
String[] names = new String[attr.size()];
|
||||
for(int i=0; i < attr.size() ; i++) {
|
||||
names[i] = attr.get(i).getName();
|
||||
}
|
||||
return names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute) {
|
||||
if (current==null) return "";
|
||||
return current.getAttributeValue(attribute);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs
|
||||
*/
|
||||
public String getString(String attribute, String defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
return current.getAttributeValue(attribute,defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param text neuer Wert des Attributs
|
||||
*/
|
||||
public void setString(String attribute, String text) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, text);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Integer-Zahl
|
||||
*/
|
||||
public int getInt(String attribute, int defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setInt(String attribute, int value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als Float-Zahl
|
||||
*/
|
||||
public float getFloat(String attribute, float defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setFloat(String attribute, float value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* @param attribute Name des Attributs
|
||||
* @return Wert des Attributs als Double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute) {
|
||||
if (current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt einen Attributwert des aktuellen Elements ab
|
||||
* Sollte es das Attribut nicht geben, wird ein default-Wert zurückgegeben
|
||||
* @param attribute Name des Attributs
|
||||
* @param defaultValue Standardwert, falls es das Attribut nicht gibt
|
||||
* @return Wert des Attributs als double-Zahl
|
||||
*/
|
||||
public double getDouble(String attribute, double defaultValue) {
|
||||
if (current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getAttributeValue(attribute));
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt einen Attributwert des aktuellen Elements
|
||||
* @param attribute Name des Attributs
|
||||
* @param value neuer Wert des Attributs
|
||||
*/
|
||||
public void setDouble(String attribute, double value) {
|
||||
if (current==null) return;
|
||||
current.setAttribute(attribute, ""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent() {
|
||||
if ( current==null) return "";
|
||||
|
||||
return current.getText();
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt/Text des aktuellen Elements ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardtext
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public String getContent(String defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
String t = current.getText();
|
||||
if(t.equals("")) t = defaultValue;
|
||||
return t;
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt/Text des aktuellen Elements
|
||||
* @param text Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setContent(String text) {
|
||||
if ( current==null) return;
|
||||
current.setText(text);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/ public int getIntContent(int defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Integerzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public int getIntContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
int i = Integer.parseInt(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setIntContent(int value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent(float defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Floatzahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public float getFloatContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
float i = Float.parseFloat(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setFloatContent(float value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* Hat das Element keinen Inhalt wird der defaultValue zurückgegeben.
|
||||
* @param defaultValue Standardwert
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent(double defaultValue) {
|
||||
if ( current==null) return defaultValue;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return defaultValue; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Fragt den Inhalt des aktuellen Elements als Doublezahl ab
|
||||
* @return Inhalt des Elements
|
||||
*/
|
||||
public double getDoubleContent() {
|
||||
if ( current==null) return 0;
|
||||
try{
|
||||
double i = Double.parseDouble(current.getText());
|
||||
return i;
|
||||
} catch(Exception e) { return 0; }
|
||||
}
|
||||
|
||||
/**
|
||||
* Setzt den Inhalt des aktuellen Elements
|
||||
* @param value Neuer Inhalt des Elements
|
||||
*/
|
||||
public void setDoubleContent(double value) {
|
||||
if ( current==null) return;
|
||||
current.setText(""+value);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------- XML-Struktur aufbauen ------------------------------------------------
|
||||
/** Erzeuge neues Element nach der aktuellen Position und setze dieses als aktuelles Element
|
||||
* @param name Name des neuen Elements
|
||||
* @return neues Element als XML-Objekt
|
||||
*/
|
||||
public XML addChild(String name) {
|
||||
Element e = new Element(name);
|
||||
if(current == null){ // man ist auf Root-Ebene
|
||||
doc.setRootElement(e);
|
||||
|
||||
}
|
||||
else {
|
||||
current.addContent(e);
|
||||
} // end of if-else
|
||||
return new XML(doc, e);
|
||||
}
|
||||
|
||||
/**
|
||||
* liefert das aktuelle Element als jdom-Element-Objekt
|
||||
* @return aktuelles Element
|
||||
*/
|
||||
private Element getCurrent() {
|
||||
return current;
|
||||
}
|
||||
|
||||
/**
|
||||
* löscht ein Kind des aktuellen Knotens.
|
||||
* Ist kid kein Kind des aktuellen Elements passiert gar nichts.
|
||||
* @param kid XML-Objekt des Kindes
|
||||
*/
|
||||
public void removeChild(XML kid) {
|
||||
if (current == null) return;
|
||||
Element e = kid.getCurrent();
|
||||
int index = current.indexOf(e);
|
||||
if(index >= 0) { current.removeContent(e);}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
import java.awt.Font;
|
||||
|
||||
/**
|
||||
* XY-Diagramm für Schalldruckpegel, Zahlen werden aus CSV-Datei gelesen.
|
||||
*
|
||||
* @author Schaller
|
||||
* @version 29.11.18
|
||||
*/
|
||||
|
||||
public class XYDiagramm extends Picture
|
||||
|
||||
{
|
||||
// Liste mit allen Werten
|
||||
double[] x_werte;
|
||||
double[] y_werte;
|
||||
|
||||
// Hilfsvariablen für die Suche
|
||||
int akt_maximum=-1; // aktuell groesstes Element
|
||||
int akt=-1; // aktuell untersuchtes Element
|
||||
int verzoegerung=0; // Geschwindigkeit der Ausführung
|
||||
|
||||
// Schriften
|
||||
Font kleineSchrift;
|
||||
Font grosseSchrift;
|
||||
|
||||
public XYDiagramm() {
|
||||
size(1000, 700);
|
||||
background(0);
|
||||
kleineSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 12 );
|
||||
grosseSchrift = new Font( Font.SANS_SERIF, Font.PLAIN, 20 );
|
||||
|
||||
// CSV-Datei laden und anzeigen
|
||||
ladeTabelle("Amplitudes.csv");
|
||||
stroke(250,250,200);
|
||||
zeichneXYDiagramm();
|
||||
}
|
||||
|
||||
|
||||
|
||||
public void ladeTabelle(String name) {
|
||||
// Tabelle aus CSV-Datei laden
|
||||
Table csv = new Table(name, "header",',','"');
|
||||
|
||||
if (csv != null && csv.getColumnCount()==2) {
|
||||
|
||||
// Initialisiere Arrays, in die alle Zeilen der Tabelle passen
|
||||
x_werte = new double[csv.getRowCount()];
|
||||
y_werte = new double[csv.getRowCount()];
|
||||
|
||||
// Fülle die Arrays mit Werten aus der Tabelle
|
||||
for (int i = 0; i < x_werte.length; i++) { //x_werte.length; i++) {
|
||||
// Lies Wert aus der i. Zeile und der Spalte "Punkte" bzw. "Name"
|
||||
x_werte[i] = csv.getDouble(i, "Zeit");
|
||||
y_werte[i] = csv.getDouble(i, "Laerm");
|
||||
System.out.println("Lade Zeile: "+i);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void zeichneXYDiagramm() {
|
||||
|
||||
// Überschrift
|
||||
fill(255,255,255);
|
||||
textFont(grosseSchrift);
|
||||
text("Lärmpegel", 2, 20);
|
||||
textFont(kleineSchrift);
|
||||
|
||||
// Alle Einträge darstellen
|
||||
if (x_werte != null) {
|
||||
for (int i = 0; i< x_werte.length; i++) {
|
||||
|
||||
fill(20,25,165);
|
||||
|
||||
// XY-Punktdiagramm zeichnen
|
||||
int x = (int) x_werte[i];
|
||||
int y = (int) y_werte[i];
|
||||
point(x,y);
|
||||
System.out.println("Zeichne Punkt: "+i);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
public int sucheMaximum(double[] zahlen) {
|
||||
// Sind überhaupt Daten da?
|
||||
if (zahlen.length==0 ) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Startwerte setzen
|
||||
akt_maximum = 0;
|
||||
akt = 1;
|
||||
|
||||
// Alle Arrayelemente untersuchen
|
||||
while (akt < zahlen.length) {
|
||||
|
||||
// Neues größtes Element??
|
||||
if (zahlen[akt]> zahlen[akt_maximum]) {
|
||||
// Dann merke dir das neue
|
||||
akt_maximum = akt;
|
||||
|
||||
}
|
||||
akt = akt + 1;
|
||||
}
|
||||
// Gib Position des größten Elements zurück
|
||||
return akt_maximum;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,83 @@
|
|||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import javax.swing.*;
|
||||
import javax.swing.event.*;
|
||||
|
||||
/**
|
||||
*
|
||||
* description
|
||||
*
|
||||
* @version 1.0 from 06.10.2018
|
||||
* @author
|
||||
*/
|
||||
|
||||
|
||||
public class XYDiagrammGUI extends JFrame {
|
||||
// Anfang Attribute
|
||||
private JButton bXYDiagrammzeichnen = new JButton();
|
||||
private PictureViewer imagePanel1 = new PictureViewer();
|
||||
|
||||
private XYDiagramm bild;
|
||||
private Picture b;
|
||||
// Ende Attribute
|
||||
|
||||
public XYDiagrammGUI (String title) {
|
||||
super (title);
|
||||
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
|
||||
int frameWidth = 768;
|
||||
int frameHeight = 551;
|
||||
setSize(frameWidth, frameHeight);
|
||||
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
|
||||
int x = (d.width - getSize().width) / 2;
|
||||
int y = (d.height - getSize().height) / 2;
|
||||
setLocation(x, y);
|
||||
Container cp = getContentPane();
|
||||
cp.setLayout(null);
|
||||
// Anfang Komponenten
|
||||
bXYDiagrammzeichnen.setBounds(280, 456, 209, 33);
|
||||
bXYDiagrammzeichnen.setText("XY-Diagramm zeichnen");
|
||||
bXYDiagrammzeichnen.setMargin(new Insets(2, 2, 2, 2));
|
||||
bXYDiagrammzeichnen.addActionListener(new ActionListener() {
|
||||
public void actionPerformed(ActionEvent evt) {
|
||||
bXYDiagrammzeichnen_ActionPerformed(evt);
|
||||
}
|
||||
});
|
||||
cp.add(bXYDiagrammzeichnen);
|
||||
imagePanel1.setBounds(24, 16, 705, 409);
|
||||
cp.add(imagePanel1);
|
||||
|
||||
b = new Picture(700,800);
|
||||
imagePanel1.setImage(b);
|
||||
b.setObserver(imagePanel1);
|
||||
addWindowListener(new WindowAdapter() {
|
||||
public void windowClosed(WindowEvent evt) {
|
||||
BalkendiagrammGUI_WindowClosed(evt);
|
||||
}
|
||||
});
|
||||
// Ende Komponenten
|
||||
setResizable(false);
|
||||
setVisible(true);
|
||||
}
|
||||
|
||||
// Anfang Methoden
|
||||
public void bXYDiagrammzeichnen_ActionPerformed(ActionEvent evt) {
|
||||
bild = new XYDiagramm();
|
||||
imagePanel1.setImage(bild);
|
||||
bild.setObserver(imagePanel1);
|
||||
imagePanel1.getVerticalScrollBar().setValue(10);
|
||||
imagePanel1.getVerticalScrollBar().setValue(0);
|
||||
imagePanel1.getViewport().repaint();
|
||||
} // end of bXYDiagrammzeichnen_ActionPerformed
|
||||
|
||||
public void BalkendiagrammGUI_WindowClosed(WindowEvent evt) {
|
||||
|
||||
|
||||
} // end of BalkendiagrammGUI_WindowClosed
|
||||
|
||||
// Ende Methoden
|
||||
|
||||
public static void main(String[] args) {
|
||||
new XYDiagrammGUI("XYDiagrammGUI");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -0,0 +1,104 @@
|
|||
object XYDiagrammGUI: TFGUIForm
|
||||
Left = 761
|
||||
Top = 237
|
||||
BorderIcons = [biSystemMenu]
|
||||
Caption = 'XYDiagrammGUI'
|
||||
ClientHeight = 512
|
||||
ClientWidth = 752
|
||||
Color = clBtnFace
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -10
|
||||
Font.Name = 'MS Sans Serif'
|
||||
Font.Style = []
|
||||
FormStyle = fsStayOnTop
|
||||
OldCreateOrder = True
|
||||
Position = poDesigned
|
||||
ShowHint = True
|
||||
Visible = True
|
||||
OnClose = FormClose
|
||||
OnCloseQuery = FormCloseQuery
|
||||
OnResize = FormResize
|
||||
FrameType = 5
|
||||
Resizable = False
|
||||
Undecorated = False
|
||||
Background = clBtnFace
|
||||
windowClosed = 'BalkendiagrammGUI_WindowClosed'
|
||||
PixelsPerInch = 96
|
||||
TextHeight = 13
|
||||
object bXYDiagrammzeichnen: TJButton
|
||||
Tag = 4
|
||||
Left = 280
|
||||
Top = 456
|
||||
Width = 209
|
||||
Height = 33
|
||||
Hint = 'jButton1'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = 15658734
|
||||
actionPerformed = 'bXYDiagrammzeichnen_ActionPerformed'
|
||||
Text = 'XY-Diagramm zeichnen'
|
||||
Mnemonic = 0
|
||||
DisplayedMnemonicIndex = 0
|
||||
Selected = False
|
||||
BorderPainted = True
|
||||
FocusPainted = False
|
||||
ContentAreaFilled = True
|
||||
HorizontalAlignment = CENTER
|
||||
VerticalAlignment = CENTER
|
||||
HorizontalTextPosition = RIGHT
|
||||
VerticalTextPosition = CENTER
|
||||
IconTextGap = 4
|
||||
RolloverEnabled = False
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
object imagePanel1: TJPanel
|
||||
Tag = 38
|
||||
Left = 24
|
||||
Top = 16
|
||||
Width = 705
|
||||
Height = 409
|
||||
Hint = 'imagePanel1'
|
||||
HelpKeyword = 'ImagePanel'
|
||||
Font.Charset = DEFAULT_CHARSET
|
||||
Font.Color = clWindowText
|
||||
Font.Height = -12
|
||||
Font.Name = 'Dialog'
|
||||
Font.Style = [fsBold]
|
||||
Foreground = 3355443
|
||||
Background = clBtnFace
|
||||
Border.BorderType = NoBorder
|
||||
Border.LineColor = clBlack
|
||||
Border.LineThickness = 0
|
||||
Border.LineRounded = False
|
||||
Border.EtchHighlightColor = clBlack
|
||||
Border.EtchShadowColor = clBlack
|
||||
Border.Etchtype = 0
|
||||
Border.BevelHighlightColor = clBlack
|
||||
Border.BevelShadowColor = clBlack
|
||||
Border.Beveltype = 0
|
||||
Border.MatteColor = clBlack
|
||||
Border.MatteTop = 0
|
||||
Border.MatteLeft = 0
|
||||
Border.MatteBottom = 0
|
||||
Border.MatteRight = 0
|
||||
end
|
||||
end
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue