Search code examples
javaarraysswingdrag-and-dropimageicon

Array of ImageIcons, change contents of array on drag and drop


I have an array of ImageIcons, and I can drag and drop other Icons onto them to replace them. When I hit a button a new JFrame is created from the array of ImageIcons.

If I do this without dragging any other Icons on to the original array, it works. However once I drop a different imageicon into the array, I get an error when I hit the button.

I'm just wondering if this is even possible at all?

I've considered other approaches of using a JTable for the top panel, or trying to use an ArrayList, but I'm not too comfortable using them. If anyone has any opinion on how this should be done, please let me know!

I shortened this example as much as possible(at 200 lines it's not exactly short). But this is exactly what my problem is...

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.Properties;
import java.awt.Toolkit; 
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;
import java.io.*;
import java.lang.String.*;
public class test extends JFrame {

JPanel storyPanel, rightStoryPanel, leftStoryPanel,centerStoryPanel, imageSelectPanel, CreatePanel, storyFramePanel, storycard;
TransferHandler handler;
MouseListener listener;
CardLayout cl3;
JLabel[] storyLabel = new JLabel[20];
JButton playStory, nextStory,addtargetbutton;
int count, start, i, j,stop, start1;

      public test(){


            CreatePanel = new JPanel(new BorderLayout());
            storyPanel = new JPanel(new BorderLayout());
            rightStoryPanel = new JPanel(new GridLayout(6,1));
            leftStoryPanel = new JPanel(new GridLayout(6,1));
            centerStoryPanel = new JPanel();
            JScrollPane centerscroll = new JScrollPane(centerStoryPanel);
            addtargetbutton = new JButton("Add Another Image Slot");
            addtargetbutton.addActionListener(new createbuttons());
            playStory = new JButton("Play your story!");
            leftStoryPanel.add(playStory);
            playStory.addActionListener(new createbuttons());
            leftStoryPanel.add(addtargetbutton);
            imageSelectPanel = new JPanel(new FlowLayout());
            storyPanel.add(rightStoryPanel,BorderLayout.EAST);
            storyPanel.add(leftStoryPanel, BorderLayout.WEST);
            storyPanel.add(centerscroll, BorderLayout.CENTER);
            CreatePanel.add(storyPanel, BorderLayout.NORTH);
            CreatePanel.add(imageSelectPanel, BorderLayout.CENTER);


            count= 3;
            start= 0;
            stop = 0;
            start1= 0;
            ImageSelection();
            targetpanel();
            getContentPane().add(CreatePanel);

        }//End Create}

      public void ImageSelection(){ 



        int i = 0;
        int j = 0;

        TransferHandler handler = new TransferHandler("icon") {
            @Override
            public boolean canImport(TransferSupport support) {
                return super.canImport(support) 
                    && support.getComponent().getParent() != imageSelectPanel;}
                };

        MouseListener listener = new MouseAdapter(){
            public void mousePressed(MouseEvent e){
            JComponent c = (JComponent) e.getSource();
            TransferHandler handler = c.getTransferHandler();
            handler.exportAsDrag(c, e, TransferHandler.COPY);
            System.out.println(e);}
        }; // Drag & Drop mouse


            try{    

                String imagePath = "";          
                BufferedImage[] CreateImagesFromDB = new BufferedImage[40];
                JLabel[] ImageLabel = new JLabel[40];

                while (count > start1) {
                    i = 1;
                    CreateImagesFromDB[i] = ImageIO.read(new File("one.jpg"));
                    ImageLabel[i] = new JLabel(new ImageIcon(CreateImagesFromDB[i]));
                    imageSelectPanel.add(ImageLabel[i]);    
                    ImageLabel[i].addMouseListener(listener);
                    ImageLabel[i].setTransferHandler(handler);
                    i++;
                    start1++;
                    }
            }//EndTRY
            catch(Exception e){
                System.out.println("CATCH"+ e);
            }//end catch

    }


      public void targetpanel(){
            TransferHandler handler = new TransferHandler("icon") {
            @Override
            public boolean canImport(TransferSupport support) {
                return super.canImport(support) 
                    && support.getComponent().getParent() != imageSelectPanel;
            }
            };
            MouseListener listener = new MouseAdapter(){
            public void mousePressed(MouseEvent e){
                JComponent c = (JComponent) e.getSource();
                TransferHandler handler = c.getTransferHandler();
                handler.exportAsDrag(c, e, TransferHandler.COPY);
            }
            };

          BufferedImage[] storyImages = new BufferedImage[20];


          try{ 

              while(count > start){  
                storyImages[j] = ImageIO.read(new File("TargetImg.jpg"));
                storyLabel[j] = new JLabel(new ImageIcon(storyImages[j]));
                centerStoryPanel.add(storyLabel[j]); 
                storyLabel[j].addMouseListener(listener);
                storyLabel[j].setTransferHandler(handler);
                j++;
                start++;
                centerStoryPanel.revalidate();
                //validate();
                System.out.println("J in Loop is: "+j );

              }//end while Loop  
                //System.out.println("J is equalto: "+j);
            } catch(Exception e) {};
      }// End TargetPanel


          public void storyFrame (JLabel[] storyArray){
                int i = 0;
        storyFramePanel = new JPanel(new BorderLayout());
        nextStory = new JButton("Next Image");
        nextStory.addActionListener(new createbuttons());
        storycard = new JPanel();
        cl3 = new CardLayout();
        storycard.setLayout(cl3);

        JPanel[] storyImgPanel = new JPanel[20];
        JLabel[] imglab = new JLabel[20];
        storyImgPanel[i]= new JPanel();

        while( i < j){

            storyImgPanel[i].add(new JLabel(storyArray[i].getIcon()));
            storycard.add(storyImgPanel[i], ""+i); 
            i++;
        }




        JFrame story = new JFrame("Story");
        story.setSize(500,500);

        storyFramePanel.add(storycard, BorderLayout.CENTER);
        storyFramePanel.add(nextStory, BorderLayout.EAST);
        story.add(storyFramePanel);
        cl3.show(storycard, "1");
        story.setVisible(true);

        }

public static void main(String[] args){

        System.out.println("Application Running");
        JFrame mainframe =  new test();
        mainframe.setTitle("Let Me Know!");
        mainframe.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        mainframe.setSize(1000,1000);
        mainframe.setVisible(true);

    }


class createbuttons implements ActionListener{
          public void actionPerformed(ActionEvent e)
        {

          if(e.getSource() == addtargetbutton){
              count++;
              targetpanel();
              System.out.println("Trying to add another TargetImg, count = "+count); 
          }
          if(e.getSource() == playStory){
                storyFrame(storyLabel);
          }
          if(e.getSource() == nextStory){

          cl3.next(storycard);
          System.out.println("button pressed");
          }
        }
    }

}

Solution

  • I figured it out:

    Firstly, each time you call targetpanel(), you create a new instance of storyLabel, but then you are behaving like you have it already populated from the previous calls. So the result is:

    first call:

    storyLabel[0] = something;
    storyLabel[1] = something;
    storyLabel[2] = something;
    storyLabel[3] = null;
    storyLabel[4] = null.... etc
    

    second call (you added another image slot):

    storyLabel[0] = null;
    storyLabel[1] = null;
    storyLabel[2] = null;
    storyLabel[3] = something;
    storyLabel[4] = null.... etc
    

    So when you use this array in the storyboard, you get NullPointerException. You need to create the array only once. So remove storyLabel = new JLabel[20] from targetpanel() and initialize the array in the constructor, or even better in the declaration:

    ...
        CardLayout cl3;
        JLabel[] storyLabel = new JLabel[20];
        JButton playStory, nextStory, addtargetbutton;
    ...
    

    Secondly, when displaying the images using the storyFrame(), you change the parent of the supplied JLabels and they subsequently disappear from the storyPanel. You must create new instances of JLabel for the storyboard.

    In storyFrame(), instead of

    storyImgPanel[i].add(storyArray[i]);
    

    write

    storyImgPanel[i].add(new JLabel(storyArray[i].getIcon()));
    

    If I do all this the program is working.