JButton showing up in the wrong spot after repaint is called

不问归期 提交于 2021-02-10 20:21:33

问题


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:


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.




回答2:


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 );


来源:https://stackoverflow.com/questions/29782303/jbutton-showing-up-in-the-wrong-spot-after-repaint-is-called

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!