什么决定了 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 中的组件可见性?的主要内容,如果未能解决你的问题,请参考以下文章