Swing窗口关闭动态效果的实现

时间:2023-02-10 13:58:17
Swing无所不能,本例实现了Swing窗口关闭动态效果
Swing窗口关闭动态效果的实现
package animation;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class WindowClosingAnimation extends JPanel {
public WindowClosingAnimation() {
setLayout(new BorderLayout());
add(new JLabel("测试窗口关闭效果", SwingConstants.CENTER), BorderLayout.CENTER);
}

private static void createAndShowGUI() {
JFrame.setDefaultLookAndFeelDecorated(true);
try {
UIManager.setLookAndFeel("com.han.gen.GenLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

JFrame jFrame = new JFrame();
jFrame.setContentPane(new WindowClosingAnimation());
jFrame.setSize(300, 200);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);

// Choose "true" or "false" to see the difference
setWindowClosingAnimated(true, jFrame);
}

private static void setWindowClosingAnimated(boolean animated, JFrame jFrame) {
if (animated) {
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowClosingAnimationToJFrame(jFrame);
} else {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

private static void addWindowClosingAnimationToJFrame(JFrame jFrame) {
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
windowClosingAnimation(jFrame);
}
});
}

private static void windowClosingAnimation(JFrame jFrame) {
BufferedImage image = new BufferedImage(jFrame.getWidth(),
jFrame.getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
jFrame.paint(g);
g.dispose();

JWindow jWindow = new JWindow() {
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), 0, 0,
image.getWidth(), image.getHeight(), this);
}
};
jWindow.setBounds(jFrame.getBounds());
jFrame.setVisible(false);
jWindow.setVisible(true);

