Search code examples
javajtabletablecellrenderer

JTable: get object location inside a cell


I can't figure out how to solve this problem:

I have a JTable with a custom cell renderer. Inside a cell renderer I put a JLabel with a grid bag layout.

If I try to obtain the location of the JLabel inside the renderer, I always get 0, 0. I tried to revalidate the JLabel before but I'm not able to find a correct solution.

This is the code of the custom renderer:

public CustomRenderer() {
    // set the renderer layout to null
    setLayout(new GridBagLayout());
    // create the layouts label
    layoutsLbl = new JLabel("Layout");
    // create a grid bag constraints instance
    GridBagConstraints gbc = new GridBagConstraints();
    // first column
    gbc.gridx = 0;
    // first row
    gbc.gridy = 0;
    // maximum horizontal weight
    gbc.weightx = 1;
    // anchor to the top left corner
    gbc.anchor = GridBagConstraints.FIRST_LINE_START;
    // fill horizontally
    gbc.fill = GridBagConstraints.HORIZONTAL;
    // set the insets
    gbc.insets = new Insets(35, 0, 10, 0);
    // add the layouts label to the view
    add(layoutsLbl, gbc);
}

public String clickCheck() {
    // revalidate the layouts label
    layoutsLbl.revalidate();
    // get the layouts label location
    System.out.println("Label location: " + layoutsLbl.getLocation());
}

I know that in some cases I might be able to calculate the JLabel location because it is fixed, but I would like to have a general approach because I need it for a renderer where I have a lot of dinamically generated JLabel.

The final goal is to find the location of each JLabel to be able to identify which JLabel has been clicked with a MouseListener attached to the table. I'm able to find the clicked cell, the mouse location in the cell and therefore I need the JLabel location in the cell to test it against the mouse location.


Solution

  • The final goal is to find the location of each JLabel to be able to identify Blockquote which JLabel has been clicked with a MouseListener attached to the table.

    This Problem is pretty easy to solve. Just use this simple Code snippet to get the clicked Object.

    this.addMouseListener(new MouseListener() {
            @Override
            public void mouseClicked(MouseEvent e) {
    
                Component clicked = getComponentAt(e.getPoint());
                if(clicked instanceof JLabel){
                    JLabel myLabel = (JLabel) clicked;
                    //obviously myLabel is the clicked JLabel
                    System.out.println("Clicked Label: " + myLabel.getLocation());
                }
    
            }
    
            @Override
            public void mousePressed(MouseEvent e) {
    
            }
    
            @Override
            public void mouseReleased(MouseEvent e) {
    
            }
    
            @Override
            public void mouseEntered(MouseEvent e) {
    
            }
    
            @Override
            public void mouseExited(MouseEvent e) {
    
            }
        });
    

    Using the getLocation() Method will now give you the real Location the JLabel has.

    UPDATE: Here is the requested complete Example (Using JTable instead)

    This is my Main:

    public static void main(String[] args) {
        JFrame frame =  new JFrame();
        frame.setContentPane(new CostumTable());
        frame.getContentPane().addMouseListener(new MouseListener() {
    
            @Override
            public void mouseClicked(MouseEvent e) {
    
                Component clicked = frame.getContentPane().getComponentAt(e.getPoint());
                if(clicked instanceof JLabel){
                    JLabel myLabel = (JLabel) clicked;
                    //obviously myLabel is the clicked JLabel
                    System.out.println("Text of clicked Label: " + myLabel.getText());
                }
    
            }
            @Override
            public void mousePressed(MouseEvent e) {
    
            }
            @Override
            public void mouseReleased(MouseEvent e) {
    
            }
            @Override
            public void mouseEntered(MouseEvent e) {
    
            }
            @Override
            public void mouseExited(MouseEvent e) {
    
            }
    
        });
    
        frame.setSize(200, 500);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
    

    and this would be the CustomRenderer (now CostumTable):

        public CostumTable() {
        // set the renderer layout to GridBagLayout
        setLayout(new GridBagLayout());
        // create the layouts label
        layoutsLbl = new JLabel("Layout");
        // create a grid bag constraints instance
        GridBagConstraints gbc = new GridBagConstraints();
        // first column
        gbc.gridx = 0;
        // first row
        gbc.gridy = 0;
        // maximum horizontal weight
        gbc.weightx = 1;
        // anchor to the top left corner
        gbc.anchor = GridBagConstraints.FIRST_LINE_START;
        // fill horizontally
        gbc.fill = GridBagConstraints.HORIZONTAL;
        // set the insets
        gbc.insets = new Insets(35, 0, 10, 0);
        // add the layouts label to the view
        add(layoutsLbl, gbc);
    
    
        //Just here to test the MousListener
        List<JLabel> testLabel = new ArrayList<>();
        for(int i = 0; i < 3; i++) {
            testLabel.add(new JLabel("TestLabel number " + i));
            gbc.gridx = 0;
            gbc.gridy = i + 1;
            add(testLabel.get(i), gbc);
        }
        //
    }
    
    public String clickCheck() {
        // revalidate the layouts label
        layoutsLbl.revalidate();
        // get the layouts label location
        System.out.println("Label location: " + layoutsLbl.getLocation());
        return null; //I dont know what you want to return
    }