Gerry
Gerry

Reputation: 79

Second JPanel covers the first one

I am a beginner with programming and I have been struggling with the following problem for some time.

I have a list of BufferedImages (this.docList). At the moment I am trying to put the images onto a JPanel and put that panel inside a JScrollPane.

If I have more than one image, the second image seems to cover the first one. With the following code I make and send the ScrollPane to the method getPanel which, when it is finished returns a JPanel containing the ScrollPane which contains the Panel(s) containing the BufferedImages. Which are then added to the JFrame.

public void processView(SecondaryProcessPanel secondary){
    this.setLayout(new BoxLayout(this.getContentPane(),BoxLayout.Y_AXIS));

    JScrollPane imageHolder = new JScrollPane();
    //imageHolder.setLayout(new BoxLayout(imageHolder BoxLayout.Y_AXIS));
    JScrollPane panelBack = secondary.getPanel(imageHolder);
    panelBack.setPreferredSize(new Dimension(800,800));
    this.add(panelBack, 0);

    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setSize(600, 800);
    this.pack();

}

The method getPanel goes through the list of BufferedImages. When it has finished the JPanel that this class is extended from is added to the JScrollPane and sent back to the processView method.

public JScrollPane getPanel(JScrollPane imageHolder) {      
    for (int j = 0; j< this.docList.size(); j++){
        image = this.docList.get(j);               
    }
    imageHolder = new JScrollPane(this);    

    return imageHolder;
}

@Override
public void paint(Graphics g) {
    g.drawImage(image, 0,0, null);
}

What ever way around I put it all I can get back from a list of two images is the second image.

Any help greatly appreciated.

After your kind answers I have changed my code back to what I had originally!

 public void processView(SecondaryProcessPanel secondary){
    this.setLayout(new BoxLayout(this.getContentPane(),BoxLayout.Y_AXIS));
        for (int i = 0; i < this.docList.size(); i++){
            System.out.println("i = " + i);
        JScrollPane imageHolder = new JScrollPane();

        JScrollPane panelBack = secondary.getPanel(this.docList.get(i), imageHolder);
        panelBack.setPreferredSize(new Dimension(800,800));
        this.add(panelBack, i);
        }


    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setSize(600, 800);
    this.pack();

}

 public JScrollPane getPanel(BufferedImage image, JScrollPane imageHolder){

        this.image = image;


        imageHolder = new JScrollPane(this);    

    return imageHolder;
}

@Override
public void paint(Graphics g){


        g.drawImage(image, 0,0, null);
        }

My problem remains that if the docList ArrayList contains more than one BufferedImage then I only get output from the second image.

Upvotes: 0

Views: 91

Answers (2)

gpasch
gpasch

Reputation: 2682

This takes the last image on the list - I dont understand what logic you are trying to implement but keeping the last image only is what it does - maybe you want to paint each image (you have a box layout add them there vertically) as it is being read

    for (int j = 0; j< this.docList.size(); j++){
                image = this.docList.get(j);

    }

--

My suggestion is as follows

GridLayout gr=new GridLayout(0, 6);
gr.setRows(0); gr.setColumns(6);
JPanel cpanel=new JPanel();
cpanel.setLayout(gr);
 for (int j = 0; j< this.docList.size(); j++){
    image = this.docList.get(j);
            JLabel jl=new JLabel(new ImageIcon(image));
  cpanel.add(jl);
}
this.add(cpanel); // assuming 'this' is the scrollpane you want

and delete the paint method

Upvotes: 0

MadProgrammer
MadProgrammer

Reputation: 347314

The first thing that jumps out at me is the fact that you're violating the painting process...

@Override
public void paint(Graphics g) {
    g.drawImage(image, 0,0, null);
}

First of all, assuming that you're extending from a JPanel, you should be overriding the paintComponent method instead, second of all, you should be calling the methods super method

@Override
protected void paintComponent(Graphics g) {
    super.paintComponent(g);
    g.drawImage(image, 0,0, this);
}

See Painting in AWT and Swing and Performing Custom Painting for more details about how painting works in Swing.

Second is, WHY? JLabel can display an image just fine. Have a look at How to Use Labels for more details...

And finally...

public void processView(SecondaryProcessPanel secondary){
    this.setLayout(new BoxLayout(this.getContentPane(),BoxLayout.Y_AXIS));
    for (int i = 0; i < this.docList.size(); i++){
        System.out.println("i = " + i);
        JScrollPane imageHolder = new JScrollPane();

        JScrollPane panelBack = secondary.getPanel(this.docList.get(i), imageHolder);
        panelBack.setPreferredSize(new Dimension(800,800));
        this.add(panelBack, i);
    }


    this.setDefaultCloseOperation(EXIT_ON_CLOSE);
    this.setSize(600, 800);
    this.pack();

}

public JScrollPane getPanel(BufferedImage image, JScrollPane imageHolder){

    this.image = image;
    imageHolder = new JScrollPane(this);    

    return imageHolder;
}

This all just looks very suspicious, it look like you're trying to add the same instance of a component to multiple JScrollPane's, assigning a different image to the single instance each time...

So, this basically will remove the instance of the component from it's previous parent and then add it to the new container (JScrollPane) and supply a new instance of a BufferedImage for it to draw, basically ignoring every that came before it.

In the future, consider providing a runnable example which demonstrates your problem. This is not a code dump, but an example of what you are doing which highlights the problem you are having. This will result in less confusion and better responses

So, what you'll end up with is a lot of empty JScrollPanes, but with one which is displaying the last image in the list...

Upvotes: 1

Related Questions