1

I am trying to add a couple of JButton objects to my GUI program in Java and it is adding them to the JPanel (which is the main file of the program) but it is appearing in the incorrect spot. It is showing op at point [0, 0] and the action that is linked to it is happening at the correct spot. The rest of the elements on the panel are Images so the repaint method is called very often.

   private void init()
 {
      setLayout(null);
      setBackground(new Color(r, g, b));
      addMouseListener(this);
      addMouseMotionListener(this);

      setSize(681, 700);
      setPreferredSize(new Dimension(681, 700));
      Insets insets = getInsets();

      //wrong spot (click at [302, 5])
      undoButton = new JButton("Undo");
       undoButton.addActionListener(this);        //button 1
       undoButton.setActionCommand("undo");
       undoButton.setVisible(true);
      add(undoButton);

      pause = new JButton("pause");
      pause.addActionListener(this);
      pause.setActionCommand("pause");          //button 2
      pause.setVisible(true);
      pause.setEnabled(true);
      add(pause);

       Dimension size = undoButton.getPreferredSize();
       undoButton.setBounds(100 + insets.left, 15 + insets.top, size.width, size.height);

       size = pause.getPreferredSize();
       pause.setBounds(100 + insets.left + undoButton.getPreferredSize().width, 15 + insets.top, size.width, size.height);


       try{
            undoButton.setMultiClickThreshhold(500);
       }
       catch (Exception e)
       {}
       //... more code ...
}

   public void paint (Graphics g)
{
      //...paint the rest of the elements...

      undoButton.update(g);
      pause.update(g);
 }

The "pause" button is showing up at the origin on top of the undo button but the clicks is woking at the correct spots. The 2 buttons should be showing up where the blue box is and all of the other cards are Images. enter image description here

  • 1
    why don't you simply leave the painting to the panel? –  Apr 21 '15 at 20:20
  • 3
    I'd recommend avoiding, at all costs, using a null layout. And do not override the paint method – copeg Apr 21 '15 at 20:22
  • Because there are components that are moved around and need to be repainted very often and those need to be manually painted. So I needed to override paint(). If I did not do the undoButton.update(g); pause.update(g); Then the buttons would not be displayed. (I will add a picture when it allows me to of the current display) – Marshall Asch Apr 21 '15 at 20:23
  • `Then the buttons would not be displayed.` - the buttons are not displayed because you should NOT be overriding paint. This is causing the problem. – camickr Apr 22 '15 at 01:17

2 Answers2

2

You should not be overriding paint, you should be overriding paintComponent. If your components have already been added to the panel, they will update themselves:

public void paintComponent(Graphics g)
{
      super.paintComponent(g);
      //...paint the rest of the elements...

      //undoButton.update(g); BAD!
      //pause.update(g); BAD!
 }

You don't have to worry about how the buttons get updated, the panel will handle that for you if you use it properly. Also do not use setLayout(null). We have layout managers for a reason, use one that has the features you need or write your own.

John
  • 3,769
  • 6
  • 30
  • 49
  • my override of `paint()` was to repaint the rest of items and the `setLayout(null)` I for got to delete when I was changing the way I put in the buttons. So I should override `paintComponent` to repaint the buttons? (I just tried to do that the same way that you have it there and the same thing happened except they did not show up at all. – Marshall Asch Apr 21 '15 at 20:31
  • don't use a null layout, why do you need to use a null layout? You should be overriding paintComponent but you should not be updating other UI elements inside of it. – John Apr 21 '15 at 20:55
  • I got rid of the null layout. I don't think I ever needed it, I saw on one of Oracle sites (I think) that you can set absolute location with a null layout so I tried that, and it did not work. the other elements are not components they are `Images` that are being painted in the spot that I wanted them. would adding the rest of the class file be helpful? (there is a lot of code in it that is unrelated to this issue) – Marshall Asch Apr 21 '15 at 21:01
  • Can I call `paintComponent`? that worked but the button is not showing up (but it is appearing in the correct spot) it is just underneath everything else when paint is called. – Marshall Asch Apr 21 '15 at 21:10
  • 1
    There is no need to override paint() or paintComponent(). Components will paint themselves when they are added to a panel. The painting methods are for creating custom components. – camickr Apr 21 '15 at 21:32
0

Because there are components that are moved around and need to be repainted very often

I see absolutely no reason to ever move the "Undo" and "Pause" buttons. These buttons should be added to a panel with uses a Flow Layout. Then add the panel to the NORTH of the frame.

Get rid of the null layout.

Get rid of the setPreferredSize() statements. The layout manager will determine the size of the buttons.

So I needed to override paint().

You should never override the paint() method of a JFrame. The default implementation of this method is responsible for painting the components that have been added to the frame.

Read the section from the Swing tutorial on How to Use Buttons for working examples and a better way to structure your code.

Edit:

You should NOT override paint() on the frame.

If you want to do custom painting you override paintComponent(...) of a JPanel and add the panel to the frame.

If you want to add some buttons to this panel then you could do something like:

JPanel buttonPanel = new JPanel();
buttonPanel.add(undoButton);
buttonPanel.add(pauseButton);
buttonPanel.setSize( buttonPanel.getPreferredSize() );
buttonPanel.setLocation(100, 0);
paintingPanel.add( buttonPanel );
camickr
  • 321,443
  • 19
  • 166
  • 288
  • there are only 2 buttons and 52 other Images that need to be painted that would not otherwise be painted with out over riding `paint()` and with out `setPreferedSize()` it appears as a tiny little box that is smaller then it should be. and it is not the buttons that are being moved. I will add a picture to the question showing what it currently looks like – Marshall Asch Apr 21 '15 at 21:37
  • buttons showing up has been fixed, the issue was overriding `paint`. They are still not showing up at the correct location. – Marshall Asch Apr 22 '15 at 18:45
  • So change the location. This is the problem with manually setting the location of the components. You are responsible for determining the exact location. – camickr Apr 22 '15 at 19:36
  • I tried usinf `setLocation()` and it did not work I allso tried using `setBounds`. – Marshall Asch Apr 23 '15 at 01:26
  • Saying you used setLocation() doesn't mean anything. Post your [SSCCE](http://sscce.org/) demonstrating the problem. That is create a JFrame that uses a null layout. Then add a panel containing two buttons to the frame. And position the panel however you want. – camickr Apr 23 '15 at 03:18