简体   繁体   中英

Java: How to nest JPanel in a GridLayout?

I want to know how to nest JPanel s using a GridLayout . This is how it should look like.

在此输入图像描述

I approached this problem by 2 ways so far,

  • using JPanel s and
  • using JLabel s,

and none of them worked (only the first panel created is shown).

Here is the code for the JPanel approach:

    int x=20, y=20;
    JPanel [] panels = new JPanel[3];
    JLabel animal = new JLabel(new ImageIcon(getClass().getResource("Pictures/animal.gif")));
    JLabel map = new JLabel(new ImageIcon(getClass().getResource("Pictures/map.gif")));
    JLabel mountain = new JLabel(new ImageIcon(getClass().getResource("Pictures/mountain.gif")));

    for(int i=0;i<panels.length;i++)
    {
        if(i>0)
        {
            x+=x;
            y+=y;
        }
        panels[i] = new JPanel(new GridLayout(2,2));
        panels[i].setPreferredSize(new Dimension(x,y));

        if(i==0)
            panels[i].add(new JPanel());

        else
            panels[i].add(panels[i-1]);

        panels[i].add(mountain);
        panels[i].add(map);
        panels[i].add(animal);
    }       
    add(panels[2]);

One option is to create a class that will represent a panel divided into the grid with the images. The only issue would be the top left quadrant which would usually contain the nested panel, at some point you want this to contain just a blank panel. So maybe something like this (barring various optimizations):

 class GridPanel extends JPanel{

    JLabel mountain, map, animal;

    public GridPanel(JPanel panel){
        super();
        setLayout(new GridLayout(2, 2));
        animal = new JLabel(new ImageIcon(getClass().getResource("pictures/animal.gif")));
        map = new JLabel(new ImageIcon(getClass().getResource("pictures/map.gif")));
        mountain = new JLabel(new ImageIcon(getClass().getResource("pictures/mountain.gif")));
        add(panel);
        add(mountain);
        add(map);
        add(animal);
    }

}

Notice that it accepts the panel that is to be displayed in the top left corner of the grid. This coud then be called with the panel specified. So at the point where you want to create the main panel:

   JPanel grid = new GridPanel(new JPanel()); //initial
    for(int i = 1; i <= 5; i++){
        grid = new GridPanel(grid);
    }
    add(grid);

The initial grid is created with a blank JPanel. And every subsequent grid will contain the previous one as the top left panel. You have to resize your images and such and maybe even avoid loading the images multiple times etc. But that is another question. This example shows 5 nested panels.

Just to be clear, you should use ImageIO to load the images once and reuse the images. For example You can create a BufferedImage like this in your main class:

  BufferedImage mointainImg = ImageIO.read(new File("pictures/mountain.gif"));

And when you want to create the JLabel you can do this:

  mountain = new JLabel(new ImageIcon(mountainImg));

And the advantage is that you can manipulate the image a bit if you want.

One issue that you have is that the images are not scaled. To scale images, use Image.getScaledInstance() . Proper scaling would at least fix the problem of the visible images being cut off. It also might cause the other images to be shown as they might just be hiding behind the visible images because they are too big.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM