【问题标题】:Java setOpaque method not working to add panels over the top of othersJava setOpaque 方法无法在其他面板之上添加面板
【发布时间】:2016-06-23 23:56:40
【问题描述】:

我试图将两个面板放在另外两个面板的顶部,因此位置完全匹配。这将允许我在之前(底部)面板的顶部进行绘画。这样做的原因是我实现了“拖动矩形”缩放功能,所以在面板上用户将拖动鼠标绘制一个矩形,然后面板将被该矩形的内容填充。但是,我现在决定在用户​​拖动矩形时包含矩形的视觉表示。

由于我(假设)我无法在底部面板上绘制矩形,因为它上面已经有复杂的油漆,我想我可以将它绘制到另一个面板上,然后放在上面。 (如果有更简单的方法请喊!)

我很高兴能够使用 BorderLayout/GridLayout 组合将面板置于正确的位置,而无需绝对定位,但是 setOpaque 方法不适用于我添加的三个面板中的任何一个。有人知道为什么吗?

非常感谢,代码如下:

public void initiate() {
    JPanel panel1 = new JPanel();
    mandPanel mandDisplay = new mandPanel(); 
    juliaPanel juliaDisplay = new juliaPanel(); 
    JPanel detailsPanel = new JPanel();
    JPanel bottomDetails = new JPanel();
    JPanel panelForDisplays = new JPanel();
    JPanel listenerPanelHolder = new JPanel();
    JPanel listenerPanel = new JPanel();
    JPanel blankPanel = new JPanel();

    panelForDisplays.setLayout(new GridLayout(1,2));
    detailsPanel.setLayout(new FlowLayout());
    bottomDetails.setLayout(new FlowLayout());
    panel1.setLayout(new BorderLayout());


    panelForDisplays.add(mandDisplay);
    panelForDisplays.add(juliaDisplay);

    listenerPanelHolder.setOpaque(false);
    listenerPanel.setOpaque(false);
    blankPanel.setOpaque(false);
    listenerPanelHolder.setLayout(new GridLayout(1,2));
    listenerPanelHolder.add(listenerPanel);
    listenerPanelHolder.add(blankPanel);


    panel1.add(detailsPanel,BorderLayout.NORTH);
    panel1.add(panelForDisplays,BorderLayout.CENTER);
    panel1.add(listenerPanel,BorderLayout.CENTER);
    panel1.add(bottomDetails, BorderLayout.SOUTH);



    setContentPane(panel1);
    setSize(width*2, height);
    setResizable(false);

    this.addWindowListener(new onClose(savedJulias));
    setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    setVisible(true);
}

PS:省略了很多代码以避免混乱,但如果有人认为他们可以用更多代码解决,请说!谢谢:)

【问题讨论】:

  • "A lot of code is omitted to avoid mess..." -- 可能太多了。你当然不想用代码压倒我们,但最好是创建一个新的程序,小,为我们编译、运行和演示你的问题,但没有任何与你的问题无关的无关代码,a有效minimal reproducible example。请点击链接阅读这个有价值的工具。
  • 也许您实际上想要使用 JLayeredPane 或使用顶级窗口的玻璃窗格,....或者这可能是伪装的 XY 问题,最好的解决方案是使用完全不同的方法。请告诉我们更多关于整体问题的信息。我自己,我仍然不完全确定你想要做什么。
  • 您的部分问题是我认为您误解了 BorderLayout。在 CENTER 位置添加两个组件会将第一个组件替换为第二个,因此第二个不会覆盖第一个,而是取代它。
  • XY 问题,我的意思是,也许你最好的选择是做一些不同的事情,比如 not 来为矩形创建一个单独的 JPanel。例如,this answer of mine with code 显示了在图像上绘制矩形并使用它放大图像(Mandelbrot 集图像)的示例。这是你想要做的吗?
  • 嗨,满载鳗鱼的气垫船 - 感谢您的快速回复。我将再次尝试解释,然后开始编写一个较小的程序来演示该问题。我有一个具有网格布局的 JPanel (panelForDisplays),其中还有两个面板(mandDisplay 和 juliaDisplay)。顾名思义,它们分别绘制了 Mandelbrot 集和 JuliaSet。我的程序的另一部分是放大,允许用户在 mandDisplay 面板上拖动一个矩形,然后放大这个矩形。我想直观地表示矩形,并假设最好的方法是放置...

标签: java swing jpanel awt


【解决方案1】:

首先,在 BorderLayout.CENTER 位置添加两个组件会将第一个组件替换为第二个,因此第二个不会覆盖第一个,而是取代它。根据BorderLayout API

每个区域可能包含不超过一个组件,...

话虽如此,但我更详细地了解您的问题,我认为您最好的解决方案是不使用 JLayeredPane 或覆盖两个 JPanel。最好的解决方案实际上是直接在显示图像的 JPanel 上绘图。这并不难做到,也不应该使您的代码过于复杂。 For example.

【讨论】:

  • 你好。我现在尝试从您的代码中实现该方法,但遇到了问题。我认为这是因为我们的代码略有不同,因为我的代码使用 paintComponant() 方法绘制 Mandelbrot 集,并且仅在拖动完成时才调用 repaint()。因此我认为在拖动鼠标时绘制矩形,每次鼠标移动时都必须调用repaint,这显然非常密集。
  • @T.Davidson:您不想在paintComponent 中编写耗时的代码,我建议您尽可能在后台线程中执行此操作。 SwingWorker 可以很好地解决这个问题,因为它具有可用的机制,允许您在它完成任务时收到通知,以及在 GUI 和后台线程之间进行简单且线程干净的通信的机制。
  • 装满鳗鱼的气垫船——老实说,很多东西对我来说都是新的!如果这是唯一的方法,我将对此进行研究并查看您的代码。非常感谢
  • @T.Davidson:您当前流程的问题在于,GUI 的感知响应性部分取决于paintComponent 运行的速度,因此,此方法必须精简且意思是,并且其中没有任何长时间运行的代码。不要担心新概念——我敢打赌,你会很快掌握它们的。
【解决方案2】:

您可以使用JLayeredPane 将一个组件放在另一个组件的顶部。可以查看this

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-01-13
    • 2012-01-16
    • 1970-01-01
    • 1970-01-01
    • 2012-06-06
    • 1970-01-01
    • 2015-01-23
    相关资源
    最近更新 更多