parent
9d78686470
commit
bfc3c5b157
|
@ -11,6 +11,6 @@ Mit der Zechenmaschine können Schüler:innen ihre Programme von Anfang an mit
|
||||||
Visualisierungen und Interaktionen ausstatten, ohne sich mit der GUI Programmierung
|
Visualisierungen und Interaktionen ausstatten, ohne sich mit der GUI Programmierung
|
||||||
mit Java Swing auseinandersetzen zu müssen.
|
mit Java Swing auseinandersetzen zu müssen.
|
||||||
|
|
||||||
Die Bibliothek wurde sich stark on [Processing](https://processing.org),
|
Die Bibliothek wurde stark on [Processing](https://processing.org),
|
||||||
[Engine Alpha](https://engine-alpha.org) und [TigerJython](https://www.tigerjython.ch/de)
|
[Engine Alpha](https://engine-alpha.org) und [TigerJython](https://www.tigerjython.ch/de)
|
||||||
inspiriert.
|
inspiriert.
|
||||||
|
|
|
@ -9,6 +9,12 @@ public class ColorLayer extends Layer {
|
||||||
clear();
|
clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ColorLayer( int width, int height, Color color ) {
|
||||||
|
super(width, height);
|
||||||
|
this.background = color;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setSize( int width, int height ) {
|
public void setSize( int width, int height ) {
|
||||||
super.setSize(width, height);
|
super.setSize(width, height);
|
||||||
|
|
|
@ -8,8 +8,8 @@ public class Constants {
|
||||||
public static final String APP_NAME = "Zeichenmaschine";
|
public static final String APP_NAME = "Zeichenmaschine";
|
||||||
|
|
||||||
public static final int APP_VERSION_MAJ = 0;
|
public static final int APP_VERSION_MAJ = 0;
|
||||||
public static final int APP_VERSION_MIN = 1;
|
public static final int APP_VERSION_MIN = 0;
|
||||||
public static final int APP_VERSION_REV = 5;
|
public static final int APP_VERSION_REV = 8;
|
||||||
|
|
||||||
public static final String APP_VERSION = APP_VERSION_MAJ + "." + APP_VERSION_MIN + "." + APP_VERSION_REV;
|
public static final String APP_VERSION = APP_VERSION_MAJ + "." + APP_VERSION_MIN + "." + APP_VERSION_REV;
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,6 @@ public class ImageLayer extends Layer {
|
||||||
|
|
||||||
protected boolean redraw = true;
|
protected boolean redraw = true;
|
||||||
|
|
||||||
public ImageLayer() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public ImageLayer( String source ) {
|
public ImageLayer( String source ) {
|
||||||
image = ImageLoader.loadImage(source);
|
image = ImageLoader.loadImage(source);
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,9 +30,9 @@ public class Zeichenleinwand extends Canvas {
|
||||||
// Liste der Ebenen initialisieren und die Standardebenen einfügen
|
// Liste der Ebenen initialisieren und die Standardebenen einfügen
|
||||||
layers = new LinkedList<>();
|
layers = new LinkedList<>();
|
||||||
synchronized( layers ) {
|
synchronized( layers ) {
|
||||||
layers.add(new ColorLayer(Constants.STD_BACKGROUND));
|
layers.add(new ColorLayer(width, height, Constants.STD_BACKGROUND));
|
||||||
layers.add(new DrawingLayer());
|
layers.add(new DrawingLayer(width, height));
|
||||||
layers.add(new ShapesLayer());
|
layers.add(new ShapesLayer(width, height));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,6 +160,16 @@ public class Zeichenleinwand extends Canvas {
|
||||||
render();
|
render();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void draw( Graphics graphics ) {
|
||||||
|
Graphics2D g2d = (Graphics2D) graphics.create();
|
||||||
|
synchronized( layers ) {
|
||||||
|
for( Layer layer : layers ) {
|
||||||
|
layer.draw(g2d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
g2d.dispose();
|
||||||
|
}
|
||||||
|
|
||||||
public void render() {
|
public void render() {
|
||||||
if( getBufferStrategy() == null ) {
|
if( getBufferStrategy() == null ) {
|
||||||
allocateBuffer();
|
allocateBuffer();
|
||||||
|
@ -192,16 +202,6 @@ public class Zeichenleinwand extends Canvas {
|
||||||
// Repeat the rendering if the drawing buffer was lost
|
// Repeat the rendering if the drawing buffer was lost
|
||||||
} while( strategy.contentsLost() );
|
} while( strategy.contentsLost() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
Graphics2D g2d = (Graphics2D) g.create();
|
|
||||||
|
|
||||||
for( Layer layer : layers ) {
|
|
||||||
layer.draw(g2d);
|
|
||||||
}
|
|
||||||
|
|
||||||
g2d.dispose();
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,21 @@
|
||||||
package schule.ngb.zm;
|
package schule.ngb.zm;
|
||||||
|
|
||||||
import schule.ngb.zm.shapes.ShapesLayer;
|
import schule.ngb.zm.shapes.ShapesLayer;
|
||||||
|
import schule.ngb.zm.util.ImageLoader;
|
||||||
|
|
||||||
import javax.swing.*;
|
import javax.swing.*;
|
||||||
import javax.swing.event.MouseInputListener;
|
import javax.swing.event.MouseInputListener;
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
import java.awt.Color;
|
||||||
import java.awt.event.*;
|
import java.awt.event.*;
|
||||||
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.RescaleOp;
|
||||||
|
import java.io.File;
|
||||||
|
import java.io.IOException;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Hauptklasse der Zeichenmaschine.
|
* Hauptklasse der Zeichenmaschine.
|
||||||
*
|
* <p>
|
||||||
* Projekte der Zeichenmaschine sollten als Unterklasse implementiert werden.
|
* Projekte der Zeichenmaschine sollten als Unterklasse implementiert werden.
|
||||||
* Die Klasse übernimmt die Initialisierung eines Programmfensters und der
|
* Die Klasse übernimmt die Initialisierung eines Programmfensters und der
|
||||||
* nötigen Komponenten.
|
* nötigen Komponenten.
|
||||||
|
@ -25,6 +31,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
/*
|
/*
|
||||||
* Attributes to be accessed by subclasses.
|
* Attributes to be accessed by subclasses.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected Zeichenleinwand canvas;
|
protected Zeichenleinwand canvas;
|
||||||
|
|
||||||
protected ColorLayer background;
|
protected ColorLayer background;
|
||||||
|
@ -41,18 +48,24 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
|
|
||||||
protected double mouseX = 0.0, mouseY = 0.0, pmouseX = 0.0, pmouseY = 0.0;
|
protected double mouseX = 0.0, mouseY = 0.0, pmouseX = 0.0, pmouseY = 0.0;
|
||||||
|
|
||||||
protected int width = STD_WIDTH, height = STD_HEIGHT;
|
protected int width, height;
|
||||||
|
|
||||||
|
protected int screenWidth, screenHeight;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Interne Attribute zur Steuerung der Zeichenmaschine.
|
||||||
|
*/
|
||||||
|
|
||||||
private Object mouseLock = new Object();
|
private Object mouseLock = new Object();
|
||||||
|
|
||||||
private Object keyboardLock = new Object();
|
private Object keyboardLock = new Object();
|
||||||
|
|
||||||
/*
|
|
||||||
* Interne Attribute zur Steuerung der Zeichenamschine.
|
|
||||||
*/
|
|
||||||
//
|
|
||||||
private JFrame frame;
|
private JFrame frame;
|
||||||
|
|
||||||
|
private GraphicsEnvironment environment;
|
||||||
|
|
||||||
|
private GraphicsDevice displayDevice;
|
||||||
|
|
||||||
private boolean running = false, isDrawing = false, isUpdating = false;
|
private boolean running = false, isDrawing = false, isUpdating = false;
|
||||||
|
|
||||||
private int framesPerSecond;
|
private int framesPerSecond;
|
||||||
|
@ -61,6 +74,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
|
|
||||||
private boolean quitAfterTeardown = false, initialized = false;
|
private boolean quitAfterTeardown = false, initialized = false;
|
||||||
|
|
||||||
|
|
||||||
public Zeichenmaschine() {
|
public Zeichenmaschine() {
|
||||||
this(APP_NAME + " " + APP_VERSION);
|
this(APP_NAME + " " + APP_VERSION);
|
||||||
}
|
}
|
||||||
|
@ -73,20 +87,37 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
try {
|
try {
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
} catch( Exception e ) {
|
} catch( Exception e ) {
|
||||||
System.err.println("Error setting the look and feel.");
|
System.err.println("Error setting the look and feel: " + e.getMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
GraphicsEnvironment environment =
|
|
||||||
GraphicsEnvironment.getLocalGraphicsEnvironment();
|
// Looking for the screen currently holding the mouse pointer
|
||||||
GraphicsDevice displayDevice = environment.getDefaultScreenDevice();
|
// that will be used as the screen device for this Zeichenmaschine
|
||||||
|
java.awt.Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
|
||||||
|
environment = GraphicsEnvironment.getLocalGraphicsEnvironment();
|
||||||
|
GraphicsDevice[] devices = environment.getScreenDevices();
|
||||||
|
for( GraphicsDevice gd: devices ) {
|
||||||
|
if( gd.getDefaultConfiguration().getBounds().contains(mouseLoc) ) {
|
||||||
|
displayDevice = gd;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if( displayDevice == null ) {
|
||||||
|
displayDevice = environment.getDefaultScreenDevice();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
this.width = width;
|
||||||
|
this.height = height;
|
||||||
|
java.awt.Rectangle displayBounds = displayDevice.getDefaultConfiguration().getBounds();
|
||||||
|
this.screenWidth = (int)displayBounds.getWidth();
|
||||||
|
this.screenHeight = (int)displayBounds.getHeight();
|
||||||
|
|
||||||
|
|
||||||
frame = new JFrame(displayDevice.getDefaultConfiguration());
|
frame = new JFrame(displayDevice.getDefaultConfiguration());
|
||||||
frame.setTitle(title);
|
frame.setTitle(title);
|
||||||
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
frame.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
|
||||||
|
|
||||||
this.width = width;
|
|
||||||
this.height = height;
|
|
||||||
|
|
||||||
canvas = new Zeichenleinwand(width, height);
|
canvas = new Zeichenleinwand(width, height);
|
||||||
frame.add(canvas);
|
frame.add(canvas);
|
||||||
|
|
||||||
|
@ -96,6 +127,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
drawing = getDrawingLayer();
|
drawing = getDrawingLayer();
|
||||||
shapes = getShapesLayer();
|
shapes = getShapesLayer();
|
||||||
|
|
||||||
|
// TODO: When to call settings?
|
||||||
settings();
|
settings();
|
||||||
|
|
||||||
canvas.addMouseListener(this);
|
canvas.addMouseListener(this);
|
||||||
|
@ -114,9 +146,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
|
|
||||||
frame.pack();
|
frame.pack();
|
||||||
frame.setResizable(false);
|
frame.setResizable(false);
|
||||||
// TODO: Center on current display (not main display by default)
|
centerFrame();
|
||||||
// TODO: Position at current BlueJ windows if IN_BLUEJ
|
|
||||||
frame.setLocationRelativeTo(null);
|
|
||||||
frame.setVisible(true);
|
frame.setVisible(true);
|
||||||
|
|
||||||
canvas.allocateBuffer();
|
canvas.allocateBuffer();
|
||||||
|
@ -148,6 +178,19 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public final void centerFrame() {
|
||||||
|
// TODO: Center on current display (not main display by default)
|
||||||
|
// TODO: Position at current BlueJ windows if IN_BLUEJ
|
||||||
|
//frame.setLocationRelativeTo(null);
|
||||||
|
//frame.setLocationRelativeTo(displayDevice.getFullScreenWindow());
|
||||||
|
|
||||||
|
java.awt.Rectangle bounds = displayDevice.getDefaultConfiguration().getBounds();
|
||||||
|
frame.setLocation(
|
||||||
|
(int)(bounds.x + (screenWidth-frame.getWidth())/2.0),
|
||||||
|
(int)(bounds.y + (screenHeight-frame.getHeight())/2.0)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
public final void redraw() {
|
public final void redraw() {
|
||||||
canvas.render();
|
canvas.render();
|
||||||
//canvas.invalidate();
|
//canvas.invalidate();
|
||||||
|
@ -242,6 +285,64 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
framesPerSecond = pFramesPerSecond;
|
framesPerSecond = pFramesPerSecond;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void saveImage() {
|
||||||
|
JFileChooser jfc = new JFileChooser();
|
||||||
|
jfc.setFileSelectionMode(JFileChooser.FILES_AND_DIRECTORIES);
|
||||||
|
jfc.setMultiSelectionEnabled(false);
|
||||||
|
|
||||||
|
int status = jfc.showSaveDialog(frame);
|
||||||
|
if( status == JFileChooser.APPROVE_OPTION ) {
|
||||||
|
File outfile = jfc.getSelectedFile();
|
||||||
|
if( outfile.isDirectory() ) {
|
||||||
|
outfile = new File(outfile.getAbsolutePath() + File.separator + "zeichenmaschine.png");
|
||||||
|
}
|
||||||
|
saveImage(outfile.getAbsolutePath());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void saveImage( String filepath ) {
|
||||||
|
BufferedImage img = new BufferedImage(canvas.getWidth(),canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
|
Graphics2D g = img.createGraphics();
|
||||||
|
g.setColor(STD_BACKGROUND.getColor());
|
||||||
|
g.fillRect(0, 0, img.getWidth(), img.getHeight());
|
||||||
|
canvas.draw(g);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
try {
|
||||||
|
ImageLoader.saveImage(img, new File(filepath), true);
|
||||||
|
} catch ( IOException ex ) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ImageLayer snapshot() {
|
||||||
|
BufferedImage img = new BufferedImage(canvas.getWidth(),canvas.getHeight(), BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
|
Graphics2D g = img.createGraphics();
|
||||||
|
g.setColor(STD_BACKGROUND.getColor());
|
||||||
|
g.fillRect(0, 0, img.getWidth(), img.getHeight());
|
||||||
|
canvas.draw(g);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
/*
|
||||||
|
float factor = 0.8f;
|
||||||
|
float base = 255f * (1f - factor);
|
||||||
|
RescaleOp op = new RescaleOp(factor, base, null);
|
||||||
|
BufferedImage filteredImage
|
||||||
|
= new BufferedImage(img.getWidth(), img.getHeight(), img.getType());
|
||||||
|
op.filter(img, filteredImage);
|
||||||
|
*/
|
||||||
|
|
||||||
|
ImageLayer imgLayer = new ImageLayer(img);
|
||||||
|
if( canvas.getLayer(0) instanceof ColorLayer ) {
|
||||||
|
canvas.addLayer(1, imgLayer);
|
||||||
|
} else {
|
||||||
|
canvas.addLayer(0, imgLayer);
|
||||||
|
}
|
||||||
|
return imgLayer;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Methoden, die von Unterklassen überschrieben werden können / sollen.
|
* Methoden, die von Unterklassen überschrieben werden können / sollen.
|
||||||
*/
|
*/
|
||||||
|
@ -366,6 +467,7 @@ public class Zeichenmaschine extends Constants implements MouseInputListener, Ke
|
||||||
pmouseX = mouseX;
|
pmouseX = mouseX;
|
||||||
pmouseY = mouseY;
|
pmouseY = mouseY;
|
||||||
|
|
||||||
|
// TODO: Seems not right ...
|
||||||
java.awt.Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
|
java.awt.Point mouseLoc = MouseInfo.getPointerInfo().getLocation();
|
||||||
java.awt.Point compLoc = canvas.getLocationOnScreen();
|
java.awt.Point compLoc = canvas.getLocationOnScreen();
|
||||||
mouseX = mouseLoc.x - compLoc.x;
|
mouseX = mouseLoc.x - compLoc.x;
|
||||||
|
|
|
@ -121,7 +121,7 @@ public abstract class Shape extends FilledShape {
|
||||||
* Bestimmt den Ankerpunkt der Form relativ zur oberen linken Ecke und
|
* Bestimmt den Ankerpunkt der Form relativ zur oberen linken Ecke und
|
||||||
* abhängig vom gesetzten {@link #setAnchor(Options.Direction) Anker}.
|
* abhängig vom gesetzten {@link #setAnchor(Options.Direction) Anker}.
|
||||||
*/
|
*/
|
||||||
public Point2D.Double getAnchorPoint() {
|
public Point2D.Double getAnchorPoint( Options.Direction anchor ) {
|
||||||
Point2D.Double anchorpoint = new Point2D.Double(0, 0);
|
Point2D.Double anchorpoint = new Point2D.Double(0, 0);
|
||||||
|
|
||||||
double bHalf = getWidth() * .5, hHalf = getHeight() * .5;
|
double bHalf = getWidth() * .5, hHalf = getHeight() * .5;
|
||||||
|
@ -203,18 +203,36 @@ public abstract class Shape extends FilledShape {
|
||||||
this.rotation = angle % 360;
|
this.rotation = angle % 360;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void rotate( Point2D center, double angle ) {
|
||||||
|
rotate(center.getX(), center.getY(), angle);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void rotate( double x, double y, double angle ) {
|
||||||
|
this.rotation += angle % 360;
|
||||||
|
|
||||||
|
// Rotate x/y position
|
||||||
|
double x1 = this.x-x, y1 = this.y-y;
|
||||||
|
|
||||||
|
double rad = Math.toRadians(angle);
|
||||||
|
double x2 = x1 * Math.cos(rad) - y1 * Math.sin(rad);
|
||||||
|
double y2 = x1 * Math.sin(rad) + y1 * Math.cos(rad);
|
||||||
|
|
||||||
|
this.x = x2 + x;
|
||||||
|
this.y = y2 + y;
|
||||||
|
}
|
||||||
|
|
||||||
/*public void shear( double dx, double dy ) {
|
/*public void shear( double dx, double dy ) {
|
||||||
verzerrung.shear(dx, dy);
|
verzerrung.shear(dx, dy);
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
public AffineTransform getTransform() {
|
public AffineTransform getTransform() {
|
||||||
Point2D.Double anchor = getAnchorPoint();
|
Point2D.Double anchorPoint = getAnchorPoint(this.anchor);
|
||||||
|
|
||||||
AffineTransform transform = new AffineTransform();
|
AffineTransform transform = new AffineTransform();
|
||||||
transform.translate(x, y);
|
transform.translate(x, y);
|
||||||
transform.rotate(Math.toRadians(rotation));
|
transform.rotate(Math.toRadians(rotation));
|
||||||
//transform.scale(scale, scale);
|
//transform.scale(scale, scale);
|
||||||
transform.translate(-anchor.x, -anchor.y);
|
transform.translate(-anchorPoint.x, -anchorPoint.y);
|
||||||
return transform;
|
return transform;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,11 @@
|
||||||
package schule.ngb.zm.util;
|
package schule.ngb.zm.util;
|
||||||
|
|
||||||
import javax.imageio.ImageIO;
|
import javax.imageio.ImageIO;
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.awt.Graphics2D;
|
||||||
|
import java.awt.Image;
|
||||||
import java.awt.image.BufferedImage;
|
import java.awt.image.BufferedImage;
|
||||||
|
import java.awt.image.RenderedImage;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.net.URL;
|
import java.net.URL;
|
||||||
|
@ -138,4 +142,45 @@ public class ImageLoader {
|
||||||
cacheing = false;
|
cacheing = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public static void saveImage( Image image, File file ) throws IOException {
|
||||||
|
saveImage(image, file, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveImage( Image image, File file, boolean overwriteIfExists ) throws IOException {
|
||||||
|
BufferedImage outimage = new BufferedImage(image.getWidth(null), image.getHeight(null), BufferedImage.TYPE_INT_RGB);
|
||||||
|
|
||||||
|
Graphics2D g = outimage.createGraphics();
|
||||||
|
g.setColor(Color.WHITE);
|
||||||
|
g.fillRect(0, 0, outimage.getWidth(), outimage.getHeight());
|
||||||
|
g.drawImage(image, 0, 0, null);
|
||||||
|
g.dispose();
|
||||||
|
|
||||||
|
saveImage(outimage, file, overwriteIfExists);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveImage( BufferedImage image, File file ) throws IOException {
|
||||||
|
saveImage(image, file, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void saveImage( BufferedImage image, File file, boolean overwriteIfExists ) throws IOException {
|
||||||
|
if( file.isFile() ) {
|
||||||
|
if( !overwriteIfExists ) {
|
||||||
|
throw new IOException("File already exists. Delete target file before saving image.");
|
||||||
|
} else if( !file.canWrite() ) {
|
||||||
|
throw new IOException("File already exists and is not writeable. Change permissions before saving again.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String filename = file.getName();
|
||||||
|
String formatName = "png";
|
||||||
|
if( filename.lastIndexOf('.') >= 0 ) {
|
||||||
|
formatName = filename.substring(filename.lastIndexOf('.') + 1);
|
||||||
|
} else {
|
||||||
|
file = new File(file.getAbsolutePath() + ".png");
|
||||||
|
}
|
||||||
|
|
||||||
|
ImageIO.write(image, formatName, file);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue