-1

Just to preface, I've looked for several hours trying to find a solution to this on here and several other sites. If you find a question I may have missed, please let me know.

Anywho, I'm trying to create a thumbnail viewer that displays 4 thumbnails (in jpanels) and 4 captions. I can draw out all 4 thumbnails, but they're all the same image (duplicates of the last one painted). I think it's part of how I'm trying to repaint them, but I can't figure out what to change. The imageAlbum is an ArrayList of jpg paths.

enter image description here

import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;

//import MainFrame.ImageComponent;

import javax.swing.JLabel;

public class Thumbnails extends JFrame {
    final int IMG_WIDTH = 80;
    final int IMG_HEIGHT = 60;
    private BufferedImage image;
    private ImageAlbum imageAlbum;
    private JPanel contentPane;
    private JPanel thmbnl_1;
    private JPanel thmbnl_2;
    private JPanel thmbnl_3;
    private JPanel thmbnl_4;
    private JLabel thmbnl_1Label;
    private JLabel thmbnl_2Label;
    private JLabel thmbnl_3Label;
    private JLabel thmbnl_4Label;

    /**
     * Create the frame.
     */
    public Thumbnails(ImageAlbum album) {
        imageAlbum = album;
        String captionUnavailable = "Caption is not available";

        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setBounds(100, 100, 450, 300);
        contentPane = new JPanel();
        contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
        contentPane.setLayout(new BorderLayout(0, 0));
        setContentPane(contentPane);

        JPanel panel = new JPanel();
        contentPane.add(panel, BorderLayout.CENTER);
        panel.setLayout(new GridLayout(4, 2, 0, 0));

        thmbnl_1 = new JPanel();
        thmbnl_1.setPreferredSize(new Dimension(80, 60));
        panel.add(thmbnl_1);

        thmbnl_2 = new JPanel();
        thmbnl_2.setPreferredSize(new Dimension(80, 60));
        panel.add(thmbnl_2);

        thmbnl_1Label = new JLabel(captionUnavailable);
        panel.add(thmbnl_1Label);

        thmbnl_2Label = new JLabel(captionUnavailable);
        panel.add(thmbnl_2Label);

        thmbnl_3 = new JPanel();
        thmbnl_3.setPreferredSize(new Dimension(IMG_WIDTH, IMG_HEIGHT));
        panel.add(thmbnl_3);

        thmbnl_4 = new JPanel();
        thmbnl_4.setPreferredSize(new Dimension(IMG_WIDTH, IMG_HEIGHT));
        panel.add(thmbnl_4);

        thmbnl_3Label = new JLabel(captionUnavailable);
        panel.add(thmbnl_3Label);

        thmbnl_4Label = new JLabel(captionUnavailable);
        panel.add(thmbnl_4Label);

        setupThumbnails();
    }// end Thumbnails(ImageAlbum album)


    // 
    private void setupThumbnails() {
        int albumSize = imageAlbum.getSize();

        for(int i = 0; i < albumSize; i++) {
            try {           
                image = resizeToThumbnail(ImageIO.read(new File(imageAlbum.getAlbum(i))));

                switch(i) {
                    case 0:
                        thmbnl_1.setLayout(new BorderLayout());
                        thmbnl_1.add(new ImageComponent(image), BorderLayout.CENTER);
                        thmbnl_1Label.setText(imageAlbum.getCaption(i));
                        break;
                    case 1:
                        thmbnl_2.setLayout(new BorderLayout());
                        thmbnl_2.add(new ImageComponent(image), BorderLayout.CENTER);
                        thmbnl_2Label.setText(imageAlbum.getCaption(i));
                        break;
                    case 2:
                        thmbnl_3.setLayout(new BorderLayout());
                        thmbnl_3.add(new ImageComponent(image), BorderLayout.CENTER);
                        thmbnl_3Label.setText(imageAlbum.getCaption(i));
                        break;
                    case 3:
                        thmbnl_4.setLayout(new BorderLayout());
                        thmbnl_4.add(new ImageComponent(image), BorderLayout.CENTER);
                        thmbnl_4Label.setText(imageAlbum.getCaption(i));
                        break;
                    default:
                        break;
                }// end switch-case

                revalidate();
                repaint();              
            }// end try-block
            catch(IOException e) {
                e.printStackTrace();
            }// end catch-block
        }// end for-loop
    }// end setupCaptions()


