使用JFileChooser上传多个图像

我试图在网上搜索这个问题的帮助,但找不到任何答案。 此时我有一个工作程序,允许您选择一个图像文件并显示它。 我想通过允许用户选择多个文件然后选择要显示的文件来构建此基础。 例如,用户将选择图像并将其显示。 然后,他可以单击一个按钮,允许其他图像排队等待,并且可能会显示一个按钮,点击后,图像将加载到框架中。 任何人都可以指导我如何实施这个方向吗? 非常感谢你的帮助!

这是我当前的代码实现:

import java.awt.Image; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.io.File; import javax.swing.*; import javax.swing.filechooser.FileNameExtensionFilter; import java.util.ArrayList; public class Images extends JFrame{ JButton button; JButton button2; JButton button3; JLabel label; ArrayList images = new ArrayList(); int selectedImageIndex =0; public Images(){ super("Java Image Selector"); button = new JButton("Select"); button.setBounds(300,300,100,40); button2 = new JButton("Next Image"); button2.setBounds(250,250,100,40); button3 = new JButton("Previous Image"); button3.setBounds(350,350,100,40); label = new JLabel(); label.setBounds(10,10,670,250); add(button); add(button2); add(button3); add(label); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { JFileChooser file = new JFileChooser(); file.setMultiSelectionEnabled(true); File selected[] = file.getSelectedFiles(); file.setCurrentDirectory(new File(System.getProperty("user.home"))); //filter the files FileNameExtensionFilter filter = new FileNameExtensionFilter("*.Images", "jpg","gif","png"); file.addChoosableFileFilter(filter); int result = file.showSaveDialog(null); //if the user click on save in Jfilechooser if(result == JFileChooser.APPROVE_OPTION){ File selectedFile = file.getSelectedFile(); String path = selectedFile.getAbsolutePath(); File[] files = file.getSelectedFiles(); for (File open : files) { images.add(open); } startProgram(selectedImageIndex); } //if the user click on save in Jfilechooser else if(result == JFileChooser.CANCEL_OPTION){ System.out.println("No File Selected"); } } }); button2.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { goToNextImages(); } }); button3.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { goToPreviousImage(); } }); setLayout(null); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setLocationRelativeTo(null); setSize(700,400); setVisible(true); } // Methode to resize imageIcon with the same size of a Jlabel public ImageIcon ResizeImage(String ImagePath) { ImageIcon MyImage = new ImageIcon(ImagePath); Image img = MyImage.getImage(); Image newImg = img.getScaledInstance(label.getWidth(), label.getHeight(), Image.SCALE_SMOOTH); ImageIcon image = new ImageIcon(newImg); return image; } public void setImage(int index){ if (index<images.size()) { File imageFile = images.get(index); String path = imageFile.getAbsolutePath(); selectedImageIndex = index; label.setIcon(ResizeImage(path)); //read the file and set the image }else{ System.out.println("no image found"); } } public void goToNextImages(){ ++selectedImageIndex; setImage(selectedImageIndex); } public void goToPreviousImage(){ --selectedImageIndex; setImage(selectedImageIndex); } public void startProgram(int index){ setImage(index); } public static void main(String[] args){ new Work(); } } 

 ArrayList images = new ArrayList<>(); int selectedImageIndex =0; public void selectFiles() { //you can call this method multiple times it wont matter //files selected at each time will be stored on the images arraylist JFileChooser chooser = new JFileChooser(); chooser.setMultiSelectionEnabled(true); chooser.showOpenDialog(this); File[] files = chooser.getSelectedFiles(); for (File file : files) { images.add(file); } startProgram(selectedImageIndex); } public void setImage(int index){ if (index 

好的,让我们稍微打破一下,你基本上需要:

  • 某种“模型”,其中包含图像文件列表
  • 显示当前图像的某种“视图”
  • 某种“控制器”管理视图和模型之间的关系
  • 某种“模型”,它跟踪当前可视图像并知道它是否可以加载下一个或上一个图像
  • 某种“视图”允许用户控制导航
  • 一些控制它的方法

好吧,如果那不是模型 – 视图 – 控制器 ,我不知道是什么……

好吧,因为我喜欢明确定义的合同和责任范围,我喜欢从接口开始……

导航…

 public interface NavigationModel { public boolean next(); public boolean previous(); public int getIndex(); public void addChangeListener(ChangeListener listener); public void removeChangeListener(ChangeListener listener); public boolean canNavigateForward(); public boolean canNavigateBack(); } public interface NavigationViewDelegate { public boolean next(NavigationView view); public boolean previous(NavigationView view); public boolean canNavigateForward(); public boolean canNavigateBack(); } public interface NavigationView { public void setDelegate(NavigationViewDelegate delegate); public NavigationViewDelegate getDelegate(); public JComponent getView(); public void stateChanged(); } public interface NavigationContoller { public NavigationView getView(); public NavigationModel getModel(); public void addChangeListener(ChangeListener listener); public void removeChangeListener(ChangeListener listener); } 

好的,所以委托允许视图向“某人”询问有关当前状态的更多信息,这通常是控制器。 该模型触发ChangeEvent ,它告诉任何感兴趣的人,模型的状态以某种方式发生了变化,控制器将它们全部绑定在一起。

默认实施

通常情况下,我会有一系列的抽象实现,但为了简洁起见,我直接进行了实现

 public class DefaultNavigationController implements NavigationContoller { private NavigationView view; private NavigationModel model; private ChangeListener modelChangeListener; private final Set changeListeners; public DefaultNavigationController(NavigationView view, NavigationModel model) { Objects.requireNonNull(model, "Model can not be null"); Objects.requireNonNull(view, "View can not be null"); this.view = view; this.model = model; view.setDelegate(new NavigationViewDelegate() { @Override public boolean next(NavigationView view) { return getModel().next(); } @Override public boolean previous(NavigationView view) { return getModel().previous(); } @Override public boolean canNavigateForward() { NavigationModel model = getModel(); return model.canNavigateForward(); } @Override public boolean canNavigateBack() { NavigationModel model = getModel(); return model.canNavigateBack(); } }); changeListeners = new HashSet<>(25); modelChangeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { getView().stateChanged(); fireStateChanged(); } }; this.model.addChangeListener(modelChangeListener); getView().stateChanged(); } @Override public NavigationView getView() { return view; } @Override public NavigationModel getModel() { return model; } protected void setModel(NavigationModel model) { this.model.removeChangeListener(modelChangeListener); this.model = model; this.model.addChangeListener(modelChangeListener); getView().stateChanged(); fireStateChanged(); } @Override public void addChangeListener(ChangeListener listener) { changeListeners.add(listener); } @Override public void removeChangeListener(ChangeListener listener) { changeListeners.remove(listener); } protected void fireStateChanged() { ChangeEvent evt = new ChangeEvent(this); for (ChangeListener listener : changeListeners) { listener.stateChanged(evt); } } } public class DefaultNavigationModel implements NavigationModel { private final int minValue; private final int maxValue; private int currentIndex; private final Set changeListeners; public DefaultNavigationModel(int minValue, int maxValue) { this.maxValue = maxValue; this.minValue = minValue; currentIndex = minValue; changeListeners = new HashSet<>(25); } @Override public boolean next() { if (currentIndex + 1 < maxValue) { currentIndex++; fireStateChanged(); } return canNavigateForward(); } @Override public boolean previous() { if (currentIndex >= minValue) { currentIndex--; fireStateChanged(); } return canNavigateBack(); } @Override public int getIndex() { return currentIndex; } @Override public void addChangeListener(ChangeListener listener) { changeListeners.add(listener); } @Override public void removeChangeListener(ChangeListener listener) { changeListeners.remove(listener); } protected void fireStateChanged() { ChangeEvent evt = new ChangeEvent(this); for (ChangeListener listener : changeListeners) { listener.stateChanged(evt); } } @Override public boolean canNavigateForward() { return size() > 0 && currentIndex < maxValue - 1; } @Override public boolean canNavigateBack() { return size() > 0 && currentIndex > minValue; } public int size() { return maxValue - minValue; } } public class DefaultNavigationView extends JPanel implements NavigationView { private JButton nextButton; private JButton previousButton; private NavigationViewDelegate delegate; public DefaultNavigationView() { setLayout(new GridBagLayout()); nextButton = new JButton(">"); previousButton = new JButton("<"); nextButton.setEnabled(false); previousButton.setEnabled(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.weightx = 1; gbc.anchor = GridBagConstraints.WEST; add(previousButton, gbc); gbc.anchor = GridBagConstraints.EAST; add(nextButton, gbc); nextButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { NavigationViewDelegate delegate = getDelegate(); if (delegate != null) { nextButton.setEnabled(delegate.next(DefaultNavigationView.this)); } } }); previousButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { NavigationViewDelegate delegate = getDelegate(); if (delegate != null) { previousButton.setEnabled(delegate.previous(DefaultNavigationView.this)); } } }); } @Override public NavigationViewDelegate getDelegate() { return delegate; } @Override public JComponent getView() { return this; } @Override public void setDelegate(NavigationViewDelegate delegate) { this.delegate = delegate; stateChanged(); } @Override public void stateChanged() { nextButton.setEnabled(delegate != null && delegate.canNavigateForward()); previousButton.setEnabled(delegate != null && delegate.canNavigateBack()); } } 

