Version 1.0.0 (2024-12-29): Material ZPG (2020)

This commit is contained in:
Thomas Schaller 2024-12-29 14:49:35 +01:00
parent 2bdc057a5e
commit aeed9dd5f6
355 changed files with 58150 additions and 0 deletions

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,56 @@
/*--
$Id: LICENSE.txt,v 1.11 2004/02/06 09:32:57 jhunter Exp $
Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the disclaimer that follows
these conditions in the documentation and/or other materials
provided with the distribution.
3. The name "JDOM" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact <request_AT_jdom_DOT_org>.
4. Products derived from this software may not be called "JDOM", nor
may "JDOM" appear in their name, without prior written permission
from the JDOM Project Management <request_AT_jdom_DOT_org>.
In addition, we request (but do not require) that you include in the
end-user documentation provided with the redistribution and/or in the
software itself an acknowledgement equivalent to the following:
"This product includes software developed by the
JDOM Project (http://www.jdom.org/)."
Alternatively, the acknowledgment may be graphical using the logos
available at http://www.jdom.org/images/logos.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
This software consists of voluntary contributions made by many
individuals on behalf of the JDOM Project and was originally
created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
on the JDOM Project, please see <http://www.jdom.org/>.
*/

View file

@ -0,0 +1,28 @@
import imp.*;
import java.io.File;
/**
* Klasse für Beispielbilder
*
* @author Thomas Schaller
* @version v1.0 (28.11.2019)
*/
public class Beispielbild extends Picture
{
/**
* Konstruktor: öffnet das Bild katze.jpg
*/
public Beispielbild()
{
super("iris.jpg");
}
public void load(String dateiname) {
super.load("images/"+dateiname);
}
public void save(String dateiname) {
super.save("images/"+dateiname);
}
}

View file

@ -0,0 +1,40 @@
import imp.*;
import java.awt.Color;
import java.util.Random;
/**
* Algorithmen zur Änderung der Pixelpositionen eines Pictures
* z.B. drehen, spiegeln usw.
*
* @author Thomas Schaller
* @version 1.1 (28.11.2019)
*/
public class GeometrischeBildoperationen
{
/** spiegeleHorizontal spiegelt das Bild, so dass rechts und links getauscht werden
* @param originalbild Ein Bild (Picture), das gespiegelt werden soll
* @return Eine gespiegelte Kopie des Bildes
*/
public Picture spiegelHorizontal(Picture originalbild) {
int breite = originalbild.getWidth();
int hoehe = originalbild.getHeight();
Color[][] pixel = originalbild.getPixelArray();
Color[][] pixelNeu = new Color[breite][hoehe];
for(int x=0; x < breite; x++) {
for(int y=0;y < hoehe; y++) {
pixelNeu[x][y] = pixel[(breite-1)-x][y];
}
}
Picture neuesBild = new Picture();
neuesBild.setPixelArray(pixelNeu);
return neuesBild;
}
}

View file

@ -0,0 +1,20 @@
<!DOCTYPE HTML>
<!-- NewPage -->
<html lang="de">
<head>
<!-- Generated by javadoc (11.0.2) on Wed Jul 24 12:57:18 CEST 2019 -->
<title>All Classes</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="dc.created" content="2019-07-24">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<h1 class="bar">All&nbsp;Classes</h1>
<main role="main" class="indexContainer">
<ul>
<li><a href="imp/PictureViewer.html" title="class in imp">PictureViewer</a></li>
</ul>
</main>
</body>
</html>

View file

