2012-08-24 52 views
0

在我的paintComponent()方法中,我有一个drawRect()绘制jpanel的背景。但是因为在paintComponent()方法被调用之前jbutton被绘制在屏幕上,所以jbutton被drawRect屏蔽掉了。有谁知道如何解决这一问题?我的猜测是在repaint被调用之前添加jbutton,但我不知道该怎么做?java 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. 
} 
+1

“框架”是否扩展了“JFrame”? – Jeffrey

+1

这真是奇怪的代码,因为我同意Jeffrey的看法,你好像试图重写一个不应该发生的JFrame类的'paintComponent(...)'方法。请在'paintComponent(...)'方法之前放置'@ Override'。确保你重写'paintComponent(...)'和** not **'paintComponents(...)',因为有一个** big **的区别。如果您可以发布[sscce](http://sscce.org)让我们亲眼看到并亲身体验您的问题,那就太好了。 –

+0

好吧,我编辑了这篇文章,这只是一个示例代码,我很快输入了不是我的实际项目 – Ewen

回答

5

我这样做真的快速测试。正如Hovercraft FullOfEels指出的那样。 JFrame没有paintComponent,所以我用JPanel代替。

Can you see me

这是由这个代码

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不会“补”什么

+2

我猜测有一些不好闻的代码正在进行,也许他试图从paintComponent中添加组件 - 很难猜到。 –

+0

+1个不错的例子 –

+1

@HovercraftFullOfEels它可能是一个沉重的/轻量级的问题,我只是做出狂野的假设,这从来不是一个聪明的主意:P – MadProgrammer

6

现在,首先,我会告诉你什么你”在这里做错了 - JFrame不是JComponent,并且没有paintComponent供您覆盖。你的代码可能永远不会被调用。除此之外,drawRect只画一个矩形 - 它确实是而不是填充一个。


但是,我相信有一个正确的方法来做到这一点。

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

分层窗格是一个容器,其深度使得重叠的组件可以相互重叠。关于分层窗格的一般信息在How to Use Layered Panes。本节讨论根面板如何使用分层窗格的细节。

根窗格覆盖在How to Use Root Panes,Java教程的一部分。分层窗格是根窗格的子项,作为顶层容器的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); 
+0

+1一个很好的描述(和漂亮的图片) – MadProgrammer

+1

图片来自Oracle Java教程 –

+0

@MadProgrammer谢谢! :-) – oldrinb

1

我以前也遇到过这一点,虽然没有明确,而不是JFrame的那种,你有情景。试试这个代码,

this.getContentPane.repaint(); 

在你的jframe上。林不知道这一点,但试试看。

+0

这是什么?你能解释更多吗? – Ewen

+0

自从我完成java GUI以来,它已经有一段时间了,但它只是重新加载或清除一个框架中的每个组件。清除意味着不删除您的图纸,但抛光组件上的设计声明。我不知道java文档如何解释它,这只是基于我自己的理解。无论何时我必须在jDesktopPane中加载图片,我都会使用此代码。 – user1577161

+0

我认为如果你在你的代码中正确地声明它的代码片段(即绘制矩形后),代码片段就可以工作。祝你好运! – user1577161