Search code examples
javaimagegridgridbaglayoutcoordinate

How to get image's coordinate on JPanel


This question is related to my previous question How to generate Cartesian Coordinate (x,y) from GridBaglayout?

I have successfully get the coordinate of each pictures, however when I checked the coordinate through (System.out.println) and the placement of the images on the screen, it seems to be wrong. e.g. if on the screen it was obvious that the x point of the first picture is on cell 2 which is on coordinate of 20, but the program shows x=1.

Here is part of the code:

public Grid (){

  setPreferredSize(new Dimension(600,600)); 
  ....
  setLayout(new GridBagLayout());
  GridBagConstraints gc = new GridBagConstraints();
  gc.weightx = 1d; 
  gc.weighty = 1d;
  gc.insets = new Insets(0, 0, 0, 0);//top, left, bottom, and right 
  gc.fill = GridBagConstraints.BOTH; 

  JLabel[][] label = new JLabel[ROWS][COLS];         
  Random rand = new Random();

  // fill the panel with labels
  for (int i=0;i<IMAGES;i++){
    ImageIcon icon = createImageIcon("myPics.jpg");
    int r, c;
    do{   
  //pick random cell which is empty
     r = (int)Math.floor(Math.random() * ROWS);
        c = (int)Math.floor(Math.random() * COLS); 
    } while (label[r][c]!=null);

    //randomly scale the images                
    int x = rand.nextInt(50)+30;
    int y = rand.nextInt(50)+30;                  
    Image image = icon.getImage().getScaledInstance(x,y, Image.SCALE_SMOOTH);
    icon.setImage(image);

    JLabel lbl = new JLabel(icon); // Instantiate GUI components 
    gc.gridx = r;
    gc.gridy = c;         
    add(lbl, gc); //add(component, constraintObj);         
    label[r][c] = lbl; 
}

I checked the coordinate through this code:

Component[] components = getComponents();     
for (Component component : components) {
   System.out.println(component.getBounds());
}

Solution

  • You can use SwingUtilities convertPointToScreen() and convertPointFromScreen() to convert between screen and component coordinates.

    Addendum: Here's a simple example I used when trying to understand how components move and resize under the influence of a layout manager.

    public class MyPanel extends JPanel {
    
        public MyPanel() {
            super(new GridLayout(4, 4));
            for (int i = 0; i < 16; i++) {
                JPanel panel = new JPanel(new GridLayout());
                panel.add(new CenterLabel());
                this.add(panel);
            }
        }
    
        private static void create() {
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.add(new MyPanel());
            f.pack();
            f.setVisible(true);
        }
    
        public static void main(String[] args) {
            EventQueue.invokeLater(new Runnable() {
    
                @Override
                public void run() {
                    create();
                }
            });
        }
    
        private static class CenterLabel extends JLabel {
    
            public CenterLabel() {
                this.setHorizontalAlignment(JLabel.CENTER);
                this.setVerticalAlignment(JLabel.CENTER);
                this.setOpaque(true);
                this.setBackground(Color.lightGray);
                this.setBorder(BorderFactory.createLineBorder(Color.blue));
                this.setPreferredSize(new Dimension(160, 100));
                this.addComponentListener(new ComponentAdapter() {
    
                    @Override
                    public void componentResized(ComponentEvent e) {
                        int w = e.getComponent().getWidth();
                        int h = e.getComponent().getHeight();
                        CenterLabel.this.setText("[" + w/2 + "\u253C" + h/2 + "]");
                    }
                });
            }
        }
    }