@ -0,0 +1,73 @@
<!DOCTYPE HTML>
<!-- NewPage -->
<html lang="de">
<head>
<!-- Generated by javadoc (11.0.2) on Wed Jul 24 12:57:18 CEST 2019 -->
<title>Constant Field Values</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="dc.created" content="2019-07-24">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Constant Field Values";
}
}
catch(err) {
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<main role="main">
<div class="header">
<h1 title="Constant Field Values" class="title">Constant Field Values</h1>
<section role="region">
<h2 title="Contents">Contents</h2>
<ul>
<li><a href="#imp">imp.*</a></li>
</ul>
</section>
</div>
<div class="constantValuesContainer"><a id="imp">
<!-- -->
</a>
<section role="region">
<h2 title="imp">imp.*</h2>
<ul class="blockList">
<li class="blockList">
<table class="constantsSummary">
<caption><span>imp.<a href="imp/PictureViewer.html" title="class in imp">PictureViewer</a></span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Modifier and Type</th>
<th class="colSecond" scope="col">Constant Field</th>
<th class="colLast" scope="col">Value</th>
</tr>
<tbody>
<tr class="altColor">
<td class="colFirst"><a id="imp.PictureViewer.FIT">
<!-- -->
</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
<th class="colSecond" scope="row"><code><a href="imp/PictureViewer.html#FIT">FIT</a></code></th>
<td class="colLast"><code>-1</code></td>
</tr>
<tr class="rowColor">
<td class="colFirst"><a id="imp.PictureViewer.NORMAL">
<!-- -->
</a><code>public&nbsp;static&nbsp;final&nbsp;int</code></td>
<th class="colSecond" scope="row"><code><a href="imp/PictureViewer.html#NORMAL">NORMAL</a></code></th>
<td class="colLast"><code>1</code></td>
</tr>
</tbody>
</table>
</li>
</ul>
</section>
</div>
</main>
</body>
</html>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,54 @@
<!DOCTYPE HTML>
<!-- NewPage -->
<html lang="de">
<head>
<!-- Generated by javadoc (11.0.2) on Wed Jul 24 12:57:18 CEST 2019 -->
<title>imp</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="dc.created" content="2019-07-24">
<link rel="stylesheet" type="text/css" href="../stylesheet.css" title="Style">
<script type="text/javascript" src="../script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="imp";
}
}
catch(err) {
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<main role="main">
<div class="header">
<h1 title="Package" class="title">Package&nbsp;imp</h1>
</div>
<div class="contentContainer">
<ul class="blockList">
<li class="blockList">
<table class="typeSummary">
<caption><span>Class Summary</span><span class="tabEnd">&nbsp;</span></caption>
<tr>
<th class="colFirst" scope="col">Class</th>
<th class="colLast" scope="col">Description</th>
</tr>
<tbody>
<tr class="altColor">
<th class="colFirst" scope="row"><a href="PictureViewer.html" title="class in imp">PictureViewer</a></th>
<td class="colLast">
<div class="block">Der PictureViewer ist ein Actor, der in der Lage ist ein
Objekt der Klasse Picture anzuzeigen.</div>
</td>
</tr>
</tbody>
</table>
</li>
</ul>
</div>
</main>
</body>
</html>

View file

@ -0,0 +1,23 @@
<!DOCTYPE HTML>
<!-- NewPage -->
<html lang="de">
<head>
<!-- Generated by javadoc (11.0.2) on Wed Jul 24 12:57:18 CEST 2019 -->
<title>Generated Documentation (Untitled)</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<script type="text/javascript">window.location.replace('imp/package-summary.html')</script>
<noscript>
<meta http-equiv="Refresh" content="0;imp/package-summary.html">
</noscript>
<link rel="canonical" href="imp/package-summary.html">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
</head>
<body>
<main role="main">
<noscript>
<p>JavaScript is disabled on your browser.</p>
</noscript>
<p><a href="imp/package-summary.html">imp/package-summary.html</a></p>
</main>
</body>
</html>

View file

@ -0,0 +1,40 @@
Class documentation
<---- javadoc command: ---->
E:\Programme\Informatik\BlueJ4.2\BlueJ\jdk\bin\javadoc.exe
-author
-version
-nodeprecated
-package
-Xdoclint:none
-noindex
-notree
-nohelp
-nonavbar
-source
11
-classpath
E:\Programme\Informatik\BlueJ4.2\bluej\lib\bluejcore.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\junit-4.11.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\hamcrest-core-1.3.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\lang-stride.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.base.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.controls.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.fxml.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.graphics.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.media.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.properties.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.swing.jar;E:\Programme\Informatik\BlueJ4.2\bluej\lib\javafx\lib\javafx.web.jar;F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\+libs\jdom-1.1.3.jar;F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk
-d
F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc
-encoding
windows-1252
-charset
windows-1252
F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\imp\PictureViewer.java
<---- end of javadoc command ---->
Loading source file F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\imp\PictureViewer.java...
Constructing Javadoc information...
Standard Doclet version 11.0.2
Building tree for all the packages and classes...
Generating F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc\imp\PictureViewer.html...
F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\imp\PictureViewer.java:123: warning - @param argument "b" is not a parameter name.
F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\imp\PictureViewer.java:163: warning - @param argument "factor" is not a parameter name.
Generating F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc\imp\package-summary.html...
Generating F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc\constant-values.html...
Generating F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc\serialized-form.html...
Building index for all the packages and classes...
Building index for all classes...
Generating F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc\allclasses.html...
Generating F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc\allclasses.html...
Generating F:\Informatik\Fortbildung ZPG IMP9\Fortbildungsfassung_überarbeitet\I02_alg\03_vorlagen_tauschordner\blueJVersion_Dirk\doc\index.html...
2 warnings

View file

@ -0,0 +1,139 @@
/*
* Copyright (c) 2013, 2018, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation. Oracle designates this
* particular file as subject to the "Classpath" exception as provided
* by Oracle in the LICENSE file that accompanied this code.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*/
var moduleSearchIndex;
var packageSearchIndex;
var typeSearchIndex;
var memberSearchIndex;
var tagSearchIndex;
function loadScripts(doc, tag) {
createElem(doc, tag, 'jquery/jszip/dist/jszip.js');
createElem(doc, tag, 'jquery/jszip-utils/dist/jszip-utils.js');
if (window.navigator.userAgent.indexOf('MSIE ') > 0 || window.navigator.userAgent.indexOf('Trident/') > 0 ||
window.navigator.userAgent.indexOf('Edge/') > 0) {
createElem(doc, tag, 'jquery/jszip-utils/dist/jszip-utils-ie.js');
}
createElem(doc, tag, 'search.js');
$.get(pathtoroot + "module-search-index.zip")
.done(function() {
JSZipUtils.getBinaryContent(pathtoroot + "module-search-index.zip", function(e, data) {
var zip = new JSZip(data);
zip.load(data);
moduleSearchIndex = JSON.parse(zip.file("module-search-index.json").asText());
});
});
$.get(pathtoroot + "package-search-index.zip")
.done(function() {
JSZipUtils.getBinaryContent(pathtoroot + "package-search-index.zip", function(e, data) {
var zip = new JSZip(data);
zip.load(data);
packageSearchIndex = JSON.parse(zip.file("package-search-index.json").asText());
});
});
$.get(pathtoroot + "type-search-index.zip")
.done(function() {
JSZipUtils.getBinaryContent(pathtoroot + "type-search-index.zip", function(e, data) {
var zip = new JSZip(data);
zip.load(data);
typeSearchIndex = JSON.parse(zip.file("type-search-index.json").asText());
});
});
$.get(pathtoroot + "member-search-index.zip")
.done(function() {
JSZipUtils.getBinaryContent(pathtoroot + "member-search-index.zip", function(e, data) {
var zip = new JSZip(data);
zip.load(data);
memberSearchIndex = JSON.parse(zip.file("member-search-index.json").asText());
});
});
$.get(pathtoroot + "tag-search-index.zip")
.done(function() {
JSZipUtils.getBinaryContent(pathtoroot + "tag-search-index.zip", function(e, data) {
var zip = new JSZip(data);
zip.load(data);
tagSearchIndex = JSON.parse(zip.file("tag-search-index.json").asText());
});
});
if (!moduleSearchIndex) {
createElem(doc, tag, 'module-search-index.js');
}
if (!packageSearchIndex) {
createElem(doc, tag, 'package-search-index.js');
}
if (!typeSearchIndex) {
createElem(doc, tag, 'type-search-index.js');
}
if (!memberSearchIndex) {
createElem(doc, tag, 'member-search-index.js');
}
if (!tagSearchIndex) {
createElem(doc, tag, 'tag-search-index.js');
}
$(window).resize(function() {
$('.navPadding').css('padding-top', $('.fixedNav').css("height"));
});
}
function createElem(doc, tag, path) {
var script = doc.createElement(tag);
var scriptElement = doc.getElementsByTagName(tag)[0];
script.src = pathtoroot + path;
scriptElement.parentNode.insertBefore(script, scriptElement);
}
function show(type) {
count = 0;
for (var key in data) {
var row = document.getElementById(key);
if ((data[key] & type) !== 0) {
row.style.display = '';
row.className = (count++ % 2) ? rowColor : altColor;
}
else
row.style.display = 'none';
}
updateTabs(type);
}
function updateTabs(type) {
for (var value in tabs) {
var sNode = document.getElementById(tabs[value][0]);
var spanNode = sNode.firstChild;
if (value == type) {
sNode.className = activeTableTab;
spanNode.innerHTML = tabs[value][1];
}
else {
sNode.className = tableTab;
spanNode.innerHTML = "<a href=\"javascript:show("+ value + ");\">" + tabs[value][1] + "</a>";
}
}
}
function updateModuleFrame(pFrame, cFrame) {
top.packageFrame.location = pFrame;
top.classFrame.location = cFrame;
}

View file

@ -0,0 +1,71 @@
<!DOCTYPE HTML>
<!-- NewPage -->
<html lang="de">
<head>
<!-- Generated by javadoc (11.0.2) on Wed Jul 24 12:57:18 CEST 2019 -->
<title>Serialized Form</title>
<meta http-equiv="Content-Type" content="text/html; charset=windows-1252">
<meta name="dc.created" content="2019-07-24">
<link rel="stylesheet" type="text/css" href="stylesheet.css" title="Style">
<script type="text/javascript" src="script.js"></script>
</head>
<body>
<script type="text/javascript"><!--
try {
if (location.href.indexOf('is-external=true') == -1) {
parent.document.title="Serialized Form";
}
}
catch(err) {
}
//-->
</script>
<noscript>
<div>JavaScript is disabled on your browser.</div>
</noscript>
<main role="main">
<div class="header">
<h1 title="Serialized Form" class="title">Serialized Form</h1>
</div>
<div class="serializedFormContainer">
<ul class="blockList">
<li class="blockList">
<section role="region">
<h2 title="Package">Package&nbsp;imp</h2>
<ul class="blockList">
<li class="blockList"><a id="imp.PictureViewer">
<!-- -->
</a>
<h3>Class <a href="imp/PictureViewer.html" title="class in imp">imp.PictureViewer</a> extends javax.swing.JFrame implements Serializable</h3>
<ul class="blockList">
<li class="blockList">
<h3>Serialized Fields</h3>
<ul class="blockList">
<li class="blockList">
<h4>history</h4>
<pre>java.util.Vector&lt;java.awt.image.BufferedImage&gt; history</pre>
</li>
<li class="blockList">
<h4>imagePane</h4>
<pre>javax.swing.JLabel imagePane</pre>
</li>
<li class="blockList">
<h4>picture</h4>
<pre>imp.Picture picture</pre>
</li>
<li class="blockListLast">
<h4>zoom</h4>
<pre>double zoom</pre>
</li>
</ul>
</li>
</ul>
</li>
</ul>
</section>
</li>
</ul>
</div>
</main>
</body>
</html>

View file

@ -0,0 +1,906 @@
/*
* Javadoc style sheet
*/
@import url('resources/fonts/dejavu.css');
/*
* Styles for individual HTML elements.
*
* These are styles that are specific to individual HTML elements. Changing them affects the style of a particular
* HTML element throughout the page.
*/
body {
background-color:#ffffff;
color:#353833;
font-family:'DejaVu Sans', Arial, Helvetica, sans-serif;
font-size:14px;
margin:0;
padding:0;
height:100%;
width:100%;
}
iframe {
margin:0;
padding:0;
height:100%;
width:100%;
overflow-y:scroll;
border:none;
}
a:link, a:visited {
text-decoration:none;
color:#4A6782;
}
a[href]:hover, a[href]:focus {
text-decoration:none;
color:#bb7a2a;
}
a[name] {
color:#353833;
}
a[name]:before, a[name]:target, a[id]:before, a[id]:target {
content:"";
display:inline-block;
position:relative;
padding-top:129px;
margin-top:-129px;
}
pre {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
}
h1 {
font-size:20px;
}
h2 {
font-size:18px;
}
h3 {
font-size:16px;
font-style:italic;
}
h4 {
font-size:13px;
}
h5 {
font-size:12px;
}
h6 {
font-size:11px;
}
ul {
list-style-type:disc;
}
code, tt {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
padding-top:4px;
margin-top:8px;
line-height:1.4em;
}
dt code {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
padding-top:4px;
}
table tr td dt code {
font-family:'DejaVu Sans Mono', monospace;
font-size:14px;
vertical-align:top;
padding-top:4px;
}
sup {
font-size:8px;
}
/*
* Styles for HTML generated by javadoc.
*
* These are style classes that are used by the standard doclet to generate HTML documentation.
*/
/*
* Styles for document title and copyright.
*/
.clear {
clear:both;
height:0px;
overflow:hidden;
}
.aboutLanguage {
float:right;
padding:0px 21px;
font-size:11px;
z-index:200;
margin-top:-9px;
}
.legalCopy {
margin-left:.5em;
}
.bar a, .bar a:link, .bar a:visited, .bar a:active {
color:#FFFFFF;
text-decoration:none;
}
.bar a:hover, .bar a:focus {
color:#bb7a2a;
}
.tab {
background-color:#0066FF;
color:#ffffff;
padding:8px;
width:5em;
font-weight:bold;
}
/*
* Styles for navigation bar.
*/
.bar {
background-color:#4D7A97;
color:#FFFFFF;
padding:.8em .5em .4em .8em;
height:auto;/*height:1.8em;*/
font-size:11px;
margin:0;
}
.navPadding {
padding-top: 107px;
}
.fixedNav {
position:fixed;
width:100%;
z-index:999;
background-color:#ffffff;
}
.topNav {
background-color:#4D7A97;
color:#FFFFFF;
float:left;
padding:0;
width:100%;
clear:right;
height:2.8em;
padding-top:10px;
overflow:hidden;
font-size:12px;
}
.bottomNav {
margin-top:10px;
background-color:#4D7A97;
color:#FFFFFF;
float:left;
padding:0;
width:100%;
clear:right;
height:2.8em;
padding-top:10px;
overflow:hidden;
font-size:12px;
}
.subNav {
background-color:#dee3e9;
float:left;
width:100%;
overflow:hidden;
font-size:12px;
}
.subNav div {
clear:left;
float:left;
padding:0 0 5px 6px;
text-transform:uppercase;
}
ul.navList, ul.subNavList {
float:left;
margin:0 25px 0 0;
padding:0;
}
ul.navList li{
list-style:none;
float:left;
padding: 5px 6px;
text-transform:uppercase;
}
ul.navListSearch {
float:right;
margin:0 0 0 0;
padding:0;
}
ul.navListSearch li {
list-style:none;
float:right;
padding: 5px 6px;
text-transform:uppercase;
}
ul.navListSearch li label {
position:relative;
right:-16px;
}
ul.subNavList li {
list-style:none;
float:left;
}
.topNav a:link, .topNav a:active, .topNav a:visited, .bottomNav a:link, .bottomNav a:active, .bottomNav a:visited {
color:#FFFFFF;
text-decoration:none;
text-transform:uppercase;
}
.topNav a:hover, .bottomNav a:hover {
text-decoration:none;
color:#bb7a2a;
text-transform:uppercase;
}
.navBarCell1Rev {
background-color:#F8981D;
color:#253441;
margin: auto 5px;
}
.skipNav {
position:absolute;
top:auto;
left:-9999px;
overflow:hidden;
}
/*
* Styles for page header and footer.
*/
.header, .footer {
clear:both;
margin:0 20px;
padding:5px 0 0 0;
}
.indexNav {
position:relative;
font-size:12px;
background-color:#dee3e9;
}
.indexNav ul {
margin-top:0;
padding:5px;
}
.indexNav ul li {
display:inline;
list-style-type:none;
padding-right:10px;
text-transform:uppercase;
}
.indexNav h1 {
font-size:13px;
}
.title {
color:#2c4557;
margin:10px 0;
}
.subTitle {
margin:5px 0 0 0;
}
.header ul {
margin:0 0 15px 0;
padding:0;
}
.footer ul {
margin:20px 0 5px 0;
}
.header ul li, .footer ul li {
list-style:none;
font-size:13px;
}
/*
* Styles for headings.
*/
div.details ul.blockList ul.blockList ul.blockList li.blockList h4, div.details ul.blockList ul.blockList ul.blockListLast li.blockList h4 {
background-color:#dee3e9;
border:1px solid #d0d9e0;
margin:0 0 6px -8px;
padding:7px 5px;
}
ul.blockList ul.blockList ul.blockList li.blockList h3 {
background-color:#dee3e9;
border:1px solid #d0d9e0;
margin:0 0 6px -8px;
padding:7px 5px;
}
ul.blockList ul.blockList li.blockList h3 {
padding:0;
margin:15px 0;
}
ul.blockList li.blockList h2 {
padding:0px 0 20px 0;
}
/*
* Styles for page layout containers.
*/
.contentContainer, .sourceContainer, .classUseContainer, .serializedFormContainer, .constantValuesContainer,
.allClassesContainer, .allPackagesContainer {
clear:both;
padding:10px 20px;
position:relative;
}
.indexContainer {
margin:10px;
position:relative;
font-size:12px;
}
.indexContainer h2 {
font-size:13px;
padding:0 0 3px 0;
}
.indexContainer ul {
margin:0;
padding:0;
}
.indexContainer ul li {
list-style:none;
padding-top:2px;
}
.contentContainer .description dl dt, .contentContainer .details dl dt, .serializedFormContainer dl dt {
font-size:12px;
font-weight:bold;
margin:10px 0 0 0;
color:#4E4E4E;
}
.contentContainer .description dl dd, .contentContainer .details dl dd, .serializedFormContainer dl dd {
margin:5px 0 10px 0px;
font-size:14px;
font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
}
.serializedFormContainer dl.nameValue dt {
margin-left:1px;
font-size:1.1em;
display:inline;
font-weight:bold;
}
.serializedFormContainer dl.nameValue dd {
margin:0 0 0 1px;
font-size:1.1em;
display:inline;
}
/*
* Styles for lists.
*/
li.circle {
list-style:circle;
}
ul.horizontal li {
display:inline;
font-size:0.9em;
}
ul.inheritance {
margin:0;
padding:0;
}
ul.inheritance li {
display:inline;
list-style:none;
}
ul.inheritance li ul.inheritance {
margin-left:15px;
padding-left:15px;
padding-top:1px;
}
ul.blockList, ul.blockListLast {
margin:10px 0 10px 0;
padding:0;
}
ul.blockList li.blockList, ul.blockListLast li.blockList {
list-style:none;
margin-bottom:15px;
line-height:1.4;
}
ul.blockList ul.blockList li.blockList, ul.blockList ul.blockListLast li.blockList {
padding:0px 20px 5px 10px;
border:1px solid #ededed;
background-color:#f8f8f8;
}
ul.blockList ul.blockList ul.blockList li.blockList, ul.blockList ul.blockList ul.blockListLast li.blockList {
padding:0 0 5px 8px;
background-color:#ffffff;
border:none;
}
ul.blockList ul.blockList ul.blockList ul.blockList li.blockList {
margin-left:0;
padding-left:0;
padding-bottom:15px;
border:none;
}
ul.blockList ul.blockList ul.blockList ul.blockList li.blockListLast {
list-style:none;
border-bottom:none;
padding-bottom:0;
}
table tr td dl, table tr td dl dt, table tr td dl dd {
margin-top:0;
margin-bottom:1px;
}
/*
* Styles for tables.
*/
.overviewSummary, .memberSummary, .typeSummary, .useSummary, .constantsSummary, .deprecatedSummary,
.requiresSummary, .packagesSummary, .providesSummary, .usesSummary {
width:100%;
border-spacing:0;
border-left:1px solid #EEE;
border-right:1px solid #EEE;
border-bottom:1px solid #EEE;
}
.overviewSummary, .memberSummary, .requiresSummary, .packagesSummary, .providesSummary, .usesSummary {
padding:0px;
}
.overviewSummary caption, .memberSummary caption, .typeSummary caption,
.useSummary caption, .constantsSummary caption, .deprecatedSummary caption,
.requiresSummary caption, .packagesSummary caption, .providesSummary caption, .usesSummary caption {
position:relative;
text-align:left;
background-repeat:no-repeat;
color:#253441;
font-weight:bold;
clear:none;
overflow:hidden;
padding:0px;
padding-top:10px;
padding-left:1px;
margin:0px;
white-space:pre;
}
.overviewSummary caption a:link, .memberSummary caption a:link, .typeSummary caption a:link,
.constantsSummary caption a:link, .deprecatedSummary caption a:link,
.requiresSummary caption a:link, .packagesSummary caption a:link, .providesSummary caption a:link,
.usesSummary caption a:link,
.overviewSummary caption a:hover, .memberSummary caption a:hover, .typeSummary caption a:hover,
.constantsSummary caption a:hover, .deprecatedSummary caption a:hover,
.requiresSummary caption a:hover, .packagesSummary caption a:hover, .providesSummary caption a:hover,
.usesSummary caption a:hover,
.overviewSummary caption a:active, .memberSummary caption a:active, .typeSummary caption a:active,
.constantsSummary caption a:active, .deprecatedSummary caption a:active,
.requiresSummary caption a:active, .packagesSummary caption a:active, .providesSummary caption a:active,
.usesSummary caption a:active,
.overviewSummary caption a:visited, .memberSummary caption a:visited, .typeSummary caption a:visited,
.constantsSummary caption a:visited, .deprecatedSummary caption a:visited,
.requiresSummary caption a:visited, .packagesSummary caption a:visited, .providesSummary caption a:visited,
.usesSummary caption a:visited {
color:#FFFFFF;
}
.useSummary caption a:link, .useSummary caption a:hover, .useSummary caption a:active,
.useSummary caption a:visited {
color:#1f389c;
}
.overviewSummary caption span, .memberSummary caption span, .typeSummary caption span,
.useSummary caption span, .constantsSummary caption span, .deprecatedSummary caption span,
.requiresSummary caption span, .packagesSummary caption span, .providesSummary caption span,
.usesSummary caption span {
white-space:nowrap;
padding-top:5px;
padding-left:12px;
padding-right:12px;
padding-bottom:7px;
display:inline-block;
float:left;
background-color:#F8981D;
border: none;
height:16px;
}
.memberSummary caption span.activeTableTab span, .packagesSummary caption span.activeTableTab span,
.overviewSummary caption span.activeTableTab span, .typeSummary caption span.activeTableTab span {
white-space:nowrap;
padding-top:5px;
padding-left:12px;
padding-right:12px;
margin-right:3px;
display:inline-block;
float:left;
background-color:#F8981D;
height:16px;
}
.memberSummary caption span.tableTab span, .packagesSummary caption span.tableTab span,
.overviewSummary caption span.tableTab span, .typeSummary caption span.tableTab span {
white-space:nowrap;
padding-top:5px;
padding-left:12px;
padding-right:12px;
margin-right:3px;
display:inline-block;
float:left;
background-color:#4D7A97;
height:16px;
}
.memberSummary caption span.tableTab, .memberSummary caption span.activeTableTab,
.packagesSummary caption span.tableTab, .packagesSummary caption span.activeTableTab,
.overviewSummary caption span.tableTab, .overviewSummary caption span.activeTableTab,
.typeSummary caption span.tableTab, .typeSummary caption span.activeTableTab {
padding-top:0px;
padding-left:0px;
padding-right:0px;
background-image:none;
float:none;
display:inline;
}
.overviewSummary .tabEnd, .memberSummary .tabEnd, .typeSummary .tabEnd,
.useSummary .tabEnd, .constantsSummary .tabEnd, .deprecatedSummary .tabEnd,
.requiresSummary .tabEnd, .packagesSummary .tabEnd, .providesSummary .tabEnd, .usesSummary .tabEnd {
display:none;
width:5px;
position:relative;
float:left;
background-color:#F8981D;
}
.memberSummary .activeTableTab .tabEnd, .packagesSummary .activeTableTab .tabEnd,
.overviewSummary .activeTableTab .tabEnd, .typeSummary .activeTableTab .tabEnd {
display:none;
width:5px;
margin-right:3px;
position:relative;
float:left;
background-color:#F8981D;
}
.memberSummary .tableTab .tabEnd, .packagesSummary .tableTab .tabEnd,
.overviewSummary .tableTab .tabEnd, .typeSummary .tableTab .tabEnd {
display:none;
width:5px;
margin-right:3px;
position:relative;
background-color:#4D7A97;
float:left;
}
.rowColor th, .altColor th {
font-weight:normal;
}
.overviewSummary td, .memberSummary td, .typeSummary td,
.useSummary td, .constantsSummary td, .deprecatedSummary td,
.requiresSummary td, .packagesSummary td, .providesSummary td, .usesSummary td {
text-align:left;
padding:0px 0px 12px 10px;
}
th.colFirst, th.colSecond, th.colLast, th.colConstructorName, th.colDeprecatedItemName, .useSummary th,
.constantsSummary th, .packagesSummary th, td.colFirst, td.colSecond, td.colLast, .useSummary td,
.constantsSummary td {
vertical-align:top;
padding-right:0px;
padding-top:8px;
padding-bottom:3px;
}
th.colFirst, th.colSecond, th.colLast, th.colConstructorName, th.colDeprecatedItemName, .constantsSummary th,
.packagesSummary th {
background:#dee3e9;
text-align:left;
padding:8px 3px 3px 7px;
}
td.colFirst, th.colFirst {
font-size:13px;
}
td.colSecond, th.colSecond, td.colLast, th.colConstructorName, th.colDeprecatedItemName, th.colLast {
font-size:13px;
}
.constantsSummary th, .packagesSummary th {
font-size:13px;
}
.providesSummary th.colFirst, .providesSummary th.colLast, .providesSummary td.colFirst,
.providesSummary td.colLast {
white-space:normal;
font-size:13px;
}
.overviewSummary td.colFirst, .overviewSummary th.colFirst,
.requiresSummary td.colFirst, .requiresSummary th.colFirst,
.packagesSummary td.colFirst, .packagesSummary td.colSecond, .packagesSummary th.colFirst, .packagesSummary th,
.usesSummary td.colFirst, .usesSummary th.colFirst,
.providesSummary td.colFirst, .providesSummary th.colFirst,
.memberSummary td.colFirst, .memberSummary th.colFirst,
.memberSummary td.colSecond, .memberSummary th.colSecond, .memberSummary th.colConstructorName,
.typeSummary td.colFirst, .typeSummary th.colFirst {
vertical-align:top;
}
.packagesSummary th.colLast, .packagesSummary td.colLast {
white-space:normal;
}
td.colFirst a:link, td.colFirst a:visited,
td.colSecond a:link, td.colSecond a:visited,
th.colFirst a:link, th.colFirst a:visited,
th.colSecond a:link, th.colSecond a:visited,
th.colConstructorName a:link, th.colConstructorName a:visited,
th.colDeprecatedItemName a:link, th.colDeprecatedItemName a:visited,
.constantValuesContainer td a:link, .constantValuesContainer td a:visited,
.allClassesContainer td a:link, .allClassesContainer td a:visited,
.allPackagesContainer td a:link, .allPackagesContainer td a:visited {
font-weight:bold;
}
.tableSubHeadingColor {
background-color:#EEEEFF;
}
.altColor, .altColor th {
background-color:#FFFFFF;
}
.rowColor, .rowColor th {
background-color:#EEEEEF;
}
/*
* Styles for contents.
*/
.description pre {
margin-top:0;
}
.deprecatedContent {
margin:0;
padding:10px 0;
}
.docSummary {
padding:0;
}
ul.blockList ul.blockList ul.blockList li.blockList h3 {
font-style:normal;
}
div.block {
font-size:14px;
font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
}
td.colLast div {
padding-top:0px;
}
td.colLast a {
padding-bottom:3px;
}
/*
* Styles for formatting effect.
*/
.sourceLineNo {
color:green;
padding:0 30px 0 0;
}
h1.hidden {
visibility:hidden;
overflow:hidden;
font-size:10px;
}
.block {
display:block;
margin:3px 10px 2px 0px;
color:#474747;
}
.deprecatedLabel, .descfrmTypeLabel, .implementationLabel, .memberNameLabel, .memberNameLink,
.moduleLabelInPackage, .moduleLabelInType, .overrideSpecifyLabel, .packageLabelInType,
.packageHierarchyLabel, .paramLabel, .returnLabel, .seeLabel, .simpleTagLabel,
.throwsLabel, .typeNameLabel, .typeNameLink, .searchTagLink {
font-weight:bold;
}
.deprecationComment, .emphasizedPhrase, .interfaceName {
font-style:italic;
}
.deprecationBlock {
font-size:14px;
font-family:'DejaVu Serif', Georgia, "Times New Roman", Times, serif;
border-style:solid;
border-width:thin;
border-radius:10px;
padding:10px;
margin-bottom:10px;
margin-right:10px;
display:inline-block;
}
div.block div.deprecationComment, div.block div.block span.emphasizedPhrase,
div.block div.block span.interfaceName {
font-style:normal;
}
div.contentContainer ul.blockList li.blockList h2 {
padding-bottom:0px;
}
/*
* Styles for IFRAME.
*/
.mainContainer {
margin:0 auto;
padding:0;
height:100%;
width:100%;
position:fixed;
top:0;
left:0;
}
.leftContainer {
height:100%;
position:fixed;
width:320px;
}
.leftTop {
position:relative;
float:left;
width:315px;
top:0;
left:0;
height:30%;
border-right:6px solid #ccc;
border-bottom:6px solid #ccc;
}
.leftBottom {
position:relative;
float:left;
width:315px;
bottom:0;
left:0;
height:70%;
border-right:6px solid #ccc;
border-top:1px solid #000;
}
.rightContainer {
position:absolute;
left:320px;
top:0;
bottom:0;
height:100%;
right:0;
border-left:1px solid #000;
}
.rightIframe {
margin:0;
padding:0;
height:100%;
right:30px;
width:100%;
overflow:visible;
margin-bottom:30px;
}
/*
* Styles specific to HTML5 elements.
*/
main, nav, header, footer, section {
display:block;
}
/*
* Styles for javadoc search.
*/
.ui-autocomplete-category {
font-weight:bold;
font-size:15px;
padding:7px 0 7px 3px;
background-color:#4D7A97;
color:#FFFFFF;
}
.resultItem {
font-size:13px;
}
.ui-autocomplete {
max-height:85%;
max-width:65%;
overflow-y:scroll;
overflow-x:scroll;
white-space:nowrap;
box-shadow: 0 3px 6px rgba(0,0,0,0.16), 0 3px 6px rgba(0,0,0,0.23);
}
ul.ui-autocomplete {
position:fixed;
z-index:999999;
}
ul.ui-autocomplete li {
float:left;
clear:both;
width:100%;
}
.resultHighlight {
font-weight:bold;
}
#search {
background-image:url('resources/glass.png');
background-size:13px;
background-repeat:no-repeat;
background-position:2px 3px;
padding-left:20px;
position:relative;
right:-18px;
}
#reset {
background-color: rgb(255,255,255);
background-image:url('resources/x.png');
background-position:center;
background-repeat:no-repeat;
background-size:12px;
border:0 none;
width:16px;
height:17px;
position:relative;
left:-4px;
top:-4px;
font-size:0px;
}
.watermark {
color:#545454;
}
.searchTagDescResult {
font-style:italic;
font-size:11px;
}
.searchTagHolderResult {
font-style:italic;
font-size:12px;
}
.searchTagResult:before, .searchTagResult:target {
color:red;
}
.moduleGraph span {
display:none;
position:absolute;
}
.moduleGraph:hover span {
display:block;
margin: -100px 0 0 100px;
z-index: 1;
}
.methodSignature {
white-space:normal;
}
/*
* Styles for user-provided tables.
*
* borderless:
* No borders, vertical margins, styled caption.
* This style is provided for use with existing doc comments.
* In general, borderless tables should not be used for layout purposes.
*
* plain:
* Plain borders around table and cells, vertical margins, styled caption.
* Best for small tables or for complex tables for tables with cells that span
* rows and columns, when the "striped" style does not work well.
*
* striped:
* Borders around the table and vertical borders between cells, striped rows,
* vertical margins, styled caption.
* Best for tables that have a header row, and a body containing a series of simple rows.
*/
table.borderless,
table.plain,
table.striped {
margin-top: 10px;
margin-bottom: 10px;
}
table.borderless > caption,
table.plain > caption,
table.striped > caption {
font-weight: bold;
font-size: smaller;
}
table.borderless th, table.borderless td,
table.plain th, table.plain td,
table.striped th, table.striped td {
padding: 2px 5px;
}
table.borderless,
table.borderless > thead > tr > th, table.borderless > tbody > tr > th, table.borderless > tr > th,
table.borderless > thead > tr > td, table.borderless > tbody > tr > td, table.borderless > tr > td {
border: none;
}
table.borderless > thead > tr, table.borderless > tbody > tr, table.borderless > tr {
background-color: transparent;
}
table.plain {
border-collapse: collapse;
border: 1px solid black;
}
table.plain > thead > tr, table.plain > tbody tr, table.plain > tr {
background-color: transparent;
}
table.plain > thead > tr > th, table.plain > tbody > tr > th, table.plain > tr > th,
table.plain > thead > tr > td, table.plain > tbody > tr > td, table.plain > tr > td {
border: 1px solid black;
}
table.striped {
border-collapse: collapse;
border: 1px solid black;
}
table.striped > thead {
background-color: #E3E3E3;
}
table.striped > thead > tr > th, table.striped > thead > tr > td {
border: 1px solid black;
}
table.striped > tbody > tr:nth-child(even) {
background-color: #EEE
}
table.striped > tbody > tr:nth-child(odd) {
background-color: #FFF
}
table.striped > tbody > tr > th, table.striped > tbody > tr > td {
border-left: 1px solid black;
border-right: 1px solid black;
}
table.striped > tbody > tr > th {
font-weight: normal;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 312 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 299 KiB

View file

@ -0,0 +1,20 @@
Eigenes Werk:
Baum1.jpg
Baum2.jpg
Iris.jpg
Katze.jpg
maske1.jpg
maske2.jpg
rosen_normal.jpg
rosen_ueberbelichtet.jpg
rosen_unterbelichtet.jpg
Pixabay Licence:
https://pixabay.com/de/illustations/haus-häuser-finde-den-unterschied-3208132/
unterschiedfinden1.png
unterschiedfinden2.png
CC-BY-SA 2.5 (https://creativecommons.org/licenses/by-sa/2.5/deed.de)
Frenelsche Zonenplatte,
Georg Wiora via Wikimedia Commons
https://commons.wikimedia.org/wiki/File:Zonenplatte_Cosinus.png

View file

@ -0,0 +1,21 @@
Eigenes Werk:
Baum1.jpg
Baum2.jpg
Iris.jpg
Katze.jpg
maske1.jpg
maske2.jpg
rosen_normal.jpg
rosen_ueberbelichtet.jpg
rosen_unterbelichtet.jpg
testbild.png
Pixabay Licence:
https://pixabay.com/de/illustations/haus-häuser-finde-den-unterschied-3208132/
unterschiedfinden1.png
unterschiedfinden2.png
CC-BY-SA 2.5 (https://creativecommons.org/licenses/by-sa/2.5/deed.de)
Frenelsche Zonenplatte,
Georg Wiora via Wikimedia Commons
https://commons.wikimedia.org/wiki/File:Zonenplatte_Cosinus.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 137 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 207 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 123 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 130 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 199 KiB

View file

@ -0,0 +1,36 @@
package imp;
import java.awt.Color;
/**
* Write a description of class PixelColor here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class HSB
{
public static double getHue(Color c) {
float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
return hsb[0];
}
public static double getSaturation(Color c) {
float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
return hsb[1];
}
public static double getBrightness(Color c) {
float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
return hsb[2];
}
public static Color getColor(double h, double s, double b) {
return new Color(Color.HSBtoRGB((float) h, (float) s, (float) b));
}
}

View file

@ -0,0 +1,747 @@
package imp;
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 fuer die Simulation von Processing-Befehlen
*
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
* werden kann.
* Zusaetzlich kann ein Bildanzeiger ueber jede Aenderung des Bildes informiert werden,
* um "Zurueck"-Befehle zu ermoeglichen. 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 uebersetzt.
*
* @version 1.2 from 06.12.2019
* @author Thomas Schaller (ZPG Informatik Klasse 9)
*/
public class Picture{
// Einstellungmoeglichkeiten fuer das Zeichnen von Rechtecken und Ellipsen
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Hoehe wird gegeben,
// CORNER = Linke obere Ecke + Breite/Hoehe, 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;
private Graphics2D g;
private boolean antialiasing;
// aktuelle Farbeinstellungen
private Color background;
private Color pencolor;
private Color fillcolor;
// aktuelle Stiftdicke
private double stroke;
// aktueller 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 Standardgroesse 500x400
*/
public Picture() {
this(500,400);
}
/**
* Erzeugt ein Bild der angegeben Groesse
* @param width Breite des Bildes
* @param height Hoehe 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) {
this.antialiasing = true;
load(filename);
showInFrame();
}
/**
* Erzeugt ein Bild der angegebenen Groesse mit festgelegtem Hintergrund
* @param width Breite des Bildes
* @param height Hoehe des Bildes
* @param background Farbe des Hintergrunds
*/
public Picture(int width, int height, String background) {
this.antialiasing = true;
this.background = decode(background);
this.pencolor = new Color(0,0,0);
this.stroke = 1;
this.fillcolor = null;
makeImage(width, height);
showInFrame();
}
public void showInFrame() {
PictureViewer v = new PictureViewer(this);
}
private void makeImage(int width, int height){
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g = (Graphics2D) this.image.getGraphics();
g.setColor(this.background);
g.fillRect(0,0,width-1, height-1);
}
protected void antialise() {
// Antialiasing
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Rendering
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
// Text
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// Color
g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
// Sonstiges
// g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
// g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
// g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
// g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
// g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
}
public void setAntialising(boolean neuerWert) {
this.antialiasing = neuerWert;
}
public boolean isAntialiasing() {
return antialiasing;
}
/**
* Legt fest, wer das Bild anzeigt.
* Diese ermoeglicht die Benachrichtung des Observers, wenn sich das Bild aendert.
* @param observer Anzeiger des Bildes
*/
public void setObserver(PictureViewer observer) {
this.observer= observer;
}
public PictureViewer getObserver() {
return observer;
}
/**
* Direktes Setzen des Bildes (fuer interne Zwecke)
* @param b Bild, das gespeichert werden soll.
*/
public void setImage(BufferedImage b) {
image = b;
}
/**
* Direktes Abfragen des Bildes (fuer interne Zwecke)
* @return Bild, das gerade gespeichert ist.
*/
public BufferedImage getImage() {
return image;
}
/**
* Definiert die Dimension der Breite und Hoehe des Anzeigefensters in Pixeleinheiten.
* Die eingebauten Variablen Breite und Hoehe werden durch die an diese Funktion uebergebenen Parameter festgelegt. So weist beispielsweise
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Hoehe 480 zu.
* @param width Breite des Bildes
* @param height Hoehe des Bildes
*/
public void size(int width, int height){
pushImage();
makeImage(width, height);
g.setColor(background);
g.fillRect(0,0,width-1, height-1);
if(observer != null) observer.resize();
repaint();
}
/**
* Liefert die Breite des Bildes zurueck.
* @return Breite des Bildes
*/
public int getWidth() {
return image.getWidth();
}
/**
* Liefert die Hoehe des Bildes zurueck.
* @return Hoehe des Bildes
*/
public int getHeight() {
return image.getHeight();
}
/**
* Erzeugt eine Kopie des Bildes und uebergibt sie an den Observer (falls existent), damit dieser die Versionen speichern kann
*/
private void pushImage() {
if(observer != null) {
observer.pushImage();
}
}
public void setTitle (String titel) {
getObserver().setTitle(titel);
}
/**
* Legt fest, ob nach jedem Zeichenbefehl automatisch das Bild auch in
* der Oberflaeche aktualisiert wird. Die Einstellung "false" beschleunigt
* das Zeichnen aufwaendiger Bilder und verhindert "Flackern".
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgeloest 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();
}
}
/**
* Ein repaint() (das Neuzeichnen) kann manuell erzwungen werden.
*/
public void forceRepaint() {
if(observer != null) {
observer.repaint();
}
}
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
/**
* Loescht den Inhalt des Bildes.
* Der Hintergrund wird mit der Hintergrundfarbe neu gefuellt.
*/
public void clear(){
pushImage();
makeImage(image.getWidth(), image.getHeight());
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-uebliche Links_Oben_Breite_Hoehe Version
* Die Aenderungen werden direkt im Array vorgenommen
* @param coord Array mit vier Koordinateneintraegen 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;
}
}
/**
* Aendert den Koordinaten-Modus beim Zeichnen von Rechtecken.
* Aendert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise aendert, wie Parameter, die an rect() uebergeben werden, interpretiert werden.
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
* waehrend der dritte und vierte Parameter seine Breite und Hoehe 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 gegenueberliegenden Ecke.
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
* waehrend der dritte und vierte Parameter seine Breite und Hoehe sind.
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
* verwendet aber den dritten und vierten Parameter, um die Haelfte der Breite und Hoehe der Formen festzulegen.
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
*/
public void rectMode(int mode) {
rectMode = mode;
}
/**
* Aendert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
* Aendert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise aendert, wie Parameter, die an ellipse() uebergeben werden, interpretiert werden.
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
* waehrend der dritte und vierte Parameter seine Breite und Hoehe 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 Hoehe 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 gegenueberliegenden Ecke.
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
* verwendet aber den dritten und vierten Parameter, um die Haelfte der Breite und Hoehe 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 einzufaerben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefuellt werden, daher hat die Funktion fill() keinen
* Einfluss auf die Farbe einer Zeile. Linien werden standardmaessig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
* {@link #strokeWeight(double) strokeWeight()} geaendert 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();
if (stroke > 0) {
g.setColor(pencolor);
g.setStroke(new BasicStroke((float) stroke));
// if(antialiasing) antialise();
g.drawLine(x1, y1, x2, y2);
}
repaint();
}
/**
* Zeichnet ein Rechteck auf das Bild.
* Standardmaessig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Hoehe.
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geaendert werden.
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Fuellfarbe des Rechtecks gewaehlt 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() geaendert werden).
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geaendert werden).
* @param c meist die Breite des Rechtecks (kann durch rectMode() geaendert werden).
* @param d meist die Hoehe des Rechtecks (kann durch rectMode() geaendert werden).
*
*/
public void rect(int a, int b, int c, int d) {
pushImage();
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.
* Standardmaessig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Hoehe.
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geaendert werden.
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Fuellfarbe des Rechtecks gewaehlt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geaendert werden).
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geaendert werden).
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geaendert werden).
* @param d meist die Hoehe des Rechtecks (kann durch ellipseMode() geaendert werden).
*
*/
public void ellipse(int a, int b, int c, int d) {
pushImage();
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));
// if(antialiasing) antialise();
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 Fuellfarbe des Rechtecks gewaehlt 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 aehnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
* sind nicht auf neunzig Grad beschraenkt. 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 Fuellfarbe des Rechtecks gewaehlt 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 Fuellfarbe des Rechtecks gewaehlt 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();
if(fillcolor != null) {
g.setColor(fillcolor);
g.fillPolygon(x,y, y.length);
}
if(pencolor != null) {
g.setColor(pencolor);
g.setStroke(new BasicStroke((float) stroke));
// if(antialiasing) antialise();
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 fuer den Punkt, der zweite Wert ist der y-Wert fuer 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 ausgewaehlte 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();
if(pencolor != null) {
if(fillcolor == null)
g.setColor(Color.black);
else
g.setColor(fillcolor);
g.setStroke(new BasicStroke((float) stroke));
g.setFont(textfont);
// if(antialiasing)g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString(s, x, y);
}
repaint();
}
/**
* Legt die Schriftart fuer Textausgaben fest.
* Jeder uebliche 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 Raender 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 fuer die roten, gruenen 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 Raender 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 weiss, 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 Raender um Formen gezeichnet werden.
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
* @param r Rotanteil (0-255) der Stiftfarbe
* @param g Gruenanteil (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 Raender um Formen gezeichnet werden soll.
*/
public void noStroke() {
this.pencolor = null;
}
/**
* Legt die Breite des Strichs fuer 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 gefuellt werden.
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei fuer die roten, gruenen und blauen Komponenten,
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
* @param fillcolor Fuellfarbe in Hexadezimaldarstellung
*/
public void fill(String fillcolor) {
this.fillcolor = decode(fillcolor);
}
/**
* Legt die Farbe fest, mit der Formen gefuellt werden.
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
* @param fillcolor Fuellfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiss, 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 gefuellt werden.
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
* @param r Rotanteil (0-255) der Fuellfarbe
* @param g Gruenanteil (0-255) der Fuellfarbe
* @param b Blauanteil (0-255) der Fuellfarbe
*/
public void fill(int r, int g, int b) {
this.fillcolor = new Color(r,g,b);
}
/** Legt fest, dass die Formen nicht gefuellt werden sollen.
*/
public void noFill() {
this.fillcolor = null;
}
/**
* Die Funktion background() setzt die Farbe, die fuer den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
* Es ist nicht moeglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberflaeche zu verwenden.
* @param c Farbe fuer den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiss, 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 fuer den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
* Es ist nicht moeglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberflaeche zu verwenden.
* @param r Rotanteil (0-255) der Hintergrundfarbe
* @param g Gruenanteil (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();
}
/**
* Die Funktion background() setzt die Farbe, die fuer den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
* Es ist nicht moeglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberflaeche zu verwenden.
* @param hex String Farbe in Hexadezimalangabe
*/
public void background(String hex) {
this.background = decode(hex);
this.clear();
}
// ----------------------------------------- Dateioperationen -----------------------------------------------
/**
* Laedt ein Bild aus dem Dateisystem.
* Laedt ein Bild von einem Datentraeger und setzt Stiftfarbe und Fuellfarbe auf Standardwerte zurueck.
* @param filename Dateiname des Bildes
*/
public void load(String filename) {
try{
this.image = ImageIO.read(new File(filename));
this.g = (Graphics2D) image.getGraphics();
this.background = decode("D0D0D0");
this.pencolor = new Color(0,0,0);
this.fillcolor = null;
this.stroke = 1;
if(observer != null) observer.resize();
this.repaint();
} catch(Exception e) {
System.out.println("Fehler beim Einlesen der Bilddatei");
}
}
/**
* Speichert ein Bild.
* Speichert ein Bild auf einem Datentraeger. Zulaessig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
* Standardmaessig wird die Dateiendung .png ergaenzt, 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 Groesse 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);
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 Verzoegern der Ausgabe
* @param millis Wartezeit in Millisekunden
*/
public void delay(int millis) {
try{
Thread.sleep(millis);
} catch(Exception e) {
System.out.println("Fehler beim Verzoegern der Ausgabe");
}
}
}

