Вопрос по swing, java – JPanel, который один из Слушателей подходит для видимости, изменен

22

Есть ли какие-то правила или хороший / плохой опытAncestorListener, ComponentListener или жеHierarchyListener прислушиваясь к видимости изменений сJPanel а такжеJComponents?

Один из них лучше или безопаснее других? Особенно хотелось бы узнать, когда и какJPanel / JComponent скрыт.

Обратите внимание, что следующий код содержит неверные правила Swing, например, использованиеThread.sleep(int)в этом случае, чтобы позволить мне распечатать правильный порядокListeners в 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");
    }
}

Ваш Ответ

1   ответ
35

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 и, следовательно, не показывает вообще!

Эта видимость имеет немного другое назначение. Вы можете использовать его, чтобы вручную скрыть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 где-то добавлен, а также для прослушивания, когда он перемещен / удален.

Кроме того, вы всегда можете проверить, еслиComponent фактически виден пользователю приложения при вызовеisShowing() метод:

boolean userCanSeeThePanel = panel.isShowing();

Это вернетсяtrue ТОЛЬКО если эта панель добавлена в VISIBLE для пользовательского фрейма иisVisible() флаг также верно (обычно этоtrue, если вы не установите его вfalse).

Я думаю, это все, что я могу вам рассказать о видимости. Возможно, я неправильно понял ваш вопрос. Поправь меня, если я ошибаюсь в этом случае.

Так в чем же тогда вопрос? Вы используете подходящих слушателей для правильных событий ... я думаю, в таком случае больше нечего сказать. Или вы нашли какую-то другую проблему?
до этого момента все ясно, как продемонстрировал мой SSCCE, все три слушателя сработали ожидаемые события, mKorbel
в основном мне интересно ловить правильные события, когда уже видимый JComponent скрыт (сменить на) mKorbel
@mKorbel Не стесняйтесь спрашивать больше, если вы все еще не понимаете какую-то часть видимости. Это довольно сложная часть Swing на самом деле
Если изменение сделано с помощью "setVisible (false)" метод - используйте ComponentListener или ComponentAdapter. В & quot; componentHidden & quot; вы получите уведомление, когда компонент скрыт («setVisible (false)» вызван) и в «componentShown» когда он отображается (вызывается "setVisible (true)")

Похожие вопросы