Results 1 to 11 of 11
  1. #1
    Join Date
    Feb 2010
    Posts
    6
    Rep Power
    0

    Default JButton: getLocationOnScreen() throws Exception

    Hi all,

    i'd like to show a context menu below an "Add" button in a JFrame when that "Add" button is clicked. To determine the location for the context menu I thought calling the getLocationOnScreen() method on "Add" button would give me its location so I can calculate the position to display the context menu.

    However, although the Button (the whole JFrame it is placed in) is visible, the call throws an IllegalComponentStateException. isVisible() returns true. Debugging shows that the JButtons "peer" is null and this is the reason why the exception is thrown.

    What is the "peer" and why is it NULL? How can I get the coords of a button in another way?

    Thanks in advance,
    Sebastian

  2. #2
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,226
    Rep Power
    6

    Default

    Its null because you have a programming bug. Maybe you defined the button twice, once as a class variable and once as a local variable, in which case the class variable is probably null.

    If you need more help post your SSCCE.

  3. #3
    hardwired's Avatar
    hardwired is offline Senior Member
    Join Date
    Jul 2007
    Posts
    1,576
    Rep Power
    8

    Default

    Java Code:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    
    public class Test implements ActionListener {
        JLabel locLabel;
        JLabel screenLocLabel;
    
        public void actionPerformed(ActionEvent e) {
            String id = e.getActionCommand();
            Component c = (Component)e.getSource();
            Point loc = c.getLocation();
            locLabel.setText(id + " loc: [" + loc.x + ", " + loc.y + "]");
            Point screenLoc = c.getLocationOnScreen();
            screenLocLabel.setText(id + " screenLoc: [" + screenLoc.x +
                                   ", " + screenLoc.y + "]");
        }
    
        private JPanel getContent() {
            locLabel = getLabel();
            screenLocLabel = getLabel();
            JPanel center = new JPanel(new GridLayout(0,1));
            center.add(locLabel);
            center.add(screenLocLabel);
            JPanel panel = new JPanel(new BorderLayout());
            panel.setOpaque(true);
            panel.add(getComponent("North"), "First");
            panel.add(center);
            panel.add(getComponent("South"), "Last");
            return panel;
        }
    
        private JLabel getLabel() {
            JLabel label = new JLabel();
            label.setHorizontalAlignment(JLabel.CENTER);
            label.setPreferredSize(new Dimension(200,25));
            return label;
        }
    
        private JPanel getComponent(String id) {
            JButton button = new JButton(id);
            button.setActionCommand(id);
            button.addActionListener(this);
            JPanel panel = new JPanel();
            panel.add(button);
            return panel;
        }
    
        public static void main(String[] args) {
            Test test = new Test();
            JFrame f = new JFrame();
            f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            f.setContentPane(test.getContent());
            f.pack();
            f.setLocation(100,100);
            f.setVisible(true);
        }
    }

  4. #4
    Join Date
    Feb 2010
    Posts
    6
    Rep Power
    0

    Default

    Alright. Thanks very much! It works using the getSource() method on the event and determining the location from it.
    In my code I remembered the JButton in a class field to have access to it later when the actionEvent occurs. But it seems after adding the button to a window you cannot use it. It seems it is not *my* button that lives in the frame, but maybe a copy?

    However, it works great now. Thanks a lot!
    Sebastian

  5. #5
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,226
    Rep Power
    6

    Default

    In my code I remembered the JButton in a class field to have access to it later when the actionEvent occurs. But it seems after adding the button to a window you cannot use it.
    Of course you can reference (use) a button after you add it to the window. Read my suggestion, I gave you a probable reason why the class field is null.

    Having said that, the better solution is to use the getSource() method from the event, then you can start to write more generic code in your listeners and you aren't dependent on class fields.

  6. #6
    Join Date
    Feb 2010
    Posts
    6
    Rep Power
    0

    Default

    Yeah, I read your suggestion but its not the fault. I remember the button in a class field and only in it. There is no local variable. As described in my first post it is *not* the class field which is null. I can call isVisible() on it and everything works but when I call the getLocationOnScreen() method and debugging it, it shows that the buttons peer is null. Its not the button itself. But I dont know what a NullPeer means...

    Regards,
    Sebastian

  7. #7
    Join Date
    Feb 2010
    Posts
    6
    Rep Power
    0

    Default

    BTW: I am not able to reproduce this behaviour in a minimalistic example. Just adding a JButton to a JFrame and calling getLocationOnScreen() works... The real frame from my code is more complex, but I can't see the general difference to my minimalistic example...

  8. #8
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,226
    Rep Power
    6

    Default

    But I dont know what a NullPeer means...
    I'm not sure, but I would guess it means you are trying to determine the buttons location on the screen before adding the button to the frame or before using frame.setVisible(true) or frame.pack(). In other words the frame has not been realized, which means Swing components don't have peers yet. Checking the isVisible() method of the button doesn't do anything since by default all Swing components (other than JFrame, JDialog) are visible by default.

  9. #9
    Join Date
    Feb 2010
    Posts
    6
    Rep Power
    0

    Default

    Yeah, but thats odd, as the whole frame and all its components are visible at the point. I'm clicking on that button in that frame, it must be visible ;)

  10. #10
    camickr is offline Senior Member
    Join Date
    Jul 2009
    Posts
    1,226
    Rep Power
    6

    Default

    The simple explanation is that the class variable "does not" reference the button that is displayed on the visible GUI.

    The fact that you cannot resolve this problem is worrisome. It probably means you have an incorrectly designed class. You may have avoided the Exception but you have not fixed the original problem. So don't be surprised if you come across other problems later.

    Sometimes this happens when two instances of the same class are created twice. The first class gets added to the GUI and the second instance if referenced from the class variables.

  11. #11
    Join Date
    Feb 2010
    Posts
    6
    Rep Power
    0

    Default

    Oh man, what a dumb bug. Just found it yesterday thinking about it while laying in bed ;)

    You are right with "the button on screen and the one stored in my class field are not the same". I added *several* buttons to the GUI into a tabed pane. As all the panes look more or less identically in the GUI, especially considering the button's section, I did not realize there is *more than one* button. When storing the button reference in the class field of course only the last one added was referenced by it and this one is not visible in the GUI when a tabbed pane other than the last is active...

    Camickr, thank you very much for your support and for encouraging me to think about again!

    Greetings,
    Sebastian

    BTW, for anyone who is interested in my app, it's a web start based tool to upload screenshots, files and other clipboard content named Clupper. Give a try, I'd be glad to hear some feedback!

Similar Threads

  1. Applet throws exception while recording
    By Basit56 in forum Java Applets
    Replies: 1
    Last Post: 08-20-2009, 01:42 PM
  2. throws
    By jdgallag in forum New To Java
    Replies: 14
    Last Post: 02-11-2009, 01:07 AM
  3. Exception throws when I read File
    By Juggler in forum New To Java
    Replies: 11
    Last Post: 08-18-2008, 06:09 PM
  4. Main method with throws Exception
    By bugger in forum New To Java
    Replies: 3
    Last Post: 01-07-2008, 02:48 PM
  5. throws Exception
    By javaplus in forum New To Java
    Replies: 1
    Last Post: 11-06-2007, 07:32 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •