【问题标题】:How to create independent JPanel-Layers within JFrame and repaint each indiviually如何在 JFrame 中创建独立的 JPanel-Layers 并单独重绘每个
【发布时间】:2016-11-10 11:49:24
【问题描述】:

我正在寻找一种将多个JComponents 相互叠加(重叠)并且仍然能够单独访问和更改它们的方法。

例如用透明背景绘制三个JPanels - 每个都包含一个圆形、一个矩形或一条线。 之后,我想改变圆圈的外观。其他两个不应重新绘制(类似于 Photoshop 中的图层)。

我当前的项目有一个包含数千行的Jpanel,如果我每次重绘完整的Jpanel 非常滞后,我需要在鼠标悬停时更改后面的矩形。

有没有一种体面的方法来实现这一点?已经感谢您的想法!

【问题讨论】:

  • 更好的方法是使用一个 JPanel 和几个 BufferedImages 作为图层。按顺序绘制每个 BufferedImage,注意不要绘制透明区域。您必须为动画的每一帧清除并重新绘制整个绘图区域。此外,您的绘图面板paintComponent 方法应该只是绘画。没有计算。除了 Graphics2D 方法之外别无他法。最后一种选择是为您的几何图形建模,并从模型中绘制图形。
  • 看看我的Moving Eyes 回答,了解如何在 Swing 中设置绘图面板。
  • 听起来可以解决我的问题! BufferedImages 作为图层 - 我会试试的!谢谢!

标签: java swing jcomponent jlayeredpane


【解决方案1】:

我需要在后面换一个矩形

你可以调用:

panel.repaint(rectangle); // or 
panel.repaint(x, y, width, height);

指定要重新绘制的矩形区域。

【讨论】:

  • 感谢您的快速答复。但在我的场景中,所有 jpanels 都直接位于彼此之上 - 所以它们具有相同的边界框。 IE。重新绘制矩形会导致所有其他层完全重新绘制。基本上矩形相当于背景。
  • 没错。 Swing 将查看您要重绘的组件并查看其所有父组件,直到找到具有不透明背景的组件。然后它在该位置绘制背景和所有子组件。这是为了确保该区域完全没有人工制品。我的建议是不要绘制整个面板的矩形,而只绘制更改的面板的一个子集。因此,当您更改圆圈时,您只会重新绘制圆圈完全包含的区域。
  • @MatthiasK,重新绘制包含圆形、矩形和线条的面板不是问题。我一次画了数百个物体没有问题。你一定有其他绘画问题。
  • 感谢您的提示!在我的项目中,我实际上正在绘制大量(>10000)条路径(边缘超过 100 条的线) - 所以重绘不是一种选择。部分重绘也很困难,因为线条遍布整个地方,并且只有中间的小点..我需要的是某种透明层,您可以绘制一次并随时显示和隐藏 - 无需任何计算工作...猜猜 Gilbert Le Blanc 的提示可能是正确的方法 - 使用缓冲图像 - 我一定会看看!
【解决方案2】:

它工作得很好 - 如果其他人有类似的问题,这是我的代码! 第一张图像可以存储并稍后显示(buff) 确保再次显示时生成新的 BufferedImage(此处为画布),否则透明度会丢失。感谢吉尔伯特·勒布朗

@Override
protected void paintComponent(Graphics g1) {
    //Create image:
    BufferedImage buff = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_INT_ARGB);

    //write to image:
    Graphics2D g2 = (Graphics2D) buff.getGraphics();
    g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,(float) 0.01f));
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2.draw(xxxRectanglewhatever);

    //then - later draw image again
    BufferedImage canvas = new BufferedImage(mywidth, myheight, BufferedImage.TYPE_INT_ARGB);
    canvas.getGraphics().drawImage(buff, 0, 0, null);
    ((Graphics2D) g1).setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
    g1.drawImage(canvas, 0, 0, null);
    canvas.flush();
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-04-17
    • 2017-10-13
    • 1970-01-01
    • 2019-11-19
    • 2012-05-05
    • 2018-04-19
    • 1970-01-01
    相关资源
    最近更新 更多