View file

@ -0,0 +1,221 @@
package imp;
import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import javax.swing.*;
import javax.swing.event.*;
import java.util.Vector;
import javax.imageio.*;
import java.io.*;
/**
* Der PictureViewer ist ein JFrame, der in der Lage ist ein
* Objekt der Klasse Picture anzuzeigen. Zusätzlich können
* mehrere Verarbeitungsschritte gespeichert werden, um ein
* "zurück"-Funktion zu ermöglichen.
*
* @author Thomas Schaller
* @version V1.2 vom 06.12.2019
*/
public class PictureViewer extends JFrame implements MouseWheelListener
{
public static final int FIT = -1;
public static final int NORMAL = 1;
private static final int ANZ_BACK = 0;
private double zoom;
protected Picture picture = null;
private Vector<BufferedImage> history;
private JLabel imagePane = new JLabel();
private JScrollPane scrollPane;
// private boolean antialiasing;
/**
* Erzeugt ein ScrollPanel der Größe 500x400
*/
public PictureViewer() {
this(800,500);
}
/**
* Erzeugt ein ScrollPanel der angegebenen Größe
* @param width Breite des Bildes
* @param height Höhe des Bildes
*/
public PictureViewer(int width, int height) {
this(new Picture(width, height));
}
public PictureViewer(Picture p) {
picture = p;
picture.setObserver(this);
this.history = new Vector<BufferedImage>();
this.zoom = NORMAL;
setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE);
Container cp = getContentPane();
cp.setLayout(new BorderLayout());
imagePane.setPreferredSize(new Dimension(p.getWidth(), p.getHeight()));
scrollPane = new JScrollPane( JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED );
scrollPane.setViewportView( imagePane );
cp.add(scrollPane, BorderLayout.CENTER);
pack();
this.setVisible(true);
repaint();
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
int x = (d.width - getSize().width);
//int x = 0;
int y = 0;
setLocation(x, y);
scrollPane.addMouseWheelListener(this);
}
/**
* 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 i = history.get(anz-1);
history.removeElementAt(anz-1);
picture.setImage(i);
repaint();
}
}
/**
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
*/
public void back() {
popImage();
}
/**
* 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 zoom) {
if(zoom>0.01 && zoom<10.0) {
this.zoom = zoom;
}
// else this.zoom = NORMAL;
resize();
repaint();
}
// public void setAntialiasing(boolean antialiasing) {
// this.antialiasing = antialiasing;
// }
/**
* Setzt die automatische Neuanzeige des Bildes.
* Mit dieser Methode kann man einstellen, ob nach jedem Zeichenbefehl
* die Anzeige auf dem Bildschirm aktualisiert werden soll. Bei sehr
* vielen Zeichenbefehlen wird die Ausgabe dadurch sehr langsam. Es reicht
* eine Anzeige am Ende der Zeichenbefehle. Rufen Sie dann für das Neuzeichnen
* die Methode refresh() auf.
* @param autoRefresh true, wenn nach jedem Zeichenbefehl die Anzeige aktualisiert werden soll.
*/
public void setAutoRefresh(boolean autoRefresh) {
picture.setAutoRefresh(autoRefresh);
}
/**
* Sorgt für die Aktualisierung der Bildschrimanzeige. Das aktuelle Bild
* wird dadurch angezeigt. Durch Einstellung von autoRefresh kann die
* Anzeige automatisiert werden.
*/
public void refresh() {
repaint();
}
/**
* Passt die Framegröße an das anzuzeigende Bild an.
*/
public void resize() {
int pref_x = (int) (picture.getWidth()*zoom);
int pref_y = (int) (picture.getHeight()*zoom);
imagePane.setPreferredSize(new Dimension(pref_x,pref_y));
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();
if((pref_x > d.getWidth()-30) || (pref_y > d.getHeight()-100)) {
pref_x = Math.min(pref_x, (int) d.getWidth()-30);
pref_y = Math.min(pref_y, (int) d.getHeight()-100);
scrollPane.setPreferredSize(new Dimension(pref_x,pref_y));
} else scrollPane.setPreferredSize(null);
imagePane.revalidate();
pack();
}
/**
* Setzt das angezeigt Bild neu und beachtet dabei den Zoomfaktor.
*/
public void repaint() {
double faktor = zoom;
if (zoom == FIT) {
double faktorw = (double) imagePane.getWidth() / picture.getWidth();
double faktorh = (double) imagePane.getHeight() / picture.getHeight();
faktor = Math.min(faktorw, faktorh);
}
int disp_width = (int) (picture.getWidth()*faktor);
int disp_height = (int) (picture.getHeight()*faktor);
BufferedImage image = new BufferedImage(disp_width, disp_height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) image.getGraphics();
if(picture.isAntialiasing()) {
picture.antialise();
}
else g.getRenderingHints().clear();
g.drawImage(picture.getImage(),0,0,disp_width, disp_height, 0, 0, picture.getWidth(), picture.getHeight(), null);
g.setColor(new java.awt.Color(0,0,0));
g.setStroke(new BasicStroke((float) 1));
g.drawRect(0,0,disp_width-1, disp_height-1);
imagePane.setIcon(new ImageIcon(image));
imagePane.repaint();
}
/** Setzt ZoomFaktor über MouseWheel
*
*/
public void mouseWheelMoved(MouseWheelEvent e) {
int notches = e.getWheelRotation();
if ( notches < 0) {
setZoom(zoom * 1.1);
} else {
setZoom(zoom * 1.0/1.1);
}
}
}

