AncestorListener
とComponentListener
を使用して変更の可視性を監視するHierarchyListener
、JPanel
またはJComponents
に関するいくつかのルール、または良い/悪い経験はありますか?
それらの1つは他のものよりも優れているか、安全ですか? JPanel
/JComponent
がいつ、どのように非表示になるかについて、特に知りたいです。
次のコードには、Thread.sleep(int)
を使用するなどの不正なSwingルールが含まれていることに注意してください。この場合、Swing GUIでListeners
の正しい順序を出力できます。
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
がComponent
に追加されておらず、したがってまったく表示されていない場合でもContainer
になります。
その可視性aの目的は少し異なります。これを使用して、すでに追加され、アプリケーションのどこかに表示されているComponent
を手動で非表示にすることができます。その場合(setVisible(false)
を使用すると)非表示になり、そのComponentListener
のすべてのComponent
にその変更が通知されます。
それで、実際の可視性について話します...
これはactualコンポーネントの出現/消失をリッスンするために使用すべきものです:
_ 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
}
} );
_
私は常にそのリスナーを使用して、Component
がどこに追加されたかを判断し、移動または削除されたときにリッスンします。
また、isShowing()
メソッドを呼び出すことで、Component
が実際にアプリケーションユーザーに表示されるかどうかを常に確認できます。
_boolean userCanSeeThePanel = panel.isShowing();
_
これは、そのパネルがユーザーフレームのVISIBLEに追加され、isVisible()
フラグもtrueの場合にのみtrue
を返します(true
に設定しない限り、通常はfalse
です)。
可視性についてお伝えできることはこれだけです。あなたの質問を誤解したかもしれません。その場合、私が間違っていれば訂正してください。