什么决定了 Java 中的组件可见性?

Posted

技术标签:

【中文标题】什么决定了 Java 中的组件可见性?【英文标题】:What determines component visibility in Java? 【发布时间】:2016-02-14 04:12:36 【问题描述】:

我正在编写一个使用 JFrame 对象和几个 JPanel 对象的 Java GUI 程序。 JPanel 对象使用paint() 和repaint() 方法,并且一些JPanel 对象具有JLabels 和JButton。当我运行程序时,这些不同的组件中的一些不以我希望的方式可见,即似乎有些组件隐藏了其他组件。

是什么决定了程序运行时哪些组件是可见的?它取决于组件添加到***容器的顺序,还是每个对象的 paint() 方法被调用的顺序?可以覆盖此默认可见性吗?

编辑:我应该补充一点,一些 JPanel(及其组件)相互重叠。

编辑: 这是一个示例程序。是什么决定了哪些组件在屏幕上可见?例如,为什么 Button1 可见,而 Button2 不可见?

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test1 extends JFrame 

  public Test1() 
    setLayout(null);
    setSize(500, 700);
    setDefaultCloseOperation(EXIT_ON_CLOSE); 
    add(new Test2());
    setVisible(true);
  

  public static void main(String[] args) 
    SwingUtilities.invokeLater(new Runnable() 
      public void run() 
        new Test1();
      
    );
  


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test2 extends JPanel 

  public Test2() 
    setBounds(0, 0, 300, 500);
    setLayout(null);
    add(new Test3());
    add(new Test4());
    setVisible(true);
  

  public void paint(Graphics g) 
    g.drawRect(0, 0, 250, 450);
  


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test3 extends JPanel 

  public Test3() 
    setBounds(0, 0, 300, 300);
    setVisible(true);
  

  public void paint(Graphics g) 
    g.fillRect(40, 50, 200, 150);
  


import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class Test4 extends JPanel 

  public JLabel label1 = new JLabel("Label1");
  public JLabel label2 = new JLabel("Label2");

  public JButton button1 = new JButton("Button1");
  public JButton button2 = new JButton("Button2");

  public Test4() 
    setBounds(0, 300, 300, 200);

    add(label1);
    add(label2);
    add(button1);
    add(button2);

    setVisible(true);
  

【问题讨论】:

每个人都应该继承一个setVisible(boolean newVisibility) 方法。你说得对吗? 对用户可见,还是你的方法? 我认为他不是在质疑setVisible()判断组件是否被渲染的方法,而是组件被渲染的顺序。 我的意思是对用户的可见性。如果组件/图形重叠,哪些在屏幕上可见,即哪些隐藏了其他? 组件可见性的功能与您期望的一样:如果一个组件被一个不透明的组件覆盖,那么下面被覆盖的部分就不会被看到。我有一种感觉,有一个隐藏的潜在问题是这个问题的起源,除非你用相关的代码为我们详细说明,否则你不可能解决你遇到的任何具体问题,包括你的minimal reproducible example。谁知道呢,解决方案可能就像使用 CardLayout 一样简单,但让我们避免胡乱猜测——请告诉我们详细信息。 【参考方案1】:

我应该补充一点,一些 JPanel(及其组件)相互重叠。

ZOrder 控制绘制组件的顺序。首先绘制具有更高 ZOrder 的组件。

是否取决于组件添加到***容器的顺序

是的,ZOrder 被分配为一个组件被添加到容器中,所以最后添加的组件将首先被绘制。

您可以使用Container 类的setComponentZOrder(...) 方法手动更改ZOrder(从而更改绘制顺序)。例如,如果您拖动一个组件并希望将其绘制在顶部,您可以将其 ZOrder 设置为 0。

您可能想查看Overlap Layout。它允许您控制组件在它们重叠时的显示方式(尽管确实使所有组件的大小相同)

这是一个示例程序。

你永远不应该写这样的应用程序,因为你会遇到各种各样的问题:

    不要使用空布局管理器。 不要覆盖paint()。自定义绘画是通过覆盖 paintComponent() 并确保调用 super.paintComponent(...) 来完成的。 不要将面板堆叠在一起。 JPanel 是不透明的,因此在另一个之上添加组件将隐藏下面的组件。

为什么 Button1 可见,而 Button2 不可见?

Button1 被绘制是因为它有焦点。如果您将鼠标移动到 button2 旁边,它也会被绘制,因为它会响应 mouseOver 事件。

如果调整框架大小,两个按钮都会消失,因为面板将根据 ZOrder 重新绘制。

我真的不知道你想用那个代码做什么。我只能说不要这样做。使用布局管理器。

【讨论】:

感谢 camickr - 这真的很有帮助。我想我写的程序没有完全理解如何使用布局管理器、ZOrder 和绘画。我现在更加专注于我需要学习的内容。

以上是关于什么决定了 Java 中的组件可见性?的主要内容,如果未能解决你的问题,请参考以下文章

Java内存模型之可见性问题

PHP 朋友/包可见性

您是不是使用 Java 中的默认(包)可见性? [关闭]

Plotly Dash:下拉组件回调可见性错误

Java 内部类可见性难题

为啥 java 5+ 中的 volatile 不能确保来自另一个线程的可见性?