View file

@ -0,0 +1,898 @@
package imp;
/**
* 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());
}
}
}
}

View file

@ -0,0 +1,319 @@
package imp;
/**
* 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));
}
}

View file

@ -0,0 +1,639 @@
package imp;
/**
* 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);}
}
}

View file

@ -0,0 +1,71 @@
#BlueJ package file
dependency1.from=PictureViewer
dependency1.to=Picture
dependency1.type=UsesDependency
dependency2.from=Table
dependency2.to=TableRow
dependency2.type=UsesDependency
dependency3.from=Picture
dependency3.to=PictureViewer
dependency3.type=UsesDependency
objectbench.height=89
objectbench.width=565
package.divider.horizontal=0.6
package.divider.vertical=0.808
package.editor.height=397
package.editor.width=475
package.editor.x=561
package.editor.y=305
package.frame.height=600
package.frame.width=605
package.numDependencies=3
package.numTargets=6
package.showExtends=true
package.showUses=true
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=PictureViewer
target1.showInterface=false
target1.type=ClassTarget
target1.width=110
target1.x=280
target1.y=310
target2.height=50
target2.name=Table
target2.showInterface=false
target2.type=ClassTarget
target2.width=80
target2.x=120
target2.y=110
target3.height=50
target3.name=HSB
target3.showInterface=false
target3.type=ClassTarget
target3.width=80
target3.x=10
target3.y=90
target4.height=50
target4.name=Picture
target4.showInterface=false
target4.type=ClassTarget
target4.width=80
target4.x=180
target4.y=250
target5.height=50
target5.name=XML
target5.showInterface=false
target5.type=ClassTarget
target5.width=80
target5.x=220
target5.y=130
target6.height=50
target6.name=TableRow
target6.showInterface=false
target6.type=ClassTarget
target6.width=90
target6.x=220
target6.y=60

View file

@ -0,0 +1,46 @@
#BlueJ package file
editor.fx.0.height=739
editor.fx.0.width=816
editor.fx.0.x=552
editor.fx.0.y=100
objectbench.height=142
objectbench.width=815
package.divider.horizontal=0.5995115995115995
package.divider.vertical=0.6902286902286903
package.editor.height=325
package.editor.width=725
package.editor.x=326
package.editor.y=348
package.frame.height=581
package.frame.width=855
package.numDependencies=0
package.numTargets=3
package.showExtends=true
package.showUses=true
project.charset=UTF-8
project.invoke.thread=FX
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=Beispielbild
target1.showInterface=false
target1.type=ClassTarget
target1.width=100
target1.x=20
target1.y=110
target2.height=62
target2.name=imp
target2.type=PackageTarget
target2.width=80
target2.x=80
target2.y=10
target3.height=50
target3.name=GeometrischeBildoperationen
target3.showInterface=false
target3.type=ClassTarget
target3.width=210
target3.x=260
target3.y=110

View file

@ -0,0 +1,12 @@
Sollte es bei der Ausführung des Projekts zu folgender Fehlermeldung kommen:
java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268)
at javafx.application.Platform.runLater(Platform.java:83)
at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:902)
at bluej.runtime.ExecServer.access$700(ExecServer.java:78)
at bluej.runtime.ExecServer$3.run(ExecServer.java:787)
dann lösen Sie das Problem, indem Sie entweder
a) die neuste BlueJ-Version installieren.
b) in BlueJ unter Werkzeuge->Einstellungen->Diverses->Run user code in this project on thread: "Default" wählen (BlueJ Version 4.1.2)

Binary file not shown.

View file

@ -0,0 +1,56 @@
/*--
$Id: LICENSE.txt,v 1.11 2004/02/06 09:32:57 jhunter Exp $
Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the disclaimer that follows
these conditions in the documentation and/or other materials
provided with the distribution.
3. The name "JDOM" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact <request_AT_jdom_DOT_org>.
4. Products derived from this software may not be called "JDOM", nor
may "JDOM" appear in their name, without prior written permission
from the JDOM Project Management <request_AT_jdom_DOT_org>.
In addition, we request (but do not require) that you include in the
end-user documentation provided with the redistribution and/or in the
software itself an acknowledgement equivalent to the following:
"This product includes software developed by the
JDOM Project (http://www.jdom.org/)."
Alternatively, the acknowledgment may be graphical using the logos
available at http://www.jdom.org/images/logos.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
This software consists of voluntary contributions made by many
individuals on behalf of the JDOM Project and was originally
created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
on the JDOM Project, please see <http://www.jdom.org/>.
*/

