Question

I'm having problems repainting a class after I have added an object to it.

public class Window extends JFrame {

/**
 * 
 */
private static final long serialVersionUID = 1L;

private MediaHandler myMediaHandler = new MediaHandler(this);

class MenuActionListener implements ActionListener {

    @Override
    public void actionPerformed(ActionEvent e) {
        String buttonText = e.getActionCommand();
        switch(buttonText) {
        case "Add Movie":
            AddMovieWindow addMovieGUI = new AddMovieWindow(myMediaHandler);
            addMovieGUI.setVisible(true);
            break;
        case "Add TV-Show":
            AddTVShowWindow addTVShowGUI = new AddTVShowWindow(myMediaHandler);
            addTVShowGUI.setVisible(true);
            break;
        }
    }
}

public Window() {
//  myMediaHandler.addMovie("Nineteen Eighty-Four", 113.00, 1984, "Michael Radford", "mediaPath", "https://dl.dropboxusercontent.com/u/16670644/Projekt/1984.png", "HD", false, "Eng", "George Orwell (novel)");
    addComponents();
    configurFrame();
    addMenu();

    validate();
    repaint();
}

private void addMenu() {
    JMenuBar bar = new JMenuBar();
    JMenu menu = new JMenu("Menu");
    bar.add(menu);

    JMenuItem item = new JMenuItem("Add Movie");
    item.addActionListener(new MenuActionListener());
    menu.add(item);

    item = new JMenuItem("Add TV-Show");
    item.addActionListener(new MenuActionListener());
    menu.add(item);

    this.setJMenuBar(bar);
}

private void configurFrame() {
    this.setSize(1205, 850);
    this.setTitle("Video Library");
    this.setLocationRelativeTo(null);
    this.setResizable(false);
    this.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
    this.setIconImage(new ImageIcon("E:\\Dropbox\\Dropbox\\Programmering\\Java\\Projekt IV 1\\icon.png").getImage());

    try {
        java.net.URL where = new URL("https://dl.dropboxusercontent.com/u/16670644/Projekt/BackGround.png");
        ImageIcon image = new ImageIcon(where);
        JLabel imageLabel = new JLabel(image);
        this.add(imageLabel);
    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        System.out.println("Error loading Background that makes the background image");
        e.printStackTrace();
    }
}

private void addComponents() {
    JPanel shelfs = buildShelfs();
    this.add(shelfs);
}

private JPanel buildShelfs() {
    JPanel mediaPanel = new JPanel();
    int nrOfMedias = myMediaHandler.mediaList.size();
    mediaPanel.setOpaque(false);
    mediaPanel.setLayout(new GridLayout(3,6,22,30));
    mediaPanel.setBounds(90, 25, 1020, 745);

            java.net.URL where;
            for(int i = 0; i < nrOfMedias; i++) {
                String temp = myMediaHandler.mediaList.get(i).getImagePath();
                try {
                    where = new URL(temp);
                    ImageIcon image = new ImageIcon(where);
                    JLabel imageLabel = new JLabel(image);
                    mediaPanel.add(imageLabel);
                } catch (MalformedURLException e) {
                    // TODO Auto-generated catch block
                    System.out.println("Error loading user media picture");
                    e.printStackTrace();
                }
            }

        java.net.URL where1;
        try {
            for(int i = nrOfMedias; i < 18; i++) {
                where1 = new URL("https://dl.dropboxusercontent.com/u/16670644/Projekt/TempPic.png");
                ImageIcon image1 = new ImageIcon(where1);           
                JLabel imageLabel1 = new JLabel(image1);
                mediaPanel.add(imageLabel1);
            }

        } catch (MalformedURLException e) {
            // TODO Auto-generated catch block
            System.out.println("Error loading TempPic that shows allowed media spots");
            e.printStackTrace();
        }

        return mediaPanel;
}

public static void main(String[] arg) {
    Window mainWindowGUI = new Window();
    mainWindowGUI.setVisible(true);
}   
}

What i'm trying to do now is from another class calling the rapaint function.

public class MediaHandler {
ArrayList<Media> mediaList;

private Window myWindow;

public MediaHandler(Window window) {
    this.mediaList = new ArrayList<Media>();
    myWindow = window;
}

public void addMovie(String title, Double playTime, int year,
        String directory, String mediaPath, String imagePath, String quality,
        boolean subtitles, String language, String writer) {
    mediaList.add(new Movie(title, playTime, year, false, directory, mediaPath, imagePath, rating.unrated, quality, subtitles, language, writer));

    myWindow.getContentPane().invalidate();
    myWindow.invalidate();

}   
}

Please let me know if there is anything which is unclear! I have been stuck on this problem for a few days now.

Was it helpful?

Solution

It's a lot of code, and not really cleanly structured and so. But as far as I can see, the problem can not solved by only "repaining" anything. The problem is that the labels (showing the media images) are not added to the shelf.

You are currently calling the buildShelfs method once, when the frame is constructed. When you are later adding a new movie via the MediaHandler, you are adding this movie to the mediaList. But you are not adding a new label/image to the mediaPanel.

This can probably be solved as follows: You can declare the mediaPanel as an instance variable. And you can offer a method to add a new ImageIcon to this panel, with an image that was read from a particular URL (given as a String). This method can on the one hand be used during the initialization (that is, during the first call to buildShelfs). But more importantly: You can also call this method from the MediaHandler, so that a new ImageIcon is added to the mediaPanel whenever a new movie is added in the MovieHandler.

I tried to sketch the basic idea in the following code. But again, the structure of the current code is not really nice and clean, so there was some guesswork involved....

class Window ... 
{
    // Store this as an instance variable
    private JPanel mediaPanel;


    private JPanel buildShelfs()
    {
        mediaPanel = new JPanel();
        mediaPanel.setOpaque(false);
        mediaPanel.setLayout(new GridLayout(3, 6, 22, 30));
        mediaPanel.setBounds(90, 25, 1020, 745);
        for (int i=0; i<18; i++)
        {
            addMedia(i);
        }
        return mediaPanel;
    }


    private void addMedia(int index)
    {
        // You should store these images LOCALLY!!!
        String urlString = "https://dl.dropboxusercontent.com/u/16670644/Projekt/TempPic.png";

        int nrOfMedias = myMediaHandler.mediaList.size();
        if (index < nrOfMedias)
        {
            urlString = myMediaHandler.mediaList.get(i).getImagePath();
        }
        addMedia(urlString);
    }

    void addMedia(String urlString)
    {
        try
        {
            java.net.URL where = new URL(urlString);
            ImageIcon image = new ImageIcon(where);
            JLabel imageLabel = new JLabel(image);
            mediaPanel.add(imageLabel);
            mediaPanel.invalidate();
            mediaPanel.validate();
        }
        catch (MalformedURLException e)
        {
            System.out.println("Error loading user media picture from "+urlString);
            e.printStackTrace();
        }
    }

}




class MediaHandler 
{
    ArrayList<Media> mediaList;

    private Window myWindow;

    public MediaHandler(Window window) 
    {
        this.mediaList = new ArrayList<Media>();
        myWindow = window;
    }

    public void addMovie(String title, Double playTime, int year,
        String directory, String mediaPath, String imagePath, String quality,
        boolean subtitles, String language, String writer) 
    {
        mediaList.add(new Movie(title, playTime, year, 
            false, directory, mediaPath, imagePath, rating.unrated, 
            quality, subtitles, language, writer));

        myWindow.addMedia(mediaPath);
    }   
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top