    // 
    public BufferedImage resizeToThumbnail(BufferedImage original) {
        int type;
        BufferedImage resizedImage = new BufferedImage(IMG_WIDTH, IMG_HEIGHT, original.getType());
        Graphics2D g = resizedImage.createGraphics();
        g.drawImage(original, 0, 0, IMG_WIDTH, IMG_HEIGHT, null);
        g.dispose();
        g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
        g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

        return resizedImage;
    }// end resizeToThumbnail(...)


    class ImageComponent extends JComponent {
        /**
         * Desc: constructor for ImageComponent
         * @param: BufferedImage img
         * @return: nothing
         */
        public ImageComponent(BufferedImage img) {
            image = img;
        }// end ImageComponent()


        /**
         * Desc: draws out the image to the panel
         * @param: Graphics g
         * @return: void
         */
        @Override
        public void paintComponent(Graphics g) {
            if(image == null)
                return;

            Graphics2D g2d = (Graphics2D) g;

            // draw the image
            g.drawImage(image, 0, 0, this);
            g.dispose();
        }// end paintComponents(Graphics g)
    }// end class ImageComponent
}// end class class Thumbnails

EDIT

ImageAlbum class:

import java.util.*;


public class ImageAlbum {
    private ArrayList imageAlbum;
    private ArrayList imageCaptions;
    private int size;


    /**
     * Desc: getter for album size
     * @param: none
     * @return: int
     */
    public int getSize() {
        return size;
    }// end getSize()


    /**
     * Desc: getter for the image
     * @param: int index
     * @return: String
     */
    public String getAlbum(int index) {
        return imageAlbum.get(index).toString();
    }// end getAlbum(int index)



    /**
     * Desc: getter for the image caption
     * @param: int index
     * @return: String
     */
    public String getCaption(int index) {
        return imageCaptions.get(index).toString();
    }// end getCaption(int index)


    /**
     * Desc: default constructor for ImageAlbum
     * @param: none
     * @return: nothing
     */
    public ImageAlbum() {
        imageAlbum = new ArrayList();
        imageCaptions = new ArrayList();
        size = 0;
    }// end ImageAlbum()


    /**
     * Desc: parameterized constructor for ImageAlbum
     * @param: none
     * @return: nothing
     */
    public ImageAlbum(ArrayList tempImageAlbum, ArrayList tempImageCaptions) {
        imageAlbum = tempImageAlbum;
        imageCaptions = tempImageCaptions;
    }// end ImageAlbum(...)


    /**
     * Desc: adds the image directory and caption to both array lists
     * @param: String imageDirectory, String imageCaption
     * @return: void
     */
    public void add(String imageDirectory, String imageCaption) {
        imageAlbum.add(imageDirectory);
        imageCaptions.add(imageCaption);
        size++;
    }// end add(...)


    /**
     * Desc: clears imageAlbum and imageCaptions array lists
     * @param: nothing
     * @return: void
     */
    public void clear() {
        imageAlbum.clear();
        imageCaptions.clear();
        size = 0;
    }// end clear()
}// end class ImageAlbum

FINAL EDIT

I'm obviously not understanding very well, so I've decided to take a different approach - I'm using JLabels and doing icons instead. Works great, thanks everyone for your help