View file

@ -0,0 +1,28 @@
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class BildbearbeitungGUI extends Application {
@Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(getClass().getResource("view/Test.fxml"));
VBox root = (VBox) loader.load();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.show();
}
catch(Exception e) {
System.out.println(e);
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}

View file

@ -0,0 +1,20 @@
Eigenes Werk:
Baum1.jpg
Baum2.jpg
Iris.jpg
Katze.jpg
maske1.jpg
maske2.jpg
rosen_normal.jpg
rosen_ueberbelichtet.jpg
rosen_unterbelichtet.jpg
Pixabay Licence:
https://pixabay.com/de/illustations/haus-häuser-finde-den-unterschied-3208132/
unterschiedfinden1.png
unterschiedfinden2.png
CC-BY-SA 2.5 (https://creativecommons.org/licenses/by-sa/2.5/deed.de)
Frenelsche Zonenplatte,
Georg Wiora via Wikimedia Commons
https://commons.wikimedia.org/wiki/File:Zonenplatte_Cosinus.png

View file

@ -0,0 +1,21 @@
Eigenes Werk:
Baum1.jpg
Baum2.jpg
Iris.jpg
Katze.jpg
maske1.jpg
maske2.jpg
rosen_normal.jpg
rosen_ueberbelichtet.jpg
rosen_unterbelichtet.jpg
testbild.png
Pixabay Licence:
https://pixabay.com/de/illustations/haus-häuser-finde-den-unterschied-3208132/
unterschiedfinden1.png
unterschiedfinden2.png
CC-BY-SA 2.5 (https://creativecommons.org/licenses/by-sa/2.5/deed.de)
Frenelsche Zonenplatte,
Georg Wiora via Wikimedia Commons
https://commons.wikimedia.org/wiki/File:Zonenplatte_Cosinus.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 140 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 454 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 456 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 470 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 127 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View file

@ -0,0 +1,36 @@
package imp;
import java.awt.Color;
/**
* Write a description of class PixelColor here.
*
* @author (your name)
* @version (a version number or a date)
*/
public class HSB
{
public static double getHue(Color c) {
float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
return hsb[0];
}
public static double getSaturation(Color c) {
float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
return hsb[1];
}
public static double getBrightness(Color c) {
float[] hsb = Color.RGBtoHSB(c.getRed(), c.getGreen(), c.getBlue(), null);
return hsb[2];
}
public static Color getColor(double h, double s, double b) {
return new Color(Color.HSBtoRGB((float) h, (float) s, (float) b));
}
}

View file

@ -0,0 +1,43 @@
package imp;
import javafx.scene.control.TextField;
public class NumberTextField extends TextField {
@Override public void replaceText(int start, int end, String text) {
if (text.matches("[0-9.]") || text == "") {
super.replaceText(start, end, text);
}
}
@Override public void replaceSelection(String text) {
if (text.matches("[0-9.]") || text == "") {
super.replaceSelection(text);
}
}
public double getDoubleValue() {
try{
return Double.parseDouble(this.getText());
} catch(Exception e) {
return 0.0;
}
}
public int getIntValue() {
try{
return Integer.parseInt(this.getText());
} catch(Exception e) {
return 0;
}
}
public void setValue(double v) {
setText(""+v);
}
public void setValue(int v) {
setText(""+v);
}
}

View file

@ -0,0 +1,744 @@
package imp;
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 fuer die Simulation von Processing-Befehlen
*
* Diese Klasse stellt ein BufferedImage bereit, in das mit Processing-Befehlen gezeichnet
* werden kann.
* Zusaetzlich kann ein Bildanzeiger ueber jede Aenderung des Bildes informiert werden,
* um "Zurueck"-Befehle zu ermoeglichen. 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 uebersetzt.
*
* @version 1.2 from 06.12.2019
* @author Thomas Schaller (ZPG Informatik Klasse 9)
*/
public class Picture{
// Einstellungmoeglichkeiten fuer das Zeichnen von Rechtecken und Ellipsen
// RADIUS = Mittelpunkt+Radius wird gegeben, CENTER = Mittelpunkt und Breite/Hoehe wird gegeben,
// CORNER = Linke obere Ecke + Breite/Hoehe, 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;
private Graphics2D g;
private boolean antialiasing;
// aktuelle Farbeinstellungen
private Color background;
private Color pencolor;
private Color fillcolor;
// aktuelle Stiftdicke
private double stroke;
// aktueller 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 Standardgroesse 500x400
*/
public Picture() {
this(500,400);
}
/**
* Erzeugt ein Bild der angegeben Groesse
* @param width Breite des Bildes
* @param height Hoehe 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) {
this.antialiasing = true;
load(filename);
}
/**
* Erzeugt ein Bild der angegebenen Groesse mit festgelegtem Hintergrund
* @param width Breite des Bildes
* @param height Hoehe des Bildes
* @param background Farbe des Hintergrunds
*/
public Picture(int width, int height, String background) {
this.antialiasing = true;
this.background = decode(background);
this.pencolor = new Color(0,0,0);
this.stroke = 1;
this.fillcolor = null;
makeImage(width, height);
}
public void showInFrame() {
PictureViewer v = new PictureViewer(this);
}
private void makeImage(int width, int height){
this.image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
g = (Graphics2D) this.image.getGraphics();
g.setColor(this.background);
g.fillRect(0,0,width-1, height-1);
}
protected void antialise() {
// Antialiasing
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
// Rendering
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
// Text
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
// Color
g.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
// Sonstiges
// g.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
// g.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
// g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
// g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
// g.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_NORMALIZE);
}
public void setAntialising(boolean neuerWert) {
this.antialiasing = neuerWert;
}
public boolean isAntialiasing() {
return antialiasing;
}
/**
* Legt fest, wer das Bild anzeigt.
* Diese ermoeglicht die Benachrichtung des Observers, wenn sich das Bild aendert.
* @param observer Anzeiger des Bildes
*/
public void setObserver(PictureViewer observer) {
this.observer= observer;
}
public PictureViewer getObserver() {
return observer;
}
/**
* Direktes Setzen des Bildes (fuer interne Zwecke)
* @param b Bild, das gespeichert werden soll.
*/
public void setImage(BufferedImage b) {
image = b;
}
/**
* Direktes Abfragen des Bildes (fuer interne Zwecke)
* @return Bild, das gerade gespeichert ist.
*/
public BufferedImage getImage() {
return image;
}
/**
* Definiert die Dimension der Breite und Hoehe des Anzeigefensters in Pixeleinheiten.
* Die eingebauten Variablen Breite und Hoehe werden durch die an diese Funktion uebergebenen Parameter festgelegt. So weist beispielsweise
* der Befehl size(640, 480) der Variablen Breite 640 und der Variablen Hoehe 480 zu.
* @param width Breite des Bildes
* @param height Hoehe des Bildes
*/
public void size(int width, int height){
pushImage();
makeImage(width, height);
g.setColor(background);
g.fillRect(0,0,width-1, height-1);
repaint();
}
/**
* Liefert die Breite des Bildes zurueck.
* @return Breite des Bildes
*/
public int getWidth() {
return image.getWidth();
}
/**
* Liefert die Hoehe des Bildes zurueck.
* @return Hoehe des Bildes
*/
public int getHeight() {
return image.getHeight();
}
/**
* Erzeugt eine Kopie des Bildes und uebergibt 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 Oberflaeche aktualisiert wird. Die Einstellung "false" beschleunigt
* das Zeichnen aufwaendiger Bilder und verhindert "Flackern".
* Das Neuzeichnen kann durch die Methode "refresh" gezielt ausgeloest 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();
}
}
/**
* Ein repaint() (das Neuzeichnen) kann manuell erzwungen werden.
*/
public void forceRepaint() {
if(observer != null) {
observer.repaint();
}
}
// ----------------------------------------- Zeichenfunktionen -----------------------------------------------
/**
* Loescht den Inhalt des Bildes.
* Der Hintergrund wird mit der Hintergrundfarbe neu gefuellt.
*/
public void clear(){
pushImage();
makeImage(image.getWidth(), image.getHeight());
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-uebliche Links_Oben_Breite_Hoehe Version
* Die Aenderungen werden direkt im Array vorgenommen
* @param coord Array mit vier Koordinateneintraegen 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;
}
}
/**
* Aendert den Koordinaten-Modus beim Zeichnen von Rechtecken.
* Aendert die Position, von der aus Rechtecke gezeichnet werden, indem es die Art und Weise aendert, wie Parameter, die an rect() uebergeben werden, interpretiert werden.
* Der Standardmodus ist rectMode(Bild.CORNER), der die ersten beiden Parameter von rect() als die linke obere Ecke der Form interpretiert,
* waehrend der dritte und vierte Parameter seine Breite und Hoehe 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 gegenueberliegenden Ecke.
* rectMode(Bild.CENTER) interpretiert die ersten beiden Parameter von rect() als Mittelpunkt der Form,
* waehrend der dritte und vierte Parameter seine Breite und Hoehe sind.
* rectMode(RADIUS) verwendet auch die ersten beiden Parameter von rect() als Mittelpunkt der Form,
* verwendet aber den dritten und vierten Parameter, um die Haelfte der Breite und Hoehe der Formen festzulegen.
* @param mode Modus der Koordinateninterpretation (CORNER, CORNERS, CENTER oder RADIUS)
*/
public void rectMode(int mode) {
rectMode = mode;
}
/**
* Aendert den Koordinaten-Modus beim Zeichnen von Kreisen/Ellipsen.
* Aendert die Position, von der aus Kreise/Ellipsen gezeichnet werden, indem es die Art und Weise aendert, wie Parameter, die an ellipse() uebergeben werden, interpretiert werden.
* Der Standardmodus ist ellipseMode(Bild.CENTER), der die ersten beiden Parameter von ellipse() als Mittelpunkt der Form interpretiert,
* waehrend der dritte und vierte Parameter seine Breite und Hoehe 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 Hoehe 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 gegenueberliegenden Ecke.
* ellipseMode(RADIUS) verwendet auch die ersten beiden Parameter von ellipse() als Mittelpunkt der Form,
* verwendet aber den dritten und vierten Parameter, um die Haelfte der Breite und Hoehe 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 einzufaerben, verwenden Sie die {@link #stroke(int, int, int) stroke()} Funktion. Eine Zeile kann nicht gefuellt werden, daher hat die Funktion fill() keinen
* Einfluss auf die Farbe einer Zeile. Linien werden standardmaessig mit einer Breite von einem Pixel gezeichnet, dies kann jedoch mit der Funktion
* {@link #strokeWeight(double) strokeWeight()} geaendert 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();
if (stroke > 0) {
g.setColor(pencolor);
g.setStroke(new BasicStroke((float) stroke));
// if(antialiasing) antialise();
g.drawLine(x1, y1, x2, y2);
}
repaint();
}
/**
* Zeichnet ein Rechteck auf das Bild.
* Standardmaessig legen die ersten beiden Parameter die Position der linken oberen Ecke fest, der dritte die Breite und der vierte die Hoehe.
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #rectMode(int) rectMode()} geaendert werden.
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Fuellfarbe des Rechtecks gewaehlt 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() geaendert werden).
* @param b meist die y-Koordinate der linken oberen Ecke (kann durch rectMode() geaendert werden).
* @param c meist die Breite des Rechtecks (kann durch rectMode() geaendert werden).
* @param d meist die Hoehe des Rechtecks (kann durch rectMode() geaendert werden).
*
*/
public void rect(int a, int b, int c, int d) {
pushImage();
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.
* Standardmaessig legen die ersten beiden Parameter die Position des Mittelpunkts fest, der dritte die Breite und der vierte die Hoehe.
* Die Art und Weise, wie diese Parameter interpretiert werden, kann jedoch mit der Funktion {@link #ellipseMode(int) ellipseMode()} geaendert werden.
* Durch den Befehl {@link #fill(int,int,int) fill()} /{@link #noFill() noFill()} kann die Fuellfarbe des Rechtecks gewaehlt werden, durch {@link #stroke(int, int, int) stroke()}/{@link #noStroke() noStroke()} die Rahmenfarbe.
* @param a meist die x-Koordinate des Mittelpunkts (kann durch ellipseMode() geaendert werden).
* @param b meist die y-Koordinate des Mittelpunkts (kann durch ellipseMode() geaendert werden).
* @param c meist die Breite des Rechtecks (kann durch ellipseMode() geaendert werden).
* @param d meist die Hoehe des Rechtecks (kann durch ellipseMode() geaendert werden).
*
*/
public void ellipse(int a, int b, int c, int d) {
pushImage();
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));
// if(antialiasing) antialise();
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 Fuellfarbe des Rechtecks gewaehlt 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 aehnlich wie ein Rechteck, aber die Winkel zwischen seinen Kanten
* sind nicht auf neunzig Grad beschraenkt. 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 Fuellfarbe des Rechtecks gewaehlt 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 Fuellfarbe des Rechtecks gewaehlt 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();
if(fillcolor != null) {
g.setColor(fillcolor);
g.fillPolygon(x,y, y.length);
}
if(pencolor != null) {
g.setColor(pencolor);
g.setStroke(new BasicStroke((float) stroke));
// if(antialiasing) antialise();
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 fuer den Punkt, der zweite Wert ist der y-Wert fuer 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 ausgewaehlte 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();
if(pencolor != null) {
if(fillcolor == null)
g.setColor(Color.black);
else
g.setColor(fillcolor);
g.setStroke(new BasicStroke((float) stroke));
g.setFont(textfont);
// if(antialiasing)g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.drawString(s, x, y);
}
repaint();
}
/**
* Legt die Schriftart fuer Textausgaben fest.
* Jeder uebliche 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 Raender 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 fuer die roten, gruenen 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 Raender 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 weiss, 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 Raender um Formen gezeichnet werden.
* Diese Farbe wird komponentenweise als RGB-Wert angegeben
* @param r Rotanteil (0-255) der Stiftfarbe
* @param g Gruenanteil (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 Raender um Formen gezeichnet werden soll.
*/
public void noStroke() {
this.pencolor = null;
}
/**
* Legt die Breite des Strichs fuer 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 gefuellt werden.
* Diese Farbe wird hexadezimal in Form der RGB angegeben: z.B. "CCFFAA" oder "004E23". Die Syntax verwendet sechs Ziffern - je zwei fuer die roten, gruenen und blauen Komponenten,
* um eine Farbe anzugeben (genau wie Farben typischerweise in HTML und CSS angegeben werden).
* @param fillcolor Fuellfarbe in Hexadezimaldarstellung
*/
public void fill(String fillcolor) {
this.fillcolor = decode(fillcolor);
}
/**
* Legt die Farbe fest, mit der Formen gefuellt werden.
* Diese Farbe wird entweder als Graustufe (0-255) oder als 3-Byte RGB-Wert angegeben.
* @param fillcolor Fuellfarbe (0-255: Graustufe zwischen 0 schwarz und 255 weiss, 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 gefuellt werden.
* Diese Farbe wird komponentenweise als RGB-Wert angegeben.
* @param r Rotanteil (0-255) der Fuellfarbe
* @param g Gruenanteil (0-255) der Fuellfarbe
* @param b Blauanteil (0-255) der Fuellfarbe
*/
public void fill(int r, int g, int b) {
this.fillcolor = new Color(r,g,b);
}
/** Legt fest, dass die Formen nicht gefuellt werden sollen.
*/
public void noFill() {
this.fillcolor = null;
}
/**
* Die Funktion background() setzt die Farbe, die fuer den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
* Es ist nicht moeglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberflaeche zu verwenden.
* @param c Farbe fuer den Hintergrund (0-255: Graustufe zwischen 0 schwarz und 255 weiss, 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 fuer den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
* Es ist nicht moeglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberflaeche zu verwenden.
* @param r Rotanteil (0-255) der Hintergrundfarbe
* @param g Gruenanteil (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();
}
/**
* Die Funktion background() setzt die Farbe, die fuer den Hintergrund des Bildes verwendet wird. Der Standardhintergrund ist hellgrau.
* Es ist nicht moeglich, den Alpha-Parameter Transparenz mit Hintergrundfarben auf der Hauptzeichnungsoberflaeche zu verwenden.
* @param hex String Farbe in Hexadezimalangabe
*/
public void background(String hex) {
this.background = decode(hex);
this.clear();
}
// ----------------------------------------- Dateioperationen -----------------------------------------------
/**
* Laedt ein Bild aus dem Dateisystem.
* Laedt ein Bild von einem Datentraeger und setzt Stiftfarbe und Fuellfarbe auf Standardwerte zurueck.
* @param filename Dateiname des Bildes
*/
public void load(String filename) {
try{
this.image = ImageIO.read(new File(filename));
this.g = (Graphics2D) image.getGraphics();
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 Datentraeger. Zulaessig sind die Dateiformate PNG und GIF. Die Dateiendung legt den Typ fest.
* Standardmaessig wird die Dateiendung .png ergaenzt, 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 Color(image.getRGB(x,y));
}
}
return pixel;
}
/**
* Setzt das Bild neu auf Basis des Pixel-Arrays.
* Die Groesse 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);
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 Verzoegern der Ausgabe
* @param millis Wartezeit in Millisekunden
*/
public void delay(int millis) {
try{
Thread.sleep(millis);
} catch(Exception e) {
System.out.println("Fehler beim Verzoegern der Ausgabe");
}
}
}

View file

@ -0,0 +1,206 @@
package imp;
/**
* 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 javafx.scene.control.ScrollPane;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.embed.swing.SwingFXUtils;
import java.util.Vector;
import java.awt.image.BufferedImage;
import java.awt.image.ColorModel;
import java.awt.image.WritableRaster;
public class PictureViewer extends ScrollPane
{
// 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 Image scrollImageIcon;
private ImageView 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 = SwingFXUtils.toFXImage(picture.getImage(), null);
//new Image(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
imageLabel = new ImageView(scrollImageIcon);
imageLabel.setPreserveRatio(true);
// imageLabel.setVerticalAlignment(JLabel.CENTER);
// imageLabel.setHorizontalAlignment(JLabel.CENTER);
setContent(imageLabel);
// this.setBorder(BorderFactory.createLineBorder(Color.black));
picture.setObserver(this);
history = new Vector<BufferedImage>();
}
/**
* Setzt das anzuzeigende Bild neu
* @param picture anzuzeigendes Bild
* @param saveOldImage soll das aktuelle Bild in der Historie gespeichert werden
*/
public void setImage(Picture picture, boolean saveOldImage) {
if (saveOldImage) pushImage();
this.picture = picture;
repaint();
}
/**
* Liefert das angezeigte Bild
* @return angezeigtes Bild
*/
public Picture getImage() {
return this.picture;
}
/**
* Erzeugt eine Kopie eines BufferedImage.
* @param Originalbild
* @return Kopie des Bildes
*/
private BufferedImage deepCopy(BufferedImage bi) {
ColorModel cm = bi.getColorModel();
boolean isAlphaPremultiplied = cm.isAlphaPremultiplied();
WritableRaster raster = bi.copyData(null);
return new BufferedImage(cm, raster, isAlphaPremultiplied, null).getSubimage(0, 0, bi.getWidth(), bi.getHeight());
}
/**
* 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);
}
history.add(deepCopy(picture.getImage()));
}
}
/**
* Ruft das letzte abgespeicherte Bild aus der History wieder auf.
*/
public void back() {
int anz = history.size();
if(anz>0) {
BufferedImage img = history.get(anz-1);
history.removeElementAt(anz-1);
picture.setImage(img);
repaint();
}
}
/**
* 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 = SwingFXUtils.toFXImage(picture.getImage(), null);
imageLabel.setFitWidth(width);
imageLabel.setFitHeight(height);
imageLabel.setImage(scrollImageIcon);
//new Image(picture.getImage().getScaledInstance(picture.getImage().getWidth(), picture.getImage().getHeight(), Image.SCALE_FAST));
// imageLabel = new ImageView(scrollImageIcon);
// 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();
}
}

View file

@ -0,0 +1,898 @@
package imp;
/**
* 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());
}
}
}
}

View file

@ -0,0 +1,319 @@
package imp;
/**
* 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));
}
}

View file

@ -0,0 +1,639 @@
package imp;
/**
* 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);}
}
}

View file

@ -0,0 +1,78 @@
#BlueJ package file
dependency1.from=PictureViewer
dependency1.to=Picture
dependency1.type=UsesDependency
dependency2.from=Picture
dependency2.to=PictureViewer
dependency2.type=UsesDependency
dependency3.from=Table
dependency3.to=TableRow
dependency3.type=UsesDependency
objectbench.height=84
objectbench.width=804
package.divider.horizontal=0.6
package.divider.vertical=0.818
package.editor.height=402
package.editor.width=714
package.editor.x=430
package.editor.y=27
package.frame.height=600
package.frame.width=844
package.numDependencies=3
package.numTargets=7
package.showExtends=true
package.showUses=true
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=PictureViewer
target1.showInterface=false
target1.type=ClassTarget
target1.width=110
target1.x=280
target1.y=310
target2.height=50
target2.name=NumberTextField
target2.showInterface=false
target2.type=ClassTarget
target2.width=130
target2.x=380
target2.y=70
target3.height=50
target3.name=Table
target3.showInterface=false
target3.type=ClassTarget
target3.width=80
target3.x=120
target3.y=110
target4.height=50
target4.name=HSB
target4.showInterface=false
target4.type=ClassTarget
target4.width=90
target4.x=40
target4.y=200
target5.height=50
target5.name=Picture
target5.showInterface=false
target5.type=ClassTarget
target5.width=80
target5.x=180
target5.y=250
target6.height=50
target6.name=XML
target6.showInterface=false
target6.type=ClassTarget
target6.width=80
target6.x=220
target6.y=130
target7.height=50
target7.name=TableRow
target7.showInterface=false
target7.type=ClassTarget
target7.width=90
target7.x=220
target7.y=60

View file

@ -0,0 +1,39 @@
#BlueJ package file
editor.fx.0.height=0
editor.fx.0.width=0
editor.fx.0.x=0
editor.fx.0.y=0
objectbench.height=93
objectbench.width=760
package.divider.horizontal=0.6
package.divider.vertical=0.8
package.editor.height=393
package.editor.width=670
package.editor.x=712
package.editor.y=240
package.frame.height=600
package.frame.width=800
package.numDependencies=0
package.numTargets=2
package.showExtends=true
package.showUses=true
project.charset=UTF-8
project.invoke.thread=FX
readme.height=58
readme.name=@README
readme.width=47
readme.x=10
readme.y=10
target1.height=50
target1.name=BildbearbeitungGUI
target1.showInterface=false
target1.type=ClassTarget
target1.width=150
target1.x=20
target1.y=90
target2.height=62
target2.name=imp
target2.type=PackageTarget
target2.width=80
target2.x=70
target2.y=10

View file

@ -0,0 +1,12 @@
Sollte es bei der Ausführung des Projekts zu folgender Fehlermeldung kommen:
java.lang.IllegalStateException: Toolkit not initialized
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:273)
at com.sun.javafx.application.PlatformImpl.runLater(PlatformImpl.java:268)
at javafx.application.Platform.runLater(Platform.java:83)
at bluej.runtime.ExecServer.runOnTargetThread(ExecServer.java:902)
at bluej.runtime.ExecServer.access$700(ExecServer.java:78)
at bluej.runtime.ExecServer$3.run(ExecServer.java:787)
dann lösen Sie das Problem, indem Sie entweder
a) die neuste BlueJ-Version installieren.
b) in BlueJ unter Werkzeuge->Einstellungen->Diverses->Run user code in this project on thread: "Default" wählen (BlueJ Version 4.1.2)

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,22 @@
void optionenAnzeigen(String fxmlFile) {
try { // try-catch ist notwendig, um Fehler durch fehlende Dateien abzufangen.
//
if(hauptbereich.getChildren().size()>1) {
viewer.back(); //
hauptbereich.getChildren().remove(1); //
}
//
FXMLLoader loader = new FXMLLoader(
getClass().getResource("view/"+fxmlFile));
loader.setController(this);
VBox filterFenster = (VBox) loader.load();
//
hauptbereich.getChildren().add(filterFenster);
}
catch(Exception e) {
System.out.println(e);
}
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,56 @@
/*--
$Id: LICENSE.txt,v 1.11 2004/02/06 09:32:57 jhunter Exp $
Copyright (C) 2000-2004 Jason Hunter & Brett McLaughlin.
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the disclaimer that follows
these conditions in the documentation and/or other materials
provided with the distribution.
3. The name "JDOM" must not be used to endorse or promote products
derived from this software without prior written permission. For
written permission, please contact <request_AT_jdom_DOT_org>.
4. Products derived from this software may not be called "JDOM", nor
may "JDOM" appear in their name, without prior written permission
from the JDOM Project Management <request_AT_jdom_DOT_org>.
In addition, we request (but do not require) that you include in the
end-user documentation provided with the redistribution and/or in the
software itself an acknowledgement equivalent to the following:
"This product includes software developed by the
JDOM Project (http://www.jdom.org/)."
Alternatively, the acknowledgment may be graphical using the logos
available at http://www.jdom.org/images/logos.
THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE JDOM AUTHORS OR THE PROJECT
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.
This software consists of voluntary contributions made by many
individuals on behalf of the JDOM Project and was originally
created by Jason Hunter <jhunter_AT_jdom_DOT_org> and
Brett McLaughlin <brett_AT_jdom_DOT_org>. For more information
on the JDOM Project, please see <http://www.jdom.org/>.
*/

Some files were not shown because too many files have changed in this diff Show more