调用重绘后 JButton 出现在错误的位置

JButton showing up in the wrong spot after repaint is called

我正在尝试将几个 JButton 对象添加到我在 Java 中的 GUI 程序中,并且它正在将它们添加到 JPanel(这是程序的主文件)但是它出现在不正确的点。它在点 [0, 0] 处显示 op,并且与其关联的操作发生在正确的位置。面板上的其余元素是图像,因此经常调用重绘方法。

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

"pause" 按钮显示在撤消按钮顶部的原点,但点击在正确的位置唤醒。 2 个按钮应该显示在蓝色框所在的位置,所有其他卡片都是图像。

你不应该覆盖 paint,你应该覆盖 paintComponent。如果您的组件已经添加到面板,它们将自行更新:

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

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

您不必担心按钮如何更新,如果您使用得当,面板会为您处理。也不要使用 setLayout(null)。我们有布局管理器是有原因的,使用具有您需要的功能的布局管理器或编写您自己的。

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

我认为绝对没有理由移动 "Undo" 和 "Pause" 按钮。这些按钮应该添加到使用流式布局的面板中。然后将面板添加到框架的北边。

摆脱空布局。

去掉 setPreferredSize() 语句。布局管理器将确定按钮的大小。

So I needed to override paint().

永远不要覆盖 JFrame 的 paint() 方法。该方法的默认实现负责绘制已添加到框架中的组件。

阅读 Swing 教程中关于 How to Use Buttons 的部分,了解工作示例和构建代码的更好方法。

编辑:

您不应覆盖框架上的 paint()。

如果您想进行自定义绘画,您可以覆盖 JPanelpaintComponent(...) 并将面板添加到框架中。

如果你想在这个面板上添加一些按钮,你可以这样做:

JPanel buttonPanel = new JPanel();
buttonPanel.add(undoButton);
buttonPanel.add(pauseButton);
buttonPanel.setSize( buttonPanel.getPreferredSize() );
buttonPanel.setLocation(100, 0);
paintingPanel.add( buttonPanel );