Graphics.drawImage von unten nach oben abbilden lassen

mmhhh

Mitglied
Hallo, ich möchte mit der Graphics.drawImage() methode ein bild abbilden lassen, die schwierigkeit ist nur, das es von unten nach oben abgebildet werden soll, also wie eine flüsigkeits anzeige, die sich füllt, wie kann ich das machen?
 
Da gibt's mehrere Möglichkeiten. Das Prinzip des Zeichnes unter Swing ist verstanden, Threads, Timer o.ä. ein Begriff?
Die m.M. einfachste Möglichkeit ist, das Bild immer ganz zu zeichnen, um dann anschließend mit einem Rechteck in der Hintergrundfarbe das Bild zu verdecken. Im Timer/Thread wird die Höhe des Rechtecks immer weiter reduziert und ein repaint() der Komponente aufgerufen.
 
Am geeignetsten ist wohl die Einschränkung des Zeichenbereichs (Clip). So könnte man das machen:
Java:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.net.URL;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.ExecutionException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;

public class PartialImagePanel extends JPanel implements PropertyChangeListener {
	public static enum Orientation {
		HORIZONTAL, VERTICAL;
	}
	
	public static enum Direction {
		BACKWARD, FORWARD;
	}
	
	private Orientation orientation = Orientation.HORIZONTAL;
	private Direction direction = Direction.FORWARD;
	private Image img;
	private int i;
	
	@Override
	protected void paintComponent(final Graphics g) {
		super.paintComponent(g);
		if (img != null) {
			final Graphics2D g2 = (Graphics2D) g.create();
			final Rectangle clip = g2.getClipBounds();
			switch (orientation) {
				case HORIZONTAL:
					final int imgWidth = img.getWidth(null);
					final int clipWidth = clip.x + imgWidth;
					switch (direction) {
						case BACKWARD:
							g2.setClip((int) ((1 - i/100d) * clipWidth), clip.y, clipWidth, clip.y + clip.height);
							break;
						case FORWARD:
							g2.setClip(clip.x, clip.y, (int) (i/100d * clipWidth), clip.y + clip.height);
							break;
					}
					break;
				case VERTICAL:
					final int imgHeight = img.getHeight(null);
					final int clipHeight = clip.y + imgHeight;
					switch (direction) {
						case BACKWARD:
							g2.setClip(clip.x, (int) ((1 - i/100d) * clipHeight), clip.x + clip.width, clipHeight);
							break;
						case FORWARD:
							g2.setClip(clip.x, clip.y, clip.x + clip.width, (int) (i/100d * clipHeight));
							break;
					}
					break;
			}
			g2.drawImage(img, 0, 0, null);
			g2.dispose();
		}
		g.drawString(String.format("%d %%", i), 0, getHeight());
	}

	public void setImg(final Image img) {
		this.img = img;
		repaint();
	}

	private void setI(final int i) {
		this.i = i;
		repaint();
	}
	
	public void setOrientation(final Orientation orientation) {
		this.orientation = orientation;
		repaint();
	}
	
	public void setDirection(final Direction direction) {
		this.direction = direction;
		repaint();
	}

	@Override
	public void propertyChange(final PropertyChangeEvent evt) {
		if (evt.getPropertyName().equals("progress")) {
			setI((Integer) evt.getNewValue());
		}
	}
	
	public static void main(String[] args) {
		SwingUtilities.invokeLater(new Runnable() {
			@Override
			public void run() {
				final JFrame frame = new JFrame();
				final PartialImagePanel panel = new PartialImagePanel();
				panel.setBackground(Color.WHITE);
				panel.setOrientation(Orientation.VERTICAL);
				panel.setDirection(Direction.BACKWARD);
				frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
				frame.setContentPane(panel);
				final SwingWorker<Void, Void> imgAnimator = new SwingWorker<Void, Void>() {
					private final Timer counter = new Timer();
					
					@Override
					protected Void doInBackground() throws Exception {
						counter.schedule(new TimerTask() {
							private int count;
							
							@Override
							public void run() {
								setProgress(++count);
								if (count >= 100) {
									counter.cancel();
								}
							}
						}, 0, 50);
						return null;
					}
				};
				imgAnimator.addPropertyChangeListener(panel);
				final SwingWorker<BufferedImage, Void> imgLoader = new SwingWorker<BufferedImage, Void>() {
					@Override
					protected BufferedImage doInBackground() throws Exception {
						return ImageIO.read(new URL("http://www.java-forum.org/images/misc/java_forum_org.gif"));
					}

					@Override
					protected void done() {
						try {
							panel.setImg(get());
							imgAnimator.execute();
						} catch (final ExecutionException | InterruptedException ex) {
							throw new RuntimeException(ex);
						}
					}
				};
				frame.setSize(600, 200);
				frame.setLocationRelativeTo(null);
				frame.setVisible(true);
				imgLoader.execute();
			}
		});
	}
}
[EDIT]Orientierung und Richtung für mehr Flexibilität hinzugefügt.[/EDIT]
 
Zuletzt bearbeitet:

Neue Themen


Zurück
Oben