I've been trying to move, and display an image (e.g. heart rate image). Here is what I have so far. The image keeps moving to the left forvever; so far so good. But I need to embed this moving image inside another frame. I know my question seems very
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class HeartBeat extends JPanel{
public static void main(String[] args) throws Exception {
new HeartBeat();
}
public HeartBeat(){
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel j = new JPanel();
j.add(new HeartBeat2());
frame.add(j);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
class HeartBeat2 extends JPanel{
BufferedImage bi;
public HeartBeat2(){
try {
bi = ImageIO.read(new URL("http://i.stack.imgur.com/i8UJD.jpg"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
Runnable r = new Runnable() {
#Override
public void run() {
final BufferedImage canvas = new BufferedImage(
bi.getWidth(), bi.getHeight(),
BufferedImage.TYPE_INT_RGB);
final JLabel animationLabel = new JLabel(new ImageIcon(canvas));
ActionListener animator = new ActionListener() {
int x = 0;
#Override
public void actionPerformed(ActionEvent e) {
Graphics2D g = canvas.createGraphics();
// paint last part of image in left of canvas
g.drawImage(bi, x, 0, null);
// paint first part of image immediately to the right
g.drawImage(bi, x + bi.getWidth(), 0, null);
// reset x to prevent hitting integer overflow
if (x%bi.getWidth()==0) x = 0;
g.dispose();
animationLabel.repaint();
x--;
}
};
Timer timer = new Timer(40, animator);
timer.start();
JPanel j = new JPanel();
JOptionPane.showMessageDialog(null, animationLabel);
timer.stop();
}
};
// Swing GUIs should be created and updated on the EDT
// http://docs.oracle.com/javase/tutorial/uiswing/concurrency
SwingUtilities.invokeLater(r);
}
}}
The problem with the code is
The animationLabel is being added to the JOptionPane, but you never add it to the HeartBeat2
The JOptionPane.showMessageDialog is a blocking (modal) call, so it blocks any code occurring after it (i.e. timer.stop()). But if you remove that JOptionPane (to try and add the label to the panel) the timer.stop() will automatically be called (The timer is controlling the image/animation). And if you just leave the JOptionPane there, the adding the label to panel won't work, as each component can only have one parent
So you need to
First of all, completely strip out the Runnable. You don't need it.
Take out the JOptionPane, and simply add(animationLabel) to the HeartBeat2
Take out the timer.stop()
public HeartBeat2() {
try {
bi = ImageIO.read(new URL("http://i.stack.imgur.com/i8UJD.jpg"));
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
final BufferedImage canvas = new BufferedImage(
bi.getWidth(), bi.getHeight(),
BufferedImage.TYPE_INT_RGB);
final JLabel animationLabel = new JLabel(new ImageIcon(canvas));
add(animationLabel);
ActionListener animator = new ActionListener() {
int x = 0;
#Override
public void actionPerformed(ActionEvent e) {
Graphics2D g = canvas.createGraphics();
// paint last part of image in left of canvas
g.drawImage(bi, x, 0, null);
// paint first part of image immediately to the right
g.drawImage(bi, x + bi.getWidth(), 0, null);
// reset x to prevent hitting integer overflow
if (x % bi.getWidth() == 0) {
x = 0;
}
g.dispose();
animationLabel.repaint();
x--;
}
};
Timer timer = new Timer(40, animator);
timer.start();
}
Related
The Program use a rectangle in which a Ball can be caught from a JLabel with an Image.
The problem is in the Timer class, in which a counter counts, the time. While it counts the time is shown on a JLabel. But the Image that should catch the Ball, jumps every time to the start position, creating a tremble.
I tried to remove the JLabel and use instead System.out.println(), and it worked as well.
Perhaps the Swing Timer doesn't like calls for JLabel, what could be the cause?
SimpleDateFormat df = new SimpleDateFormat("mm:ss:SSS");
timeL.setText("Time :" + df.format(duration - clockTime));
//System.out.println("Time :" + df.format(duration - clockTime));
The Code was modified a bit, it works as expected, I hope it's correct.
Now the Image may be moved around independently of the Ball's Speed, and the Image stays at the moved position.
To add the Picture, add in the Project Folder a new Folder, named "resources". I tested it with Netbeans 8.2 .
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ImageMoveTest implements ActionListener {
JPanel panel;
Image rimg;
Thread t;
int x;
int y;
int v;
int z;
int n;
public static void main(String[] args) throws InterruptedException, IOException {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
try {
new ImageMoveTest().startApp();
} catch (InterruptedException ex) {
Logger.getLogger(ImageMoveTest.class.getName()).log(Level.SEVERE, null, ex);
} catch (IOException ex) {
Logger.getLogger(ImageMoveTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public void startApp() throws InterruptedException, IOException {
panel = new DrawPanel();
InputStream inStream = this.getClass().getClassLoader().getResourceAsStream("i6.jpeg");
BufferedImage img = ImageIO.read(inStream);
rimg = img.getScaledInstance(150, 150, Image.SCALE_SMOOTH);
MoveMouse mm = new MoveMouse();
panel.addMouseMotionListener((MouseMotionListener) mm);
JFrame f = new JFrame();
f.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE);
f.getContentPane().add(panel).setBackground(Color.white);
f.setSize(750, 750);
f.setResizable(false);
f.setVisible(true);
f.setLocationRelativeTo(null);
MathC mc = new MathC();
t = new Thread(mc);
t.start();
}
class MoveMouse extends JPanel implements MouseMotionListener {
#Override
public void mouseDragged(MouseEvent e) {
v=e.getX();
z=e.getY();
this.repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
class MathC implements Runnable {
#Override
public void run() {
while(true) {
// x,y here
x = (int) (Math.random() * panel.getWidth());
y = (int) (Math.random() * panel.getHeight());
panel.repaint();
try {
t.sleep(700);
} catch (InterruptedException ex) {
Logger.getLogger(ImageMoveTest.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
}
#Override
public void actionPerformed(ActionEvent e) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
class DrawPanel extends JPanel {
public void update(Graphics g) {
super.paintChildren(g);
}
public void paintChildren( Graphics g) {
super.paintChildren(g);
drawIt(g);
// repaint the backround to see the single circle moving
// draw the Ball
g.setColor(Color.red);
g.fillOval(x, y, 35, 35);
g.drawOval(x, y, 35, 35);
this.repaint();
}
public void drawIt(Graphics g) {
super.paintChildren(g);
// draw Rectangle
g.drawRect(0,0,this.getWidth(),this.getHeight());
// draw the Image
g.drawImage(rimg, v, z, this);
this.repaint();
}
}
}
I have written a small code for simple resizing of any image on my system in java using SWING.
http://ideone.com/9vii2E
import java.awt.Color;
import java.awt.FlowLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;
class T extends JPanel implements ActionListener {
/**
*
*/
private static final long serialVersionUID = -2900955352094956729L;
int x = 0;
int flag = 0;
BufferedImage b;
Image z;
JButton j, a, cl;
JTextField ht, wdth;
T() {
j = new JButton("Hi");
a = new JButton("Resizze");
a.addActionListener(this);
add(a);
j.addActionListener(this);
add(j);
setBackground(Color.WHITE);
}
class tobi implements ActionListener {// for close button of second window
public void actionPerformed(ActionEvent asd) {
// if(x==1)
{
int gadda = 100, w = 100;
gadda = Integer.parseInt(ht.getText());
w = Integer.parseInt(wdth.getText());
z = z.getScaledInstance(gadda, w, Image.SCALE_SMOOTH);
setBackground(Color.BLACK);
j.repaint();
JButton ttr = (JButton) asd.getSource();
Window qwe = SwingUtilities.windowForComponent(ttr);
qwe.setVisible(false);
}
}
}
public void meth()// method to create second window
{
JFrame win = new JFrame();
win.setTitle("resizze!!");
win.setLayout(new FlowLayout());
JLabel height = new JLabel("Height:");
ht = new JTextField(20);
JLabel width = new JLabel("Width:");
wdth = new JTextField(20);
JButton cl = new JButton("close");
cl.addActionListener(new tobi());
win.add(height);
win.add(ht);
win.add(width);
win.add(wdth);
win.add(cl);
win.pack();
win.setVisible(true);
}
public void paintComponent(Graphics g) {
Graphics2D gt = (Graphics2D) g;
super.paintComponent(g);
if (x == 1)
g.drawImage(z, 0, 0, null);
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() == j) {
JFileChooser q = new JFileChooser();
// q.setFileFilter(new
// FileNameExtensionFilter("Image Files",ImageIO.getReaderFileSuffixes()));
q.addChoosableFileFilter(new FileNameExtensionFilter("Image Files",
"jpg", "jpeg", "png"));
int option = q.showOpenDialog(null);
if (option == JFileChooser.APPROVE_OPTION) {
File f = q.getSelectedFile();
try {
b = ImageIO.read(f);
z = b.getScaledInstance(100, 100, Image.SCALE_SMOOTH);
} catch (IOException ae) {
}
}
x = 1;
repaint();
}
else if (e.getSource() == a) {
meth();
}
}
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable(){
public void run(){
JFrame j = new JFrame();
j.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
j.setSize(500, 500);
j.add(new T());
j.setVisible(true);
j.revalidate();
j.repaint();
}
});
}
}
I am asking user to upload the image file and then taking parameters height and width for resizing.
After clicking on close button in second window,nothing happens(except for first few times),while the image on first window should be repainted.
(Sorry for bad variable names and formatting)
You have a whole bunch of issues, variable naming only been one of them...
g.drawImage(z, 0, 0, null); should be g.drawImage(z, 0, 0, this);, this ensures that if the image is still be processed for some reason, the component can respond to any of it's changes and update schedule new repaints of it's own accord
Don't ignore exceptions
try {
b = ImageIO.read(f);
z = b.getScaledInstance(100, 100, Image.SCALE_SMOOTH);
} catch (IOException ae) {
}
should be (at the very least)
try {
b = ImageIO.read(f);
z = b.getScaledInstance(100, 100, Image.SCALE_SMOOTH);
} catch (IOException ae) {
ae.printStackTrace();
}
This will help you solve probable issues in your code.
I'd also change the above to
try {
b = ImageIO.read(f);
z = b;
} catch (IOException ae) {
ae.printStackTrace();
}
so you are presented with the original image first (this is just my opinion), but since you don't have any real scaling properties at this point, it makes sense to me.
You're shadowing the cl variable, declaring it as a instance field, but re-declaring it again as a local variable in meth. I don't if this will be an issue, but you need to be aware of it.
z = z.getScaledInstance(gadda, w, Image.SCALE_SMOOTH); should be z = b.getScaledInstance(gadda, w, Image.SCALE_SMOOTH);. You want to scale from the source, otherwise you are going to have a lot of pixelation issues.
You also calling j.repaint(); which is just repainting the button, which is clearly not what you want to do, instead you should just be calling repaint() on the panel itself
You should also have a look at The Perils of Image.getScaledInstance() and this example and this example for examples of how you might produce better scaling operations
I am building a desktop application in Java. I want to get the mouse coordinates of a mouse click relative to an image which is within a JSrollPane. The JScrollPane, screenScroll, is contained in a JPanel with a BorderLayout.
final JLabel screenLabel = new JLabel(new ImageIcon(image));
JScrollPane screenScroll = new JScrollPane(screenLabel);
screenScroll.getViewport().setBackground(Color.white);
screenLabel.addMouseListener(new MouseAdapter() {
#Override //I override only one method for presentation
public void mousePressed(MouseEvent e) {
System.out.println("Y'all clicked at: "+e.getX() + ", " + e.getY()+" in the image.");
}
});
So here's the problem: the JPanel is larger than the image and the JScrollPane is taking up 100% of the JPanel (which looks nice, I'm happy about that) but the mousePressed event is giving me the coordinates relative to the JScrollPane/JPanel, not the image so the x coordinate is offset (even though the mouseListener was add to the JLabel containing the ImageIcon).
Hope I explained that clearly. How can I modify above code to get coordinates relative to image?
Basically, it would be very hard to achieve this using a JLabel as the actual position of the image is determined by the JLabel's look and feel delegate. While you could create your own delegate, you would end up needing to create one for each supported platform and...I'm too lazy...
Instead, you could create a custom component and render the image the way you want. You would then be in a position to better ascertain the location of the image and convert the mouse point values you require, for example...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Point;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
BufferedImage img = ImageIO.read(new File("C:\\hold\\thumbnails\\MT015.jpg"));
final ImagePanel imgPane = new ImagePanel(img);
JScrollPane scrollPane = new JScrollPane(imgPane);
final JLabel report = new JLabel("...");
imgPane.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
Point panelPoint = e.getPoint();
Point imgContext = imgPane.toImageContext(panelPoint);
report.setText("You clicked at " + panelPoint + " which is relative to the image " + imgContext);
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(scrollPane);
frame.add(report, BorderLayout.SOUTH);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex);
}
}
});
}
public class ImagePanel extends JPanel {
private BufferedImage img;
public ImagePanel(BufferedImage img) {
this.img = img;
}
#Override
public Dimension getPreferredSize() {
return img == null ? super.getPreferredSize() : new Dimension(img.getWidth(), img.getHeight());
}
protected Point getImageLocation() {
Point p = null;
if (img != null) {
int x = (getWidth() - img.getWidth()) / 2;
int y = (getHeight() - img.getHeight()) / 2;
p = new Point(x, y);
}
return p;
}
public Point toImageContext(Point p) {
Point imgLocation = getImageLocation();
Point relative = new Point(p);
relative.x -= imgLocation.x;
relative.y -= imgLocation.y;
return relative;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Point p = getImageLocation();
g.drawImage(img, p.x, p.y, this);
}
}
}
}
Take a look at Performing Custom Painting and 2D Graphics for more details
I am trying to learn how to fade in and out images into another image or from another image. So, if I have 2 images, and 1 is being displayed at the moment, I want to display another image in the background and fade the first image out into the 2nd image. OR, I want to set the focus on the new image and slowly fade it in over the 1st image, then stop displaying the 1st one.
I'm not sure how:
to set focus, if even needed.
I can fade in if I change the alpha to 0 and increment up and only draw one image, however I cannot get it to fade out either with any variation of this code. (i.e. commenting out one image to draw).
Edit: Really, all I'm worried about is being able to have 2 images and make the image currently being displayed slowly disappear into the 2nd image. How that is accomplished doesn't need to be with this.
Here is a code sample I'm messing with:
import java.awt.AlphaComposite;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class FadeIn extends JPanel implements ActionListener {
private Image imagem;
private Image image2;
private Timer timer;
private float alpha = 1f;
public FadeIn() {
imagem = (new ImageIcon(getClass().getResource(
"/resources/1stImage.jpg"))).getImage();
image2 = (new ImageIcon(getClass().getResource(
"/resources/2ndImage.jpg"))).getImage();
timer = new Timer(20, this);
timer.start();
}
// here you define alpha 0f to 1f
public FadeIn(float alpha) {
imagem = (new ImageIcon(getClass().getResource(
"/resources/1stImage.jpg"))).getImage();
this.alpha = alpha;
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(imagem, 0, 0, 400, 300, null);
g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,
alpha));
g2d.drawImage(image2, 0, 0, 400, 300, null);
}
public static void main(String[] args) {
JFrame frame = new JFrame("Fade out");
frame.add(new FadeIn());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(420, 330);
// frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
alpha += -0.01f;
if (alpha <= 0) {
alpha = 0;
timer.stop();
}
repaint();
}
}
Basically, what this does is use the same alpha value, fading in from 0-1 and then using the same alpha, going from 1-0, allowing the two images to cross fade over each other...
The magic basically, happens in the paintComponent, where the image coming in using the alpha value and the outgoing image uses 1f - alpha.
Switching between the two images is actually a the same process, expect the inImage is swapped for the outImage
The timing is little different. Instead of a straight move from 0-1 using a standard delta (ie 0.01 for example), this uses a time based algorithm.
That is, I use a timer which ticks every 40 milliseconds or so, it then does a calculation based on the amount of time the timer has being running and calculates the alpha value accordingly...
This allows you to change the amount of time the animation will take, but also provides a slightly better algorithm that takes into account the passive nature of Swings rendering engine...
import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class FadeImage {
public static void main(String[] args) {
new FadeImage();
}
public FadeImage() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public static class TestPane extends JPanel {
public static final long RUNNING_TIME = 2000;
private BufferedImage inImage;
private BufferedImage outImage;
private float alpha = 0f;
private long startTime = -1;
public TestPane() {
try {
inImage = ImageIO.read(new File("/path/to/inImage"));
outImage = ImageIO.read(new File("/path/to/outImage"));
} catch (IOException exp) {
exp.printStackTrace();
}
final Timer timer = new Timer(40, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (startTime < 0) {
startTime = System.currentTimeMillis();
} else {
long time = System.currentTimeMillis();
long duration = time - startTime;
if (duration >= RUNNING_TIME) {
startTime = -1;
((Timer) e.getSource()).stop();
alpha = 0f;
} else {
alpha = 1f - ((float) duration / (float) RUNNING_TIME);
}
repaint();
}
}
});
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
alpha = 0f;
BufferedImage tmp = inImage;
inImage = outImage;
outImage = tmp;
timer.start();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(
Math.max(inImage.getWidth(), outImage.getWidth()),
Math.max(inImage.getHeight(), outImage.getHeight()));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));
int x = (getWidth() - inImage.getWidth()) / 2;
int y = (getHeight() - inImage.getHeight()) / 2;
g2d.drawImage(inImage, x, y, this);
g2d.setComposite(AlphaComposite.SrcOver.derive(1f - alpha));
x = (getWidth() - outImage.getWidth()) / 2;
y = (getHeight() - outImage.getHeight()) / 2;
g2d.drawImage(outImage, x, y, this);
g2d.dispose();
}
}
}
This is a easy and short most developers using java code for image fade.
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.awt.image.RescaleOp;
import java.io.File;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
/**
*
* #author ADMIN
*/
public class ImageFade extends JFrame {
ImageFade() {
setLayout(null);
JLabel l = new JLabel();
l.setBounds(0, 0, 100, 96);
add(l);
Thread tp = new Thread() {
#Override
public void run() {
for (int amp = 0; amp <= 500; amp++) {
try {
sleep(1);
try {
BufferedImage bim = ImageIO.read(new File("src/image/fade/image.png"));
BufferedImage nbim = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D createGraphics = nbim.createGraphics();
createGraphics.drawImage(bim, null, 0, 0);
RescaleOp r = new RescaleOp(new float[]{1f, 1f, 1f, (float) amp / 500}, new float[]{0, 0, 0, 0}, null);
BufferedImage filter = r.filter(nbim, null);
l.setIcon(new ImageIcon(filter));
} catch (Exception ex) {
System.err.println(ex);
}
} catch (InterruptedException ex) {
}
}
}
};
tp.start();
setUndecorated(true);
setBackground(new Color(0, 0, 0, 0));
setSize(100, 96);
setVisible(true);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
setAlwaysOnTop(true);
}
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
ImageFade fr = new ImageFade();
}
}
in this code you can see a thread code. in the thread this image will fade in.
the used image is stack overflow web page's logo image.
only by shown code the image will fade in.
Thread tp = new Thread() {
#Override
public void run() {
for (int amp = 0; amp <= 500; amp++) {
try {
sleep(1);
try {
BufferedImage bim = ImageIO.read(new File("src/image/fade/image.png"));
BufferedImage nbim = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D createGraphics = nbim.createGraphics();
createGraphics.drawImage(bim, null, 0, 0);
RescaleOp r = new RescaleOp(new float[]{1f, 1f, 1f, (float) amp / 500}, new float[]{0, 0, 0, 0}, null);
BufferedImage filter = r.filter(nbim, null);
l.setIcon(new ImageIcon(filter));
} catch (Exception ex) {
System.err.println(ex);
}
} catch (InterruptedException ex) {
}
}
}
};
tp.start();
This code is very simple to use.
This is not from any book, internet or etc. It is developed by me.
A normal image is not able to change alpha. By code : BufferedImage nbim = new BufferedImage(bim.getWidth(), bim.getHeight(), BufferedImage.TYPE_INT_ARGB); the image will convert to ARGB - Alpha, Red, Green, Blue (R,G,B,A) image.
So you can change the alpha of a image.
I've got an editor with lots of image thumbnails. I'd like a double-click on an image to display the full resolution image using a modal undecorated dialog. Ideally, this would be animated, to show the image zooming up to full resolution on the center of the screen, then any click would make the image go away, either zooming back out or fading away.
I'm not concerned with establishing an exact behavior, I just want something slick. I've found plenty of JavaScript examples for this, but is there anything built for Swing?
This piece of code does more or less the trick...
There is still a problem in the way I'm setting the dialog's location...
Hope it helps.
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class OpenImageZooming {
private static final int NB_STEPS = 30;
private static final long OPENING_TOTAL_DURATION = 3000;
public static void main(String[] args) {
OpenImageZooming me = new OpenImageZooming();
me.openImage(args[0]);
}
private JFrame frame;
private JDialog dialog;
private JPanelZooming panelZooming;
private void openImage(final String imagePath) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
frame = new JFrame();
frame.setTitle("Open image with zoom");
JPanel p = new JPanel(new BorderLayout());
p.add(new JLabel("click on button to display image"), BorderLayout.CENTER);
JButton button = new JButton("Display!");
frame.setContentPane(p);
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Thread t = new Thread() {
#Override
public void run() {
displayImaggeWithProgressiveZoom(imagePath);
}
};
t.start();
}
});
p.add(button, BorderLayout.SOUTH);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(300, 100);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
protected void displayImaggeWithProgressiveZoom(String imagePath) {
try {
final BufferedImage image = ImageIO.read(new File(imagePath));
for (int i = 0; i < NB_STEPS; i++) {
displayDialog(i, NB_STEPS, image);
Thread.sleep(OPENING_TOTAL_DURATION / NB_STEPS);
}
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private void displayDialog(final int i, final int nbSteps, final BufferedImage image) {
try {
SwingUtilities.invokeAndWait(new Runnable() {
public void run() {
if (dialog == null) {
dialog = new JDialog(frame);
dialog.setUndecorated(true);
dialog.setModal(false);
panelZooming = new JPanelZooming(image);
dialog.setContentPane(panelZooming);
dialog.setSize(0, 0);
dialog.setLocationRelativeTo(frame);
dialog.setVisible(true);
}
int w = (i + 1) * image.getWidth() / nbSteps;
int h = (i + 1) * image.getHeight() / nbSteps;
panelZooming.setScale((double) (i + 1) / nbSteps);
dialog.setSize(w, h);
dialog.setLocationRelativeTo(null);
}
});
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
#SuppressWarnings("serial")
public static class JPanelZooming extends JPanel {
private BufferedImage image;
private double scale = 1.0d;
public JPanelZooming(BufferedImage image) {
this.image = image;
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
AffineTransform at = g2.getTransform();
AffineTransform oldTransform = (AffineTransform) at.clone();
at.scale(scale, scale);
g2.setTransform(at);
g2.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
g2.setTransform(oldTransform);
}
public void setScale(double scale) {
this.scale = scale;
}
}
}
You can create a custom control that displays the image at the scale you want.
1) Create a BufferedImage from the image file you want using ImageIO.read(file) (you can also create it from an InputStream)
2) Extend the JComponent or Canvas class and overload the paint function to draw the animated image using Graphics.DrawImage() and set the width and height based on how long the window has been open. Set a timer or use another thread to repeatedly have the component redraw itself for however long you want the animation to play.
I haven't done much with customized modal dialogs (I mostly find them annoying), but you can use a JDialog and and your component to it.