At the moment, this is how my paintComponent looks:
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(choice);
if(choice == 1)
{
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
System.out.println("\nImgWidth: " + img.getWidth()
+ "\nFrameWidth: " + getWidth()
+ "\nImgHeight: " + img.getHeight()
+ "\nFrameHeight: " + getHeight()
);
}
else if (choice == 2)
{
scale = 3.0;
while(currScale < scale){
currScale += .1;
System.out.println(currScale + "-" + scale);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
int w = getWidth();
int h = getHeight();
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
double x = (w - currScale * imageWidth)/2;
double y = (h - currScale * imageHeight)/2;
AffineTransform at = AffineTransform.getTranslateInstance(x,y);
at.scale(currScale, currScale);
g2.drawRenderedImage(img, at);
try {
Thread.sleep(100);
} catch (InterruptedException ex) {}
}
}
}
The code works when I forget about looping and just use a fixed value for scale, but I want it to be animated instead of the immediate zoom. I've tried using a Timer alternative, but nothing shows up and the image just disappears the moment paintComponent is triggered and choice is 2.
With the sleep method, the scaled image shows up, but only till after the loop. Before and during the loop, it still shows the original full image. It runs like the whole point of the loop (to animate) was pointless as the change only happens when it exits .
Any help is appreciated.
Also if any of you wondered how I messed up with the timer, this was my code for it (it removed the original image and didn't display anything at all, but timer does terminate)
else
{
scale = 3.0;
timer = new Timer(500, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if(currScale < scale){
System.out.println(currScale + "-" + scale);
currScale += .1;
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
int w = getWidth();
int h = getHeight();
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
double x = (w - currScale * imageWidth)/2;
double y = (h - currScale * imageHeight)/2;
AffineTransform at = AffineTransform.getTranslateInstance(x,y);
at.scale(currScale, currScale);
g2.drawRenderedImage(img, at);
}
}
});
if(currScale > scale)
{
timer.stop();
}
else
{
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
}
This is the snippet of my class attributes:
class loadImage extends JPanel {
private int choice;
double scale;
double currScale = 1.0;
BufferedImage img;
//Timer timer; (if using the timer)
FIX: To add some context, I'm using Netbean's GUI-Builder. I choose to go the way of manually typecasting the panel to the loadImage class everytime I need to use loadImage's methods.
public void ZoomIn() {
double scale = 3.0;
double scaleAddOn = 0.1;
Timer timer;
timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e)
{
double currScale;
currScale = ((loadImage)imageArea).getCurrScale();
if(currScale < scale)
{
((loadImage)imageArea).setCurrScale(currScale + scaleAddOn);
}
}
});
if(((loadImage)imageArea).getCurrScale() > scale)
{
timer.stop();
}
else
{
timer.setRepeats(true);
timer.setCoalesce(true);
timer.start();
}
}
Thanks again for the help. Hopefully this page will be of use to others as well.
When you create a drawing panel from a JPanel, the paintComponent method paints or draws. Full stop. The paintComponent method does nothing else. No Thread.sleep. No calculations. Just draw.
Since you just provided a paintComponent method, I'm just providing the DrawingPanel class.
package com.ggl.testing;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import javax.swing.JPanel;
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 506794466435048661L;
private double currScale;
private int choice;
private BufferedImage img;
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
System.out.println(choice);
if (choice == 1) {
g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
System.out.println("\nImgWidth: " + img.getWidth()
+ "\nFrameWidth: " + getWidth() + "\nImgHeight: "
+ img.getHeight() + "\nFrameHeight: " + getHeight());
} else if (choice == 2) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
int w = getWidth();
int h = getHeight();
int imageWidth = img.getWidth();
int imageHeight = img.getHeight();
double x = (w - currScale * imageWidth) / 2;
double y = (h - currScale * imageHeight) / 2;
AffineTransform at = AffineTransform.getTranslateInstance(x, y);
System.out.println("Pass");
at.scale(currScale, currScale);
System.out.println("Pass");
g2.drawRenderedImage(img, at);
System.out.println("Pass");
}
}
public double getCurrScale() {
return currScale;
}
public void setCurrScale(double currScale) {
this.currScale = currScale;
repaint();
}
public int getChoice() {
return choice;
}
public void setChoice(int choice) {
this.choice = choice;
}
public BufferedImage getImg() {
return img;
}
public void setImg(BufferedImage img) {
this.img = img;
}
}
You can use a Runnable class or a Swing Timer to update the currScale value.