这里需要注意的重要一点是,导航API并不关心图像,它只关心“范围”以及它当前的价值。

例如,这可能意味着您可以将视图更改为基于JSlider或包含JComboBox或者您希望允许用户更改索引的控件,其余代码将无关紧要。

图片...

以类似的方式,我们定义一个简单的模型,它维护一个表示可用图像的File列表,一个显示它们的视图和一个绑定它们的控制器......

 public interface ImageModel { public File getImageAt(int index); public int size(); } public interface ImageView { public void loadImageAt(int index); public void setDelegate(ImageViewDelegate delegate); public ImageViewDelegate getDelegate(); public JComponent getView(); } public interface ImageViewDelegate { public File imageAt(ImageView view, int index); } public interface ImageViewController { public ImageModel getModel(); public ImageView getView(); public void loadImageAt(int index); } 

默认实施......

同样,为简洁起见,直接执行......

 public class DefaultImageModel implements ImageModel { private List images; private int currentImage = -1; public DefaultImageModel(List images) { this.images = new ArrayList<>(images); } @Override public File getImageAt(int index) { return images.get(index); } @Override public int size() { return images.size(); } } public class DefaultImageController implements ImageViewController { private ImageView view; private ImageModel model; public DefaultImageController(ImageView view, ImageModel model) { Objects.requireNonNull(model, "Model can not be null"); Objects.requireNonNull(view, "View can not be null"); this.view = view; this.model = model; view.setDelegate(new ImageViewDelegate() { @Override public File imageAt(ImageView view, int index) { return getModel().getImageAt(index); } }); } public void setModel(ImageModel model) { Objects.requireNonNull(model, "Model can not be null"); this.model = model; } @Override public ImageModel getModel() { return model; } @Override public ImageView getView() { return view; } @Override public void loadImageAt(int index) { getView().loadImageAt(index); } } public class DefaultImageViewPane extends JPanel implements ImageView { private ImageViewDelegate delegate; private BufferedImage img = null; public DefaultImageViewPane() { } @Override public Dimension getPreferredSize() { return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (img != null) { Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - img.getWidth()) / 2; int y = (getHeight() - img.getHeight()) / 2; g2d.drawImage(img, x, y, this); g2d.dispose(); } } @Override public void setDelegate(ImageViewDelegate delegate) { this.delegate = delegate; } @Override public ImageViewDelegate getDelegate() { return delegate; } @Override public JComponent getView() { return this; } @Override public void loadImageAt(int index) { ImageViewDelegate delegate = getDelegate(); if (delegate != null) { img = null; File file = delegate.imageAt(this, index); if (file != null) { try { img = ImageIO.read(file); } catch (IOException ex) { ex.printStackTrace(); } } revalidate(); repaint(); } } } 

