그래서 당신이 직면하고있는 문제는 그림을 그려야하는 Graphics
컨텍스트가 업데이트 사이에 실제로 "정리"되거나 "휴식"되지 않는다는 사실과 관련이 있습니다. 어느 것이 고통인지, 나도 안다.하지만 거기에있다.
당신이 가지고있는 유일한 선택은 다음 이미지를 칠하기 전에 실제로 각 사이클의 출력을 재설정하는 것입니다.
운 좋게도 SplashScreen
은 실제로 배경 이미지에 URL
을 제공합니다. 이를 통해 우리는 이미지를 스스로로드하고 필요에 따라 표면에 다시 칠할 수 있습니다.
Graphics
컨텍스트를 찾은 상태로 복원하는 데 최선의 노력을 기울여야합니다 (물론 그 위에 무엇을 칠했는지는 제외). 당신이 그것에 페인트 전에이는 eaisly로 ... 그래픽 상태의 복사본을 만들어
기본적으로 다른 접근 방식으로 업데이트
Graphics2D g2d = (Graphics2D)g.create();
// Do you're painting here...
// Release the state when you're done.
g2d.dispose();
import java.awt.AlphaComposite;
import java.awt.Dimension;
import java.awt.Frame;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.SplashScreen;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
public class SplashScreen100 extends Frame implements ActionListener {
static ArrayList<Image> imgs;
private static final long serialVersionUID = 1L;
private BufferedImage background;
protected void renderSplashFrame(Graphics2D g, Image bg) {
// Get the splash screen size...
Dimension size = SplashScreen.getSplashScreen().getSize();
int width = size.width;
int height = size.height;
// Center the image within the splash screen
int x = (width - bg.getWidth(null))/2;
int y = (height - bg.getHeight(null))/2;
Graphics2D g2d = (Graphics2D) g.create();
// Draw the background
g2d.drawImage(background, 0, 0, null);
// Apply alpha composite
g2d.setComposite(AlphaComposite.SrcOver.derive(0.5f));
// Draw the image...
g2d.drawImage(bg, x, y, null);
g2d.dispose();
}
public SplashScreen100() {
super("SplashScreen demo");
final SplashScreen splash = SplashScreen.getSplashScreen();
if (splash == null) {
System.out.println("SplashScreen.getSplashScreen() returned null");
return;
}
Graphics2D g = splash.createGraphics();
if (g == null) {
System.out.println("g is null");
return;
}
try {
background = ImageIO.read(splash.getImageURL());
for (Image img : imgs) {
renderSplashFrame(g, img);
splash.update();
// I put this in to slow the updates down...
try {
Thread.sleep(250);
} catch (InterruptedException ex) {
Logger.getLogger(SplashScreen100.class.getName()).log(Level.SEVERE, null, ex);
}
}
} catch (IOException exp) {
exp.printStackTrace();
}
splash.close();
}
public void actionPerformed(ActionEvent ae) {
System.exit(0);
}
public static void main(String args[]) {
System.setProperty("sun.java2d.opengl", "True");
GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice device = env.getDefaultScreenDevice();
GraphicsConfiguration config = device.getDefaultConfiguration();
imgs = new ArrayList<Image>();
for (File file : new File("\path\to\images").listFiles()) {
if (file.getName().toLowerCase().endsWith(".png")) {
try {
Image buffy = ImageIO.read(file);
imgs.add(buffy);
} catch (IOException e) {
e.printStackTrace();
}
}
}
SplashScreen100 test = new SplashScreen100();
}
}
을 수행 할 수 있습니다 이미지의 크기가 증가하면 업데이트 속도가 느려집니다. 대신, 나는 자신 만의 도구를 만들어서 업데이트 프로세스를보다 잘 제어 할 수 있습니다.
이것은 JWindow
을 기본 창으로 사용하고 사용자 지정된 JPanel
을 주 디스플레이로 사용합니다.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import static splashscreen.MySplashScreen.createCompatibleImage;
import static splashscreen.MySplashScreen.getGraphicsConfiguration;
public class DifferentSplashScreen {
public static void main(String[] args) {
new DifferentSplashScreen();
}
public DifferentSplashScreen() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JWindow frame = new JWindow();
frame.setAlwaysOnTop(true);
frame.setLayout(new BorderLayout());
frame.add(new SplashPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class SplashPane extends JPanel {
private BufferedImage background;
private List<BufferedImage> frames;
private int frameIndex;
private BufferedImage currentFrame;
public SplashPane() {
try {
background = ImageIO.read(new File("C:\\Users\\shane\\Dropbox\\MegaTokyo\\2005-09-29-3957.jpeg"));
frames = new ArrayList<>(40);
List<BufferedImage> images = new ArrayList<>(20);
for (int index = 0; index < 20; index++) {
try {
BufferedImage buffy = ImageIO.read(new File(index + ".png"));
images.add(createCompatibleImage(buffy));
} catch (IOException e) {
e.printStackTrace();
}
}
frames.addAll(images);
Collections.reverse(images);
frames.addAll(images);
} catch (IOException ex) {
ex.printStackTrace();
}
final Timer timer = new Timer(40, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (frameIndex >= frames.size()) {
frameIndex = 0;
}
currentFrame = frames.get(frameIndex);
frameIndex++;
repaint();
}
});
timer.start();
}
@Override
public Dimension getPreferredSize() {
return background == null ? new Dimension(200, 200) : new Dimension(background.getWidth(), background.getHeight());
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (background != null) {
Graphics2D g2d = (Graphics2D) g.create();
int x = (getWidth() - background.getWidth())/2;
int y = (getHeight() - background.getHeight())/2;
g2d.drawImage(background, x, y, this);
if (currentFrame != null) {
x = (getWidth() - currentFrame.getWidth())/2;
y = (getHeight() - currentFrame.getHeight())/2;
g2d.drawImage(currentFrame, x, y, this);
}
g2d.dispose();
}
}
}
public static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
public static BufferedImage createCompatibleImage(BufferedImage master) {
BufferedImage img = createCompatibleImage(master, master.getWidth(), master.getHeight());
Graphics2D g2d = img.createGraphics();
g2d.drawImage(master, 0, 0, null);
g2d.dispose();
return img;
}
public static BufferedImage createCompatibleImage(BufferedImage image,
int width, int height) {
return getGraphicsConfiguration().createCompatibleImage(width, height, image.getTransparency());
}
}
그것은 또한 빠르게 자신의 색 레트의이 즉석에서 변환 할 필요가 없기 때문에 렌더링해야 의미 모든 이미지에 "장치 compatiable"이미지를 변환합니다. 배경 이미지는 1563x1250이고 얼굴 이미지는 300x300 (알파 수준이 달라짐)입니다.
사용이 예, 나는, 그것은
링크 된 코드를 사용하거나 당신이 그것을 변경 한 경우에만 코드가 ... 꽤 무서운 꾸준히
SplashScreen
와 같은 이미지를 사용하여, 문제없이 업데이트하려면했다있어? – MadProgrammer@MadProgrammer http://pastebin.com/UWm25QfY 약간 죄송합니다. 게시글을 업데이트했습니다. –