new Thread(new Runnable() {
@Override
public void run() {
final int indent = 20;
for (;;) {
Rectangle bounds = jWindow.getBounds();
bounds.x += indent / 2;
bounds.y += indent / 2;
bounds.width -= indent;
bounds.height -= indent;
if (bounds.width < 0 || bounds.height < 0) {
System.exit(0);
} else {
jWindow.setBounds(bounds.x, bounds.y, bounds.width,
bounds.height);// will call repaint()
}
try {
Thread.sleep(15);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}).start();
}

public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}

6 个解决方案

#1


想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer

#2


引用 1 楼 raistlic 的回复:
想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer
哦,线程怎么错了啊?求指出,为什么要用Timer呢

#3


引用 1 楼 raistlic 的回复:
想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer

哦,我看了Timer的API。就是在EDT中执行了。觉得应该用Timer。修改后的代码如下,还望检查:
package animation;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class WindowClosingAnimation extends JPanel {
/**
 * Specifies the content pane.
 */
public WindowClosingAnimation() {
setLayout(new BorderLayout());
add(new JLabel("测试窗口关闭效果", SwingConstants.CENTER), BorderLayout.CENTER);
}

private static void createAndShowGUI() {
/* Specifies the L&F using its own JFrame decorations */
JFrame.setDefaultLookAndFeelDecorated(true);
try {
UIManager.setLookAndFeel("com.han.gen.GenLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

/* Creates a JFrame object and shows it */
JFrame jFrame = new JFrame();
jFrame.setContentPane(new WindowClosingAnimation());
jFrame.setSize(300, 200);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);

// Choose "true" or "false" to see the difference
setWindowClosingAnimated(true, jFrame);
}

private static void setWindowClosingAnimated(boolean animated, JFrame jFrame) {
if (animated) {
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowClosingAnimationToJFrame(jFrame);
} else {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

private static void addWindowClosingAnimationToJFrame(JFrame jFrame) {
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
windowClosingAnimation(jFrame);
}
});
}

private static void windowClosingAnimation(JFrame jFrame) {
/* Firstly stores the bounds of our JFrame object to be closed as final */
final Rectangle bounds = jFrame.getBounds();

/* Captured the entire JFrame image */
BufferedImage image = new BufferedImage(bounds.width, bounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
jFrame.paint(g);
g.dispose();

/*
 * Creates a new JWindow object to show the captured image, and at the
 * same time hides the JFrame object.
 */
JWindow jWindow = new JWindow() {
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
};
jWindow.setBounds(bounds);
jFrame.setVisible(false);
jWindow.setVisible(true);

/* Uses a Timer to perform the size variation of JWindow */
int delay = 15; // milliseconds
final int indent = 20;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// ...Perform a task...
Rectangle bounds = jWindow.getBounds();
bounds.x += indent / 2;
bounds.y += indent / 2;
bounds.width -= indent;
bounds.height -= indent;
if (bounds.width < 0 || bounds.height < 0) {
System.exit(0);
} else {
jWindow.setBounds(bounds);// will call repaint()
}
}
};
new Timer(delay, taskPerformer).start();
}

public static void main(String[] args) {
// To make sure that the GUI creation happens on the EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}

#4


引用 3 楼 u014742479 的回复:
Quote: 引用 1 楼 raistlic 的回复:

想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer

哦,我看了Timer的API。就是在EDT中执行了。觉得应该用Timer。修改后的代码如下,还望检查:
package animation;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class WindowClosingAnimation extends JPanel {
/**
 * Specifies the content pane.
 */
public WindowClosingAnimation() {
setLayout(new BorderLayout());
add(new JLabel("测试窗口关闭效果", SwingConstants.CENTER), BorderLayout.CENTER);
}

private static void createAndShowGUI() {
/* Specifies the L&F using its own JFrame decorations */
JFrame.setDefaultLookAndFeelDecorated(true);
try {
UIManager.setLookAndFeel("com.han.gen.GenLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

/* Creates a JFrame object and shows it */
JFrame jFrame = new JFrame();
jFrame.setContentPane(new WindowClosingAnimation());
jFrame.setSize(300, 200);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);

// Choose "true" or "false" to see the difference
setWindowClosingAnimated(true, jFrame);
}

private static void setWindowClosingAnimated(boolean animated, JFrame jFrame) {
if (animated) {
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowClosingAnimationToJFrame(jFrame);
} else {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

private static void addWindowClosingAnimationToJFrame(JFrame jFrame) {
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
windowClosingAnimation(jFrame);
}
});
}

private static void windowClosingAnimation(JFrame jFrame) {
/* Firstly stores the bounds of our JFrame object to be closed as final */
final Rectangle bounds = jFrame.getBounds();

/* Captured the entire JFrame image */
BufferedImage image = new BufferedImage(bounds.width, bounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
jFrame.paint(g);
g.dispose();

/*
 * Creates a new JWindow object to show the captured image, and at the
 * same time hides the JFrame object.
 */
JWindow jWindow = new JWindow() {
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
};
jWindow.setBounds(bounds);
jFrame.setVisible(false);
jWindow.setVisible(true);

/* Uses a Timer to perform the size variation of JWindow */
int delay = 15; // milliseconds
final int indent = 20;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// ...Perform a task...
Rectangle bounds = jWindow.getBounds();
bounds.x += indent / 2;
bounds.y += indent / 2;
bounds.width -= indent;
bounds.height -= indent;
if (bounds.width < 0 || bounds.height < 0) {
System.exit(0);
} else {
jWindow.setBounds(bounds);// will call repaint()
}
}
};
new Timer(delay, taskPerformer).start();
}

public static void main(String[] args) {
// To make sure that the GUI creation happens on the EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}



Swing窗口关闭动态效果的实现

#5


可以控制更多窗口关闭时的动态效果,比如窗口旋转变形、淡入淡出、大小缩放等:
package animation;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class WindowClosingAnimation extends JPanel {
static float alpha = 1.0f;
static double shx = 0.0;

/**
 * Specifies the content pane.
 */
public WindowClosingAnimation() {
setLayout(new BorderLayout());
add(new JLabel("测试窗口关闭效果", SwingConstants.CENTER), BorderLayout.CENTER);
}

private static void createAndShowGUI() {
/* Specifies the L&F using its own JFrame decorations */
JFrame.setDefaultLookAndFeelDecorated(true);
try {
UIManager.setLookAndFeel("com.han.gen.GenLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

/* Creates a JFrame object and shows it */
JFrame jFrame = new JFrame();
jFrame.setContentPane(new WindowClosingAnimation());
jFrame.setSize(300, 200);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);

// Choose "true" or "false" to see the difference
setWindowClosingAnimated(true, jFrame);
}

private static void setWindowClosingAnimated(boolean animated, JFrame jFrame) {
if (animated) {
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowClosingAnimationToJFrame(jFrame);
} else {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

private static void addWindowClosingAnimationToJFrame(JFrame jFrame) {
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
windowClosingAnimation(jFrame);
}
});
}

private static void windowClosingAnimation(JFrame jFrame) {
/* Firstly stores the bounds of our JFrame object to be closed as final */
final Rectangle bounds = jFrame.getBounds();

/* Captured the entire JFrame image */
BufferedImage image = new BufferedImage(bounds.width, bounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
jFrame.paint(g);
g.dispose();

/*
 * Creates a new JWindow object to show the captured image, and at the
 * same time hides the JFrame object.
 */
JWindow jWindow = new JWindow() {
@Override
public void paint(Graphics g) {
super.paint(g);// important to call to have transparency
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha));
g2.shear(shx, 0);
g2.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
};
jWindow.setBounds(bounds);
jFrame.setVisible(false);
jWindow.setVisible(true);

/* Uses a Timer to perform the size variation of JWindow */
int delay = 30; // milliseconds
final int indent = 20;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// ...Perform a task...
alpha -= 0.1;
shx += 0.01;
Rectangle bounds = jWindow.getBounds();
bounds.x += indent / 2;
bounds.y += indent / 2;
bounds.width -= indent;
bounds.height -= indent;
if (shx > 0.1 || alpha < 0 || bounds.width < 0
|| bounds.height < 0) {
System.exit(0);
} else {
jWindow.setBounds(bounds);// will call repaint()
}
}
};
new Timer(delay, taskPerformer).start();
}

public static void main(String[] args) {
// To make sure that the GUI creation happens on the EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}

#6


该回复于2014-09-22 08:50:34被管理员删除

#1


想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer

#2


引用 1 楼 raistlic 的回复:
想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer
哦,线程怎么错了啊?求指出,为什么要用Timer呢

#3


引用 1 楼 raistlic 的回复:
想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer

哦,我看了Timer的API。就是在EDT中执行了。觉得应该用Timer。修改后的代码如下,还望检查:
package animation;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class WindowClosingAnimation extends JPanel {
/**
 * Specifies the content pane.
 */
public WindowClosingAnimation() {
setLayout(new BorderLayout());
add(new JLabel("测试窗口关闭效果", SwingConstants.CENTER), BorderLayout.CENTER);
}

private static void createAndShowGUI() {
/* Specifies the L&F using its own JFrame decorations */
JFrame.setDefaultLookAndFeelDecorated(true);
try {
UIManager.setLookAndFeel("com.han.gen.GenLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

/* Creates a JFrame object and shows it */
JFrame jFrame = new JFrame();
jFrame.setContentPane(new WindowClosingAnimation());
jFrame.setSize(300, 200);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);

// Choose "true" or "false" to see the difference
setWindowClosingAnimated(true, jFrame);
}

private static void setWindowClosingAnimated(boolean animated, JFrame jFrame) {
if (animated) {
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowClosingAnimationToJFrame(jFrame);
} else {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

private static void addWindowClosingAnimationToJFrame(JFrame jFrame) {
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
windowClosingAnimation(jFrame);
}
});
}

private static void windowClosingAnimation(JFrame jFrame) {
/* Firstly stores the bounds of our JFrame object to be closed as final */
final Rectangle bounds = jFrame.getBounds();

/* Captured the entire JFrame image */
BufferedImage image = new BufferedImage(bounds.width, bounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
jFrame.paint(g);
g.dispose();

/*
 * Creates a new JWindow object to show the captured image, and at the
 * same time hides the JFrame object.
 */
JWindow jWindow = new JWindow() {
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
};
jWindow.setBounds(bounds);
jFrame.setVisible(false);
jWindow.setVisible(true);

/* Uses a Timer to perform the size variation of JWindow */
int delay = 15; // milliseconds
final int indent = 20;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// ...Perform a task...
Rectangle bounds = jWindow.getBounds();
bounds.x += indent / 2;
bounds.y += indent / 2;
bounds.width -= indent;
bounds.height -= indent;
if (bounds.width < 0 || bounds.height < 0) {
System.exit(0);
} else {
jWindow.setBounds(bounds);// will call repaint()
}
}
};
new Timer(delay, taskPerformer).start();
}

public static void main(String[] args) {
// To make sure that the GUI creation happens on the EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}

#4


引用 3 楼 u014742479 的回复:
Quote: 引用 1 楼 raistlic 的回复:

想法挺好的,线程错了。

用 Thread 那部分想办法改成用 javax.swing.Timer

哦,我看了Timer的API。就是在EDT中执行了。觉得应该用Timer。修改后的代码如下,还望检查:
package animation;

import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class WindowClosingAnimation extends JPanel {
/**
 * Specifies the content pane.
 */
public WindowClosingAnimation() {
setLayout(new BorderLayout());
add(new JLabel("测试窗口关闭效果", SwingConstants.CENTER), BorderLayout.CENTER);
}

private static void createAndShowGUI() {
/* Specifies the L&F using its own JFrame decorations */
JFrame.setDefaultLookAndFeelDecorated(true);
try {
UIManager.setLookAndFeel("com.han.gen.GenLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

/* Creates a JFrame object and shows it */
JFrame jFrame = new JFrame();
jFrame.setContentPane(new WindowClosingAnimation());
jFrame.setSize(300, 200);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);

// Choose "true" or "false" to see the difference
setWindowClosingAnimated(true, jFrame);
}

private static void setWindowClosingAnimated(boolean animated, JFrame jFrame) {
if (animated) {
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowClosingAnimationToJFrame(jFrame);
} else {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

private static void addWindowClosingAnimationToJFrame(JFrame jFrame) {
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
windowClosingAnimation(jFrame);
}
});
}

private static void windowClosingAnimation(JFrame jFrame) {
/* Firstly stores the bounds of our JFrame object to be closed as final */
final Rectangle bounds = jFrame.getBounds();

/* Captured the entire JFrame image */
BufferedImage image = new BufferedImage(bounds.width, bounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
jFrame.paint(g);
g.dispose();

/*
 * Creates a new JWindow object to show the captured image, and at the
 * same time hides the JFrame object.
 */
JWindow jWindow = new JWindow() {
@Override
public void paint(Graphics g) {
super.paint(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
};
jWindow.setBounds(bounds);
jFrame.setVisible(false);
jWindow.setVisible(true);

/* Uses a Timer to perform the size variation of JWindow */
int delay = 15; // milliseconds
final int indent = 20;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// ...Perform a task...
Rectangle bounds = jWindow.getBounds();
bounds.x += indent / 2;
bounds.y += indent / 2;
bounds.width -= indent;
bounds.height -= indent;
if (bounds.width < 0 || bounds.height < 0) {
System.exit(0);
} else {
jWindow.setBounds(bounds);// will call repaint()
}
}
};
new Timer(delay, taskPerformer).start();
}

public static void main(String[] args) {
// To make sure that the GUI creation happens on the EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}



Swing窗口关闭动态效果的实现

#5


可以控制更多窗口关闭时的动态效果,比如窗口旋转变形、淡入淡出、大小缩放等:
package animation;

import java.awt.AlphaComposite;
import java.awt.BorderLayout;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.image.BufferedImage;

import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
import javax.swing.SwingConstants;
import javax.swing.SwingUtilities;
import javax.swing.Timer;
import javax.swing.UIManager;

@SuppressWarnings("serial")
public class WindowClosingAnimation extends JPanel {
static float alpha = 1.0f;
static double shx = 0.0;

/**
 * Specifies the content pane.
 */
public WindowClosingAnimation() {
setLayout(new BorderLayout());
add(new JLabel("测试窗口关闭效果", SwingConstants.CENTER), BorderLayout.CENTER);
}

private static void createAndShowGUI() {
/* Specifies the L&F using its own JFrame decorations */
JFrame.setDefaultLookAndFeelDecorated(true);
try {
UIManager.setLookAndFeel("com.han.gen.GenLookAndFeel");
} catch (Exception e) {
e.printStackTrace();
}

/* Creates a JFrame object and shows it */
JFrame jFrame = new JFrame();
jFrame.setContentPane(new WindowClosingAnimation());
jFrame.setSize(300, 200);
jFrame.setLocationRelativeTo(null);
jFrame.setVisible(true);

// Choose "true" or "false" to see the difference
setWindowClosingAnimated(true, jFrame);
}

private static void setWindowClosingAnimated(boolean animated, JFrame jFrame) {
if (animated) {
jFrame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
addWindowClosingAnimationToJFrame(jFrame);
} else {
jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}

private static void addWindowClosingAnimationToJFrame(JFrame jFrame) {
jFrame.addWindowListener(new WindowAdapter() {
@Override
public void windowClosing(WindowEvent e) {
windowClosingAnimation(jFrame);
}
});
}

private static void windowClosingAnimation(JFrame jFrame) {
/* Firstly stores the bounds of our JFrame object to be closed as final */
final Rectangle bounds = jFrame.getBounds();

/* Captured the entire JFrame image */
BufferedImage image = new BufferedImage(bounds.width, bounds.height,
BufferedImage.TYPE_INT_ARGB);
Graphics g = image.getGraphics();
jFrame.paint(g);
g.dispose();

/*
 * Creates a new JWindow object to show the captured image, and at the
 * same time hides the JFrame object.
 */
JWindow jWindow = new JWindow() {
@Override
public void paint(Graphics g) {
super.paint(g);// important to call to have transparency
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, alpha));
g2.shear(shx, 0);
g2.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
};
jWindow.setBounds(bounds);
jFrame.setVisible(false);
jWindow.setVisible(true);

/* Uses a Timer to perform the size variation of JWindow */
int delay = 30; // milliseconds
final int indent = 20;
ActionListener taskPerformer = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
// ...Perform a task...
alpha -= 0.1;
shx += 0.01;
Rectangle bounds = jWindow.getBounds();
bounds.x += indent / 2;
bounds.y += indent / 2;
bounds.width -= indent;
bounds.height -= indent;
if (shx > 0.1 || alpha < 0 || bounds.width < 0
|| bounds.height < 0) {
System.exit(0);
} else {
jWindow.setBounds(bounds);// will call repaint()
}
}
};
new Timer(delay, taskPerformer).start();
}

public static void main(String[] args) {
// To make sure that the GUI creation happens on the EDT
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
createAndShowGUI();
}
});
}
}

#6


该回复于2014-09-22 08:50:34被管理员删除