Drew Adams
  • 154
  • 3
  • 11
  • 1
    1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). To be an MCVE, this code would need to a) include a `main(String[])` method b) cut the number of images from 4 to two c) Factor out missing code like `ImageAlbum`. 2) One way to get image(s) for a MCVE is to hot link to images seen in [this Q&A](http://stackoverflow.com/q/19209650/418556). 3) See [Should I avoid the use of set(Preferred|Maximum|Minimum)Size methods in Java Swing?](http://stackoverflow.com/q/7229226/418556) (Yes.) – Andrew Thompson Dec 04 '16 at 11:24
  • Possible duplicate of [*add thumnails to spring layout like a grid?*](http://stackoverflow.com/q/15961412/230513). – trashgod Dec 04 '16 at 11:25
  • I've added the ImageAlbum class - not sure how reducing images from 4 to 2 would help though – Drew Adams Dec 04 '16 at 21:14
  • Also @trashgod i looked at that question and it didn't help answer mine – Drew Adams Dec 05 '16 at 03:33
  • *"not sure how reducing images from 4 to 2 would help though"* Multiple means 'more than one' and two is the smallest number that is 'more than one'. A **minimal** CVE is one that shows the problem in the **shortest** practical amount of code. If you can figure out how to do it with two images, it should be easy to extend that to 4, 8, or 10 thousand images. I also note you are still loading the images from `File` and pointedly, files that we do not have ob our local file-systems, and therefore cannot run the code & see the problem. Like I mentioned in the 2nd comment, easier for us if you .. – Andrew Thompson Dec 05 '16 at 11:11
  • .. (or rather the code) loads the images by URL! – Andrew Thompson Dec 05 '16 at 11:12

1 Answers1

0

Your panel is set for a BorderLayout, and you call panel.add() for each of your thumbnails. That method sets the given component into the middle of the BorderLayout, replacing whatever is there, so that's why you're just seeing the last one added. BorderLayout does not do what you want for the thumbnails.

I would expect you want GridLayout; it lays out components added to it in rows and columns. Set your panel to GridLayout (or whatever else you want to layout the thumbnails), and add the thumbnails to it. Then put panel wherever you want; by default, a JFrame has a Borderlayout on it, you probably want to put panel in the middle of that.

arcy
  • 12,845
  • 12
  • 58
  • 103
  • Arent i setting panel to gridlayout with panel.setLayout(new gridLayou(...))? – Drew Adams Dec 04 '16 at 19:22
  • I've changed that bit of code, but it still shows all 4 thumbnails as duplicates. `contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));` and `contentPane.add(panel, new FlowLayout(FlowLayout.CENTER));` – Drew Adams Dec 04 '16 at 21:52
  • 1
    ok, perhaps it wasn't wrong the way I thought it was. This is why people annoyingly insist on simple examples; there is so much code here it is not worthwhile to me to understand all of it when you may not want an answer when I finally find one, may find the answer yourself, may have left something out that I need, etc., etc. As a learning exercise, I suggest that you write your own simple example; JUST a JFrame, with border layout, and gridlayout in its center, with some labels or images or whatever. Shouldn't take more than 100 lines. If you can't see your own error then, someone here can. – arcy Dec 05 '16 at 03:01
  • there wasn't originally that much code - i didn't think the second half was relevant, but was marked down partly because i didn't include it. thanks for the help though; tried the 100 liner and still couldn't get it to work, though it looks practically identical to my first block of code – Drew Adams Dec 05 '16 at 05:45
  • I hope you understood that the short program was to be a simpler program, complete by itself. If you can't get that to run, post it. – arcy Dec 05 '16 at 09:34
  • (sigh) in your `setupThumbnails()` method, you are loading your image(s) to one instance variable `image`. So you load an image into that variable, iterate in the loop, load the next image into that same variable, iterate, etc. Create a NEW image each time through the loop to add to the UI. I don't think you need your own repaint method, at the least I can't see what it does that requires it to be there, and in that case you don' t need the `image` variable for it to work on. – arcy Dec 05 '16 at 09:40