【问题标题】:java repaint blocks out jbuttonjava重绘阻止jbutton
【发布时间】:2012-08-24 23:14:34
【问题描述】:

在我的paintComponent() 方法中,我有一个绘制jpanel 背景的drawRect()。但是因为在调用paintComponent() 方法之前jbutton 是在屏幕上绘制的,所以jbutton 被drawRect 挡住了。有谁知道如何解决这一问题?我的猜测是在调用 repaint 之前添加 jbutton,但我不知道该怎么做?

一些代码:

public Frame(){
  add(new JButton());
}

public void paintComponent(Graphics g){
  super.paintComponent(g);
  g.drawRect(0,0,screenwidth,screenheight); //paints the background with a color 
                                            //but blocks out the jbutton.
}

【问题讨论】:

  • Frame 是否扩展 JFrame
  • 这确实是个奇怪的代码,因为我同意 Jeffrey 的观点,您似乎正试图为 JFrame 类重写 paintComponent(...) 方法,这是不应该发生的。请在您的 paintComponent(...) 方法之前添加一个 @Override。确保您覆盖 paintComponent(...)not paintComponents(...),因为它们之间存在差异。如果您能发布sscce 让我们亲眼看到和体验您的问题,那就太好了。
  • 你做错了什么?你怎么修好它的?请注意,发布实际代码而不是无关代码几乎总是更好。
  • @HovercraftFullOfEels 事实上,这不可能发生。 JFrame 没有 paintComponent 方法。
  • 艾文:这就是问题所在。当我们还不知道是什么导致了您的主要问题时,我们不能忽略任何错误。这就是为什么发布真实代码几乎总是最好的。

标签: java swing graphics jbutton jcomponent


【解决方案1】:

现在,首先,我会告诉你你做错了什么——JFrame 不是JComponent,并且没有paintComponent 可供你覆盖。您的代码可能永远不会被调用。除此之外,drawRect 仅仅绘制了一个矩形——它填充了一个。


但是,我相信有一种适当的方法可以做到这一点。

由于您使用的是JFrame,因此您应该通过JFrame.getLayeredPane 来利用容器的分层窗格

分层窗格是一个具有深度的容器,这样重叠的组件可以一个在另一个之上。有关分层窗格的一般信息位于How to Use Layered Panes。本节讨论根窗格如何使用分层窗格的细节。

根窗格包含在 Java 教程的一部分 How to Use Root Panes 中。分层窗格是根窗格的子窗格,JFrame 作为顶级容器利用底层JRootPane

无论如何,既然您对创建背景感兴趣,请参阅下图了解分层窗格在顶级容器中的一般外观:

下表描述了每一层的预期用途,并列出了与每一层对应的 JLayeredPane 常量:

层名称 - - 描述

FRAME_CONTENT_LAYER - new Integer(-30000) - 根窗格在此深度将菜单栏和内容窗格添加到其分层窗格中。

由于我们要指定我们的背景在内容的后面,所以我们先将其添加到同一层(JLayeredPane.FRAME_CONTENT_LAYER),如下:

final JComponent background = new JComponent() {

  private final Dimension size = new Dimension(screenwidth, screenheight);

  private Dimension determineSize() {
    Insets insets = super.getInsets();
    return size = new Dimension(screenwidth + insets.left + insets.right,
        screenheight + insets.bottom + insets.top);
  }

  public Dimension getPreferredSize() {
    return size == null ? determineSize() : size;
  }

  public Dimension getMinimumSize() {
    return size == null ? determineSize() : size;
  }

  protected void paintComponent(final Graphics g) {
    g.setColor(Color.BLACK);
    g.fillRect(0, 0, screenwidth, screenheight);
  }
};
final JLayeredPane layeredPane = frame.getLayeredPane();
layeredPane.add(background, JLayeredPane.FRAME_CONTENT_LAYER);

现在,为了确保我们在内容之前绘制背景,我们使用JLayeredPane.moveToBack

layeredPane.moveToBack(background);

【讨论】:

  • 图片来自Oracle Java教程
  • @HovercraftFullOfEels 确实如此,点击教程链接后很容易看到。
  • @HovercraftFullOfEels - 是的,我知道(我确实阅读了教程;)) - 但你一定喜欢漂亮的图片;)
  • 如果我直接在没有 jpanel 的 jframe 上绘图怎么办?
  • @veer 如果我直接在没有 jpanel 的 jframe 上绘图怎么办?
【解决方案2】:

我做了这个非常快速的测试。正如 HovercraftFullOfEels 指出的那样。 JFrame 没有paintComponent,所以我使用了JPanel

这是由这段代码产生的

public class PanelTest extends JPanel {

    private JButton button;

    public PanelTest() {

        setLayout(new GridBagLayout());

        button = new JButton("Can you see me ?");
        add(button);

    }

    @Override
    protected void paintComponent(Graphics g) {

        super.paintComponent(g);

        Rectangle bounds = button.getBounds();
        bounds.x -= 10;
        bounds.y -= 10;
        bounds.width += 20;
        bounds.height += 20;

        g.setColor(Color.RED);
        ((Graphics2D)g).fill(bounds);

    }

}

我尝试通过在JFrame 上使用paintComponents 来复制问题,但我没有看到矩形。即使我在JFrame 上覆盖paint,矩形仍会绘制在按钮下方(我也不建议这样做)。

问题是,你没有给我们足够的代码来知道出了什么问题

ps - drawRect 不会“填充”任何东西

【讨论】:

  • 我猜有一些难闻的代码正在运行,也许他正试图从 paintComponent 中添加组件——很难猜到。
  • @HovercraftFullOfEels 这可能是一个重量级/重量级的问题,我只是在做出疯狂的假设,这绝不是一个聪明的主意:P
  • 需要gridbaglayout吗?
  • @Ewen 不,我只想将按钮放在窗格上,以免它尝试填充可用区域。这只是一个例子而已
  • 好的,另外,你能做 add(new JButton());在paintComponent()里面?
【解决方案3】:

我之前遇到过这种情况,虽然不是专门针对 jframe 的,也不是您所拥有的那种场景。试试这段代码,

    this.getContentPane.repaint();

在您的 jframe 上。我不确定,但请尝试一下。

【讨论】:

  • 这有什么作用?你能解释更多吗?
  • 自从我完成 java GUI 以来已经有一段时间了,但它只是重新加载或清理框架中的每个组件。清理意味着不删除您的绘图,而是完善您组件上的设计声明。我不确定java文档是如何解释的,这只是基于我自己的理解。每当我必须在 jDesktopPane 中加载图片时,我都会使用此代码。
  • 我认为,如果您在代码中的某处正确声明了代码 sn-p(即在您绘制矩形之后),代码 sn-p 将起作用。祝你好运!
猜你喜欢
  • 2012-05-27
  • 2018-02-04
  • 1970-01-01
  • 1970-01-01
  • 2012-10-18
  • 1970-01-01
  • 2017-07-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多