因此,您想尝试两个基本概念…
首先,为了在其他类上调用方法,您需要对其进行引用。您不一定总是要自己创建该引用,有时,您只是想获得一个预先创建的引用,这使您可以修改引用对象的实际基础实现,而无需修改依赖于该对象的代码。
..
通常,最好通过使用来达到最佳效果
interface,因为它减少了实现的公开性,并阻止了其余API使用他们不应该使用的引用来做事,但这是另一个讨论要点…
基本上,您需要将图像框架的引用传递给图形框架,以便图形框架可以在需要时调用图像框架。在下面的示例中,这是通过
BrowserPane要求的实例
SlideShowPane通过其构造函数传递给它来完成的…
SlideShowPane slideShowPane = new SlideShowPane();//...browser.add(new BrowserPane(slideShowPane));
在
BrowserPane可以使用该引用调用的方法
SlideShowPane,在这种情况下,尤其是
setPath方法…
slideShowPane.setPath(path);
这将导致,
SlideShowPane根据过去的目录/路径的内容开始新的幻灯片放映。
第二个概念是事实,Swing是单线程环境,它也是事件驱动的环境。
第一部分意味着您不能阻止UI线程,否则它就不能处理重画请求。第二部分重点介绍了一种您可以解决此问题的方法。
在此示例中,我仅使用a
javax.swing.Timer来设置图像之间的1秒延迟。计时器在后台(在其自己的线程中)等待,并在触发时将在UI线程的上下文内调用已注册
ActionListener的
actionPerformed方法,从而可以安全地从内部更新UI。
这确保了UI线程不会被阻塞并且可以继续处理新事件,同时为我们提供了执行延迟回调的便捷机制
查看Swing中的并发性和如何使用Swing计时器以了解更多详细信息
import java.awt.Dimension;import java.awt.EventQueue;import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.GraphicsDevice;import java.awt.GraphicsEnvironment;import java.awt.GridBagLayout;import java.awt.Image;import java.awt.Rectangle;import java.awt.event.ActionEvent;import java.awt.event.ActionListener;import java.io.File;import java.io.FileFilter;import java.io.IOException;import java.util.ArrayList;import java.util.Arrays;import java.util.List;import java.util.logging.Level;import java.util.logging.Logger;import javax.imageio.ImageIO;import javax.swing.JButton;import javax.swing.JFileChooser;import javax.swing.Jframe;import javax.swing.JPanel;import javax.swing.Timer;import javax.swing.UIManager;import javax.swing.UnsupportedLookAndFeelException;public class SlideShow { public static void main(String[] args) { new SlideShow(); } public SlideShow() { EventQueue.invokeLater(new Runnable() { @Override public void run() { try { UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { ex.printStackTrace(); } GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); GraphicsDevice gd = ge.getDefaultScreenDevice(); Rectangle bounds = gd.getDefaultConfiguration().getBounds(); System.out.println(bounds); SlideShowPane slideShowPane = new SlideShowPane(); Jframe frame = new Jframe("Image"); frame.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE); frame.add(slideShowPane); frame.pack(); int x = (bounds.x + (bounds.width / 2)) - frame.getWidth(); int y = (bounds.y + (bounds.height - frame.getHeight()) / 2); frame.setLocation(x, y); frame.setVisible(true); Jframe browser = new Jframe("Browser"); browser.setDefaultCloseOperation(Jframe.EXIT_ON_CLOSE); browser.add(new BrowserPane(slideShowPane)); browser.pack(); x = (bounds.x + (bounds.width / 2)) + browser.getWidth(); y = (bounds.y + (bounds.height - browser.getHeight()) / 2); browser.setLocation(x, y); browser.setVisible(true); } }); } public class BrowserPane extends JPanel { private SlideShowPane slideShowPane; private JFileChooser chooser; private BrowserPane(SlideShowPane pane) { this.slideShowPane = pane; setLayout(new GridBagLayout()); JButton browse = new JButton("..."); add(browse); browse.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (chooser == null) { chooser = new JFileChooser(); chooser.setMultiSelectionEnabled(false); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); } switch (chooser.showOpenDialog(BrowserPane.this)) { case JFileChooser.APPROVE_OPTION: File path = chooser.getSelectedFile(); slideShowPane.setPath(path); break; } } }); } } public class SlideShowPane extends JPanel { private File path; private Timer timer; private List<File> imageList; private int nextImage; private Image currentImage; public SlideShowPane() { imageList = new ArrayList<>(25); timer = new Timer(1000, new ActionListener() { @Override public void actionPerformed(ActionEvent e) { if (imageList != null && !imageList.isEmpty()) { nextImage++; if (nextImage >= imageList.size()) { nextImage = 0; } System.out.println("NextImage = " + nextImage); do { try { File file = imageList.get(nextImage); System.out.println("Load " + file); currentImage = ImageIO.read(file); } catch (IOException ex) { currentImage = null; nextImage++; ex.printStackTrace(); } } while (currentImage == null && nextImage < imageList.size()); repaint(); } } }); timer.setInitialDelay(0); } public void setPath(File path) { System.out.println("SetPath"); this.path = path; timer.stop(); imageList.clear(); currentImage = null; if (path.isDirectory()) { File files[] = path.listFiles(new FileFilter() { @Override public boolean accept(File pathname) { String name = pathname.getName().toLowerCase(); return name.endsWith(".jpg") || name.endsWith(".jpeg") || name.endsWith(".png") || name.endsWith(".bmp") || name.endsWith(".gif"); } }); if (files != null) { System.out.println("Found " + files.length + " matches"); imageList.addAll(Arrays.asList(files)); } } if (imageList.isEmpty()) { repaint(); } else { System.out.println("Start timer..."); nextImage = -1; timer.restart(); } } @Override public Dimension getPreferredSize() { return new Dimension(200, 200); } protected void paintComponent(Graphics g) { super.paintComponent(g); if (currentImage != null) { Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - currentImage.getWidth(this)) / 2; int y = (getHeight() - currentImage.getHeight(this)) / 2; g2d.drawImage(currentImage, x, y, this); g2d.dispose(); } } }}


