3

I am trying to programmatically create a background grid for a project I am working on. The problem is that the first item I add to the jpanel is always painted at center of the jpanel. I am expressly trying to put it at the top right. I have even tried just placing a dummy jlabel down first and going from there but then the second and third element just overlap each other. This bug has me thoroughly dumbfounded. Any help would be great.

 private void evalWindow(){
    window.removeAll();
    window.setBorder(BorderFactory.createLineBorder(Color.black));
    JLabel p = new JLabel(new ImageIcon(tiles[0][0].getImage()));
    p.setLocation(0,0);

    System.out.println("1: " + p.getLocation());
    p.setSize(64,64);
    window.add(p);
    System.out.println("2: " + p.getLocation());
    for(int i = 0; i < x; i++){
        for (int j = 0; j  < y; j++){
            JLabel piclabel = new JLabel(new ImageIcon(tiles[i][j].getImage()));
            piclabel.setSize(64,64);
            piclabel.setLocation(64*j, 64*i);

            System.out.println("1: " + piclabel.getLocation());
            window.add(piclabel);
        }
    }
}

sample image:

https://i.stack.imgur.com/DlSgb.png

Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433
zlb323
  • 106
  • 1
  • 7
  • 3
    `I am trying to programmatically create a background grid` - Don't reinvent the wheel. Swing was designed to be used with layout managers. The default layout manager overrides the size/location of the component. In your case use a `GridLayout`. See the Swing tutorial on [Layout Manager](https://docs.oracle.com/javase/tutorial/uiswing/layout/visual.html) for more information and working examples. – camickr Feb 18 '18 at 02:22
  • 1
    1) For better help sooner, post a [MCVE] or [Short, Self Contained, Correct Example](http://www.sscce.org/). 2) *`window.removeAll();`* Use a [`CardLayout`](http://download.oracle.com/javase/8/docs/api/java/awt/CardLayout.html) as shown in [this answer](http://stackoverflow.com/a/5786005/418556). 3) *"I am expressly trying to put it at the top right."* co-ordinates `0,0` are at the top **left** of a component. – Andrew Thompson Feb 18 '18 at 02:24
  • Ok I'll keep that in mind in the future, I meant top left I just wasn't thinking when I put that up – zlb323 Feb 19 '18 at 03:08

2 Answers2

2

You do not tell us the type of the variable "window", but I'll assume it's a JFrame or something else that will take a layout manager. Components on Swing windows are not normally placed with absolute positions like 0,0; they are added to containers which are set to use an extension of LayoutManager, and the LayoutManager class manages where the components added to it will go.

FlowLayout adds things in order; GridLayout puts things in equal-size cells on a grid; BorderLayout allows placement in one of 5 areas, etc. The LayoutManager scheme saves you from having to mess with positioning while the user changes the size of the outer window, allows some elements to grow and shrink with available overall size, etc.

If you must place things with absolute positions, there is a NullLayoutManager, but in over 20 years of Java programming and a number of different Swing applications, I've never seen one.

Read about LayoutManagers. I'm sure whatever one is default for your window variable is placing your component in the center and ignoring the absolute placement.

arcy
  • 12,845
  • 12
  • 58
  • 103
2

As mentioned elsewhere, a GridLayout would be the easiest way to layout the grid positions. It can be as simple as:

public void initUI(Image img) {
    ui = new JPanel(new GridLayout(0,8));

    ImageIcon icon = new ImageIcon(img);
    for (int ii=0; ii<32; ii++) {
        ui.add(new JLabel(icon));
    }
}

This is the effect:

enter image description here

Here is the MCVE that produces the above GUI. In future, please post code in the form of an MVCE.

import java.awt.*;
import java.awt.image.*;
import java.io.IOException;
import javax.swing.*;
import javax.imageio.*;
import java.net.URL;

public class ImageGrid {

    private JComponent ui = null;
    String imageURL = "https://i.stack.imgur.com/DlSgb.png";

    ImageGrid() {
        try {
            BufferedImage img = ImageIO.read(new URL(imageURL));
            BufferedImage subImg = img.getSubimage(2, 2, 64, 64);
            initUI(subImg);
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    final public void initUI(Image img) {
        ui = new JPanel(new GridLayout(0,8));

        ImageIcon icon = new ImageIcon(img);
        for (int ii=0; ii<32; ii++) {
            ui.add(new JLabel(icon));
        }
    }

    public JComponent getUI() {
        return ui;
    }

    public static void main(String[] args) {
        Runnable r = () -> {
            try {
                UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
            } catch (Exception useDefault) {
            }
            ImageGrid o = new ImageGrid();

            JFrame f = new JFrame(o.getClass().getSimpleName());
            f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
            f.setLocationByPlatform(true);

            f.setContentPane(o.getUI());
            f.pack();
            f.setMinimumSize(f.getSize());

            f.setVisible(true);
        };
        SwingUtilities.invokeLater(r);
    }
}
Andrew Thompson
  • 168,117
  • 40
  • 217
  • 433