Как прослушать «видимое» свойство Window в Swing / AWT?

1

Существует свойство bean-компонента "visible", которое представлено getter isVisible() и setter setVisible() в Window класса.

Как слушать это значение?

Я хотел бы реализовать популярное меню "view" с флажком с библиотекой привязки. К сожалению, я не вижу, как привязать "видимое" свойство окна. Даже я не могу писать переводчик, потому что я не вижу предопределенного способа прослушивания этого свойства:

package tests;

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.awt.event.WindowStateListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;

import javax.swing.AbstractAction;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;

    public class Try_Swing2 {

        public static void main(String[] args) {

            SwingUtilities.invokeLater(new Runnable() {

                @Override
                public void run() {


                    final JFrame frame2 = new JFrame();
                    frame2.addWindowStateListener(new WindowStateListener() {

                        @Override
                        public void windowStateChanged(WindowEvent e) {

                            System.out.println("windowState.newState = " + e.getNewState());


                        }
                    });

                    frame2.addWindowListener(new WindowListener() {

                        @Override
                        public void windowOpened(WindowEvent e) {
                            System.out.println("windowOpened");
                        }

                        @Override
                        public void windowIconified(WindowEvent e) {
                            System.out.println("windowIconified");

                        }

                        @Override
                        public void windowDeiconified(WindowEvent e) {
                            System.out.println("windowDeiconified");

                        }

                        @Override
                        public void windowDeactivated(WindowEvent e) {
                            System.out.println("windowDeactivated");
                        }

                        @Override
                        public void windowClosing(WindowEvent e) {
                            System.out.println("windowClosing");
                        }

                        @Override
                        public void windowClosed(WindowEvent e) {
                            System.out.println("windowClosed");
                        }

                        @Override
                        public void windowActivated(WindowEvent e) {
                            System.out.println("windowActivated");
                        }
                    });

                    frame2.addPropertyChangeListener("visible", new PropertyChangeListener() {

                        @Override
                        public void propertyChange(PropertyChangeEvent evt) {
                            System.out.println("visible = " + evt.getNewValue());
                        }
                    });

                    frame2.setDefaultCloseOperation(JFrame.HIDE_ON_CLOSE);

                    frame2.setTitle("This window is controlled by another window");

                    frame2.setSize(800, 600);
                    frame2.setLocationRelativeTo(null);
                    frame2.setVisible(true);

                    AbstractAction toggleAction = new AbstractAction("Toggle another window visibility") {

                        @Override
                        public void actionPerformed(ActionEvent e) {
                            frame2.setVisible( !frame2.isVisible() );
                        }

                    };


                    JButton toggleButton = new JButton(toggleAction);

                    JFrame frame1 = new JFrame();

                    frame1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                    frame1.setTitle("This windows controls");
                    frame1.setLayout(new FlowLayout());
                    frame1.add(toggleButton);


                    frame1.pack();
                    frame1.setLocation(0, 0);
                    frame1.setVisible(true);




                }
            });

        }
    }
  • 1
    свойство бина "видимое" нет, это не свойство бина. Вам понадобится адаптер, который прослушивает windowEvents и сопоставляет их со свойством bean-компонента, а затем привязывает ваш клиент к этому адаптеру.
  • 2
    Вы можете использовать ComponentListener и переопределить componentShown и componentHidden . Это похоже на природу
Теги:
swing
awt

3 ответа

2

В документации метода для Component.addPropertyChangeListener четко перечислены свойства, которые наблюдаются. Состояние видимости не указано. И поскольку JFrame (или один из его супер-классов до Component) не добавляет никакого нового поведения, вы не можете наблюдать изменения состояния видимости на JFrame.

Однако вы можете подклассифицировать JFrame с переопределением метода setVisible. В этой новой реализации вы можете запустить такое изменение свойства:

public class VisibleAwareFrame extends JFrame {
    public void setVisible(boolean b) {
        boolean visible = isVisible();
        super.setVisible(b);
        firePropertyChange("visible", visible, b);
    }
}
  • 1
    подклассы являются неоптимальными - и не помогут, если кадр не полностью находится под контролем связующего кода. Вместо этого используйте адаптер (это моя сегодняшняя строка тега ;-), который отображает windowEvents на надлежащие свойства bean-компонента. Кроме того, запуск некорректен, так как вы не можете знать, действительно ли новый видимый объект b после вызова super - как правило, всегда запрашивать новое свойство при запуске.
  • 0
    Какие адаптеры вы говорите целый день? Почему вы держите в секрете?
Показать ещё 3 комментария
0

Свойство visible самом деле не связано с WindowsListener, а с ComponentListener потому что оно принадлежит классу Component, а не классу Window.

Чтобы прослушать изменения в visible свойстве, необходимо componentShown(ComponentEvent e) метод componentShown(ComponentEvent e) ComponentListener. Из адаптеров всегда легче выйти, поэтому в этом случае:

frame2.addComponentListener(new ComponentAdapter() {

    @Override
    public void componentShown(WindowEvent e) {
        System.out.println("Component is Visible");
    }

}

Адаптеры имеют пустые implementions слушателей, например, ComponentAdapter класс, который имеет пустые реализации методов в ComponentListener и WindowAdapter от WindowListener.

Для получения дополнительной информации см. Компонентный адаптер, компонентный прослушиватель и как написать компонентный прослушиватель и

0

Попробуйте прослушиватель Global AWT Event Listener

long eventMask = AWTEvent.COMPONENT_EVENT_MASK;

Toolkit.getDefaultToolkit().addAWTEventListener(new AWTEventListener() {
    public void eventDispatched(AWTEvent e) {
        String paramString = e.paramString();
        System.out.println(paramString);
    }
}, eventMask);

Вот некоторые результаты

COMPONENT_RESIZED (0,0 500x500)
COMPONENT_HIDDEN
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_RESIZED (4,23 492x473)
COMPONENT_MOVED (4,23 492x473)
COMPONENT_RESIZED (0,0 492x473)
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_MOVED (0,0 500x500)
COMPONENT_SHOWN
COMPONENT_MOVED (0,0 500x500)
COMPONENT_MOVED (0,0 500x500)
COMPONENT_RESIZED (0,0 500x500)
COMPONENT_HIDDEN
COMPONENT_RESIZED (0,0 494x475)
COMPONENT_MOVED (0,0 494x475)

Вы можете помещать проверки на источник, а также тип события в paramString. Проверьте событие COMPONENT_HIDDEN и COMPONENT_SHOWN и на основе изменения события или установите visible свойство. Это может помочь вам.

  • 1
    правда, но не в этом суть вопроса ;-)

Ещё вопросы

Сообщество Overcoder
Наверх
Меню