Java JPanel更改哪一个侦听器适合可见性
对于Java JPanel更改哪一个侦听器适合可见性,java,swing,listener,jpanel,jcomponent,Java,Swing,Listener,Jpanel,Jcomponent,对于AncestorListener、ComponentListener或HierarchyListener使用JPanel和JComponents监听更改的可见性,是否有一些规则或好/坏的经验 其中一个比其他的好还是安全?我特别想知道JPanel/JComponent何时以及如何隐藏 请注意,下面的代码包含不正确的Swing规则,例如在本例中使用Thread.sleep(int),以允许我在Swing GUI中打印出正确的侦听器顺序 import java.awt.BorderLayout;
AncestorListener
、ComponentListener
或HierarchyListener
使用JPanel
和JComponents
监听更改的可见性,是否有一些规则或好/坏的经验
其中一个比其他的好还是安全?我特别想知道JPanel
/JComponent
何时以及如何隐藏
请注意,下面的代码包含不正确的Swing规则,例如在本例中使用Thread.sleep(int)
,以允许我在Swing GUI中打印出正确的侦听器顺序
import java.awt.BorderLayout;
import java.awt.CardLayout;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.HierarchyEvent;
import java.awt.event.HierarchyListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.event.AncestorEvent;
import javax.swing.event.AncestorListener;
public class CardlayoutTest extends JFrame {
private static final long serialVersionUID = 1L;
public CardLayout card = new CardLayout();
public CardlayoutTest() {
JPanel pnlA = new JPanel(new BorderLayout());
pnlA.add(new JButton("A"), BorderLayout.CENTER);
JPanel pnlB = new JPanel(new BorderLayout());
pnlB.add(new JButton("B"), BorderLayout.CENTER);
JPanel pnlC = new JPanel(new BorderLayout());
pnlC.add(new JButton("C"), BorderLayout.CENTER);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setLayout(card);
add(pnlA, "A");
add(pnlB, "B");
add(pnlC, "C");
pnlA.addAncestorListener(new EventHandler());
pnlB.addAncestorListener(new EventHandler());
pnlC.addAncestorListener(new EventHandler());
pnlA.addHierarchyListener(new EventHandler());
pnlB.addHierarchyListener(new EventHandler());
pnlB.addHierarchyListener(new EventHandler());
pnlA.addComponentListener(new EventHandler());
pnlB.addComponentListener(new EventHandler());
pnlB.addComponentListener(new EventHandler());
}
class EventHandler implements AncestorListener, ComponentListener, HierarchyListener {
@Override
public void ancestorAdded(AncestorEvent event) {
System.out.println("CardlayoutTest.EventHandler.ancestorAdded()");
}
@Override
public void ancestorMoved(AncestorEvent event) {
System.out.println("CardlayoutTest.EventHandler.ancestorMoved()");
}
@Override
public void ancestorRemoved(AncestorEvent event) {
System.out.println("CardlayoutTest.EventHandler.ancestorRemoved()");
}
@Override
public void hierarchyChanged(HierarchyEvent e) {
System.out.println("Components Change: " + e.getChanged());
if ((e.getChangeFlags() & HierarchyEvent.DISPLAYABILITY_CHANGED) != 0) {
if (e.getComponent().isDisplayable()) {
System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged());
} else {
System.out.println("Components DISPLAYABILITY_CHANGED : " + e.getChanged());
}
}
if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0) {
if (e.getComponent().isDisplayable()) {
System.out.println("Components SHOWING_CHANGED : " + e.getChanged());
} else {
System.out.println("Components SHOWING_CHANGED : " + e.getChanged());
}
}
}
public void componentHidden(ComponentEvent e) {
System.out.println(e.getComponent().getClass().getName() + " --- Hidden");
}
public void componentMoved(ComponentEvent e) {
System.out.println(e.getComponent().getClass().getName() + " --- Moved");
}
public void componentResized(ComponentEvent e) {
System.out.println(e.getComponent().getClass().getName() + " --- Resized ");
}
public void componentShown(ComponentEvent e) {
System.out.println(e.getComponent().getClass().getName() + " --- Shown");
}
}
public static void main(String[] args) {
CardlayoutTest t = new CardlayoutTest();
t.setSize(500, 500);
System.out.println("CardlayoutTest.main()------------------------ FIRST");
t.card.show(t.getContentPane(), "A");
t.setVisible(true);
System.out.print("\n");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("CardlayoutTest.main()------------------------ SECOND");
t.card.show(t.getContentPane(), "B");
System.out.print("\n");
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
}
System.out.println("CardlayoutTest.main()------------------------ THIRD");
t.card.show(t.getContentPane(), "C");
System.out.print("\n");
}
}
如果您想准确地监听可见性更改,请使用ComponentListener
或ComponentAdapter
:
JPanel panel = new JPanel ();
panel.addComponentListener ( new ComponentAdapter ()
{
public void componentShown ( ComponentEvent e )
{
System.out.println ( "Component shown" );
}
public void componentHidden ( ComponentEvent e )
{
System.out.println ( "Component hidden" );
}
} );
但这种可见性可能不是你所想的isVisible()
标志将为true
,即使组件
未添加到任何容器
,因此根本不显示
这种可见性有一个稍微不同的目的。您可以使用它手动隐藏已添加并显示在应用程序某处的组件。在这种情况下,(如果使用setVisible(false)
),它将被隐藏,并且该组件的每个ComponentListener
都将被告知该更改
所以,说到实际能见度
这是您应该用来收听实际组件外观/消失的内容:
JPanel panel = new JPanel ();
panel.addAncestorListener ( new AncestorListener ()
{
public void ancestorAdded ( AncestorEvent event )
{
// Component added somewhere
}
public void ancestorRemoved ( AncestorEvent event )
{
// Component removed from container
}
public void ancestorMoved ( AncestorEvent event )
{
// Component container moved
}
} );
我总是使用该侦听器来确定何时将组件添加到某处,以及何时将其移动/删除
此外,通过调用isShowing()
方法,您始终可以检查组件是否对应用程序用户实际可见:
boolean userCanSeeThePanel = panel.isShowing();
仅当该面板被添加到“用户可见”框架并且isVisible()
标志也为真时,才会返回true
(通常为true
,除非将其设置为false
)
我想这就是我能告诉你的关于能见度的所有信息。我可能误解了你的问题。如果我在这种情况下错了,请纠正我。@mKorbel如果您仍然不了解可视性的某些部分,请随时询问更多信息。在Swing中,当已经可见的JComponent(更改为)隐藏时,捕获适当的事件是一个相当棘手的部分。如果更改是通过“setVisible(false)”方法进行的,则使用ComponentListener或ComponentAdapter。在“componentHidden”中,当组件被隐藏(“setVisible(false)”调用)时,您将收到通知;在“ComponentShowed”中,当组件被显示(“setVisible(true)”调用)时,您将收到通知,直到现在一切都清楚,如我的SSCCE所示,所有三个侦听器都触发了预期事件,那么,问题是什么呢?您正在为适当的事件使用适当的侦听器。。。我想在这种情况下没什么可说的了。或者你发现了其他问题?