把它们放在一起......

现在,您可能想知道这一切是如何组合在一起的?

这是一个很好的例子,说明控制器如何协同工作,实际上彼此不了解,相互提供信息以实现所需的结果......

图像和导航

 import java.awt.BorderLayout; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Objects; import java.util.Set; import java.util.prefs.Preferences; import javax.imageio.ImageIO; import javax.swing.AbstractAction; import javax.swing.JButton; import javax.swing.JComponent; import javax.swing.JFileChooser; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JToolBar; import javax.swing.UIManager; import javax.swing.UnsupportedLookAndFeelException; import javax.swing.event.ChangeEvent; import javax.swing.event.ChangeListener; import javax.swing.filechooser.FileNameExtensionFilter; public class Test { public static void main(String[] args) { new Test(); } public Test() { 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 MainPane()); frame.pack(); frame.setLocationRelativeTo(null); frame.setVisible(true); } }); } public class MainPane extends JPanel { private DefaultImageController imageController; private DefaultNavigationController navigationController; public MainPane() { setLayout(new BorderLayout()); ImageView imageView = new DefaultImageViewPane(); ImageModel imageModel = new DefaultImageModel(new ArrayList<>()); imageController = new DefaultImageController(imageView, imageModel); add(new JScrollPane(imageController.getView().getView())); NavigationView navView = new DefaultNavigationView(); NavigationModel navModel = new DefaultNavigationModel(0, 0); navigationController = new DefaultNavigationController(navView, navModel); navigationController.addChangeListener(new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { NavigationContoller controller = (NavigationContoller) e.getSource(); imageController.loadImageAt(controller.getModel().getIndex()); } }); add(navigationController.getView().getView(), BorderLayout.SOUTH); JToolBar tb = new JToolBar(); tb.add(new AbstractAction("Browse") { @Override public void actionPerformed(ActionEvent e) { String lastDirectory = Preferences.userNodeForPackage(MainPane.class).get("Images.lastDirectory", System.getProperty("user.home")); JFileChooser fc = new JFileChooser(); File lastPath = new File(lastDirectory); if (lastPath.exists() && lastPath.isDirectory()) { fc.setCurrentDirectory(new File(lastDirectory)); } fc.addChoosableFileFilter(new FileNameExtensionFilter("Image files", ImageIO.getReaderFileSuffixes())); fc.setMultiSelectionEnabled(true); if (fc.showOpenDialog(MainPane.this) == JFileChooser.APPROVE_OPTION) { lastDirectory = fc.getCurrentDirectory().getPath(); Preferences.userNodeForPackage(MainPane.class).put("Images.lastDirectory", lastDirectory); File[] files = fc.getSelectedFiles(); imageController.setModel(new DefaultImageModel(Arrays.asList(files))); navigationController.setModel(new DefaultNavigationModel(0, files.length)); } } }); add(tb, BorderLayout.NORTH); } } public interface ImageModel { public File getImageAt(int index); public int size(); } public interface ImageView { public void loadImageAt(int index); public void setDelegate(ImageViewDelegate delegate); public ImageViewDelegate getDelegate(); public JComponent getView(); } public interface ImageViewDelegate { public File imageAt(ImageView view, int index); } public interface ImageViewController { public ImageModel getModel(); public ImageView getView(); public void loadImageAt(int index); } public class DefaultImageModel implements ImageModel { private List images; private int currentImage = -1; public DefaultImageModel(List images) { this.images = new ArrayList<>(images); } @Override public File getImageAt(int index) { return images.get(index); } @Override public int size() { return images.size(); } } public class DefaultImageController implements ImageViewController { private ImageView view; private ImageModel model; public DefaultImageController(ImageView view, ImageModel model) { Objects.requireNonNull(model, "Model can not be null"); Objects.requireNonNull(view, "View can not be null"); this.view = view; this.model = model; view.setDelegate(new ImageViewDelegate() { @Override public File imageAt(ImageView view, int index) { return getModel().getImageAt(index); } }); } public void setModel(ImageModel model) { Objects.requireNonNull(model, "Model can not be null"); this.model = model; } @Override public ImageModel getModel() { return model; } @Override public ImageView getView() { return view; } @Override public void loadImageAt(int index) { getView().loadImageAt(index); } } public class DefaultImageViewPane extends JPanel implements ImageView { private ImageViewDelegate delegate; private BufferedImage img = null; public DefaultImageViewPane() { } @Override public Dimension getPreferredSize() { return img == null ? new Dimension(200, 200) : new Dimension(img.getWidth(), img.getHeight()); } @Override protected void paintComponent(Graphics g) { super.paintComponent(g); if (img != null) { Graphics2D g2d = (Graphics2D) g.create(); int x = (getWidth() - img.getWidth()) / 2; int y = (getHeight() - img.getHeight()) / 2; g2d.drawImage(img, x, y, this); g2d.dispose(); } } @Override public void setDelegate(ImageViewDelegate delegate) { this.delegate = delegate; } @Override public ImageViewDelegate getDelegate() { return delegate; } @Override public JComponent getView() { return this; } @Override public void loadImageAt(int index) { ImageViewDelegate delegate = getDelegate(); if (delegate != null) { img = null; File file = delegate.imageAt(this, index); if (file != null) { try { img = ImageIO.read(file); } catch (IOException ex) { ex.printStackTrace(); } } revalidate(); repaint(); } } } /** * ************************************************************************* */ public interface NavigationModel { public boolean next(); public boolean previous(); public int getIndex(); public void addChangeListener(ChangeListener listener); public void removeChangeListener(ChangeListener listener); public boolean canNavigateForward(); public boolean canNavigateBack(); } public interface NavigationViewDelegate { public boolean next(NavigationView view); public boolean previous(NavigationView view); public boolean canNavigateForward(); public boolean canNavigateBack(); } public interface NavigationView { public void setDelegate(NavigationViewDelegate delegate); public NavigationViewDelegate getDelegate(); public JComponent getView(); public void stateChanged(); } public interface NavigationContoller { public NavigationView getView(); public NavigationModel getModel(); public void addChangeListener(ChangeListener listener); public void removeChangeListener(ChangeListener listener); } public class DefaultNavigationController implements NavigationContoller { private NavigationView view; private NavigationModel model; private ChangeListener modelChangeListener; private final Set changeListeners; public DefaultNavigationController(NavigationView view, NavigationModel model) { Objects.requireNonNull(model, "Model can not be null"); Objects.requireNonNull(view, "View can not be null"); this.view = view; this.model = model; view.setDelegate(new NavigationViewDelegate() { @Override public boolean next(NavigationView view) { return getModel().next(); } @Override public boolean previous(NavigationView view) { return getModel().previous(); } @Override public boolean canNavigateForward() { NavigationModel model = getModel(); return model.canNavigateForward(); } @Override public boolean canNavigateBack() { NavigationModel model = getModel(); return model.canNavigateBack(); } }); changeListeners = new HashSet<>(25); modelChangeListener = new ChangeListener() { @Override public void stateChanged(ChangeEvent e) { getView().stateChanged(); fireStateChanged(); } }; this.model.addChangeListener(modelChangeListener); getView().stateChanged(); } @Override public NavigationView getView() { return view; } @Override public NavigationModel getModel() { return model; } protected void setModel(NavigationModel model) { this.model.removeChangeListener(modelChangeListener); this.model = model; this.model.addChangeListener(modelChangeListener); getView().stateChanged(); fireStateChanged(); } @Override public void addChangeListener(ChangeListener listener) { changeListeners.add(listener); } @Override public void removeChangeListener(ChangeListener listener) { changeListeners.remove(listener); } protected void fireStateChanged() { ChangeEvent evt = new ChangeEvent(this); for (ChangeListener listener : changeListeners) { listener.stateChanged(evt); } } } public class DefaultNavigationModel implements NavigationModel { private final int minValue; private final int maxValue; private int currentIndex; private final Set changeListeners; public DefaultNavigationModel(int minValue, int maxValue) { this.maxValue = maxValue; this.minValue = minValue; currentIndex = minValue; changeListeners = new HashSet<>(25); } @Override public boolean next() { if (currentIndex + 1 < maxValue) { currentIndex++; fireStateChanged(); } return canNavigateForward(); } @Override public boolean previous() { if (currentIndex >= minValue) { currentIndex--; fireStateChanged(); } return canNavigateBack(); } @Override public int getIndex() { return currentIndex; } @Override public void addChangeListener(ChangeListener listener) { changeListeners.add(listener); } @Override public void removeChangeListener(ChangeListener listener) { changeListeners.remove(listener); } protected void fireStateChanged() { ChangeEvent evt = new ChangeEvent(this); for (ChangeListener listener : changeListeners) { listener.stateChanged(evt); } } @Override public boolean canNavigateForward() { return size() > 0 && currentIndex < maxValue - 1; } @Override public boolean canNavigateBack() { return size() > 0 && currentIndex > minValue; } public int size() { return maxValue - minValue; } } public class DefaultNavigationView extends JPanel implements NavigationView { private JButton nextButton; private JButton previousButton; private NavigationViewDelegate delegate; public DefaultNavigationView() { setLayout(new GridBagLayout()); nextButton = new JButton(">"); previousButton = new JButton("<"); nextButton.setEnabled(false); previousButton.setEnabled(false); GridBagConstraints gbc = new GridBagConstraints(); gbc.weightx = 1; gbc.anchor = GridBagConstraints.WEST; add(previousButton, gbc); gbc.anchor = GridBagConstraints.EAST; add(nextButton, gbc); nextButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { NavigationViewDelegate delegate = getDelegate(); if (delegate != null) { nextButton.setEnabled(delegate.next(DefaultNavigationView.this)); } } }); previousButton.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent e) { NavigationViewDelegate delegate = getDelegate(); if (delegate != null) { previousButton.setEnabled(delegate.previous(DefaultNavigationView.this)); } } }); } @Override public NavigationViewDelegate getDelegate() { return delegate; } @Override public JComponent getView() { return this; } @Override public void setDelegate(NavigationViewDelegate delegate) { this.delegate = delegate; stateChanged(); } @Override public void stateChanged() { nextButton.setEnabled(delegate != null && delegate.canNavigateForward()); previousButton.setEnabled(delegate != null && delegate.canNavigateBack()); } } }