I'm trying to code a picture viewer application using Java Swing. My little application has a JMenuItem importItem in order to select an image. The problem in this app. is that when you add only one picture it doesn't show up, so you should add two or more pictures. I think the problem is inside the importItem actionPerformed() method but I don't know where is it exactly.
Any idea how to fix it?
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
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;
public class MainFrame2 extends JFrame implements ActionListener{
private JPanel northPanel,principalPanel,centerPanel;
private JButton nextButton,previousButton;
private int counter = 1;
private JFileChooser jFileChooser;
private ArrayList<JPanel> picturesPanels;
private ArrayList<BufferedImage> pictures;
public MainFrame2() {
setSize(600,600);
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
northPanel = new JPanel(new FlowLayout());
nextButton = new JButton(">>");
nextButton.addActionListener(this);
previousButton = new JButton("<<");
previousButton.addActionListener(this);
northPanel.add(previousButton);
northPanel.add(nextButton);
picturesPanels = new ArrayList<>();
pictures = new ArrayList<>();
centerPanel = new JPanel(new CardLayout());
principalPanel = new JPanel(new BorderLayout());
principalPanel.add(northPanel,BorderLayout.NORTH);
principalPanel.add(centerPanel,BorderLayout.CENTER);
setContentPane(principalPanel);
setJMenuBar(myMenu());
jFileChooser = new JFileChooser();
//jFileChooser.setFileFilter(new PictureFilter());
jFileChooser.setMultiSelectionEnabled(true);
setMinimumSize(new Dimension(300,300));
setVisible(true);
}
private JMenuBar myMenu() {
JMenuBar jMenuBar = new JMenuBar();
JMenu fileMenu = new JMenu("File");
JMenuItem importItem = new JMenuItem("Import pictures");
fileMenu.add(importItem);
////////////////Setting Up importItem///////////////////
importItem.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (jFileChooser.showOpenDialog(MainFrame2.this)
== JFileChooser.APPROVE_OPTION) {
File [] files = jFileChooser.getSelectedFiles();
for (int i=0;i<files.length;i++) {
try {
pictures.add(ImageIO.read(new
File(files[i].getPath())));
} catch (IOException e1) {
System.out.println("Error loading image");
}
}
picturesPanels.clear();
for (BufferedImage image:pictures) {
picturesPanels.add(new JPanel() {
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int original_width = image.getWidth();
int original_height = image.getHeight();
int bound_width = getWidth();
int bound_height = getHeight();
int new_width = original_width;
int new_height = original_height;
if (original_width > bound_width) {
new_width = bound_width;
new_height = (new_width * original_height) /
original_width;
}
if (new_height > bound_height) {
new_height = bound_height;
new_width = (new_height * original_width)/
original_height;
}
g.drawImage(image,(getWidth()-new_width)/2
,(getHeight()-
new_height)/2,new_width,new_height,this);
}
});
}
for (int i=0;i<picturesPanels.size();i++) {
centerPanel.add(picturesPanels.get(i),""+(i+1));
}
}
}
});
jMenuBar.add(fileMenu);
return jMenuBar;
}
@Override
public void actionPerformed(ActionEvent e) {
CardLayout cardLayout = (CardLayout)centerPanel.getLayout();
if (e.getSource() == nextButton) {
counter++;
if (counter>pictures.size()) {
counter = 1;
}
cardLayout.show(centerPanel,""+counter);
}
if (e.getSource() == previousButton) {
counter--;
if (counter<1) {
counter = pictures.size();
}
cardLayout.show(centerPanel,""+counter);
}
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
new MainFrame2();
}
});
}
}
picturesbut then each time the user adds pictures, you loop throughpicturesand add a newJPaneltopicturePanels. I would think this would cause a repeat of any previously loaded pictures. Then when you add them to thecenterPanelyou haven't removed the previous ones, so there might be multiple picturePanels with the sameconstraints.PicturePanelclass that extendsJPaneland implements anBufferedImage image;class variable and set that in the constructor, likepicturePanels.add(new PicturePanel(image));.constraintsjus with addingpicturesPanels.clear();before this loop` for (BufferedImage image:pictures)`