简体   繁体   English

如何在Swing / AWT中侦听Window的“ visible”属性?

[英]How to listen for “visible” property of Window in Swing/AWT?

There is a bean property "visible", which is represented by getter isVisible() and setter setVisible() in class Window . 有一个bean属性“ visible”,由Window类中的getter isVisible()和setter setVisible()

How to listen for this value? 如何听这个值?

I would like to implement popular "view" menu with check box with binding library. 我想用带有绑定库的复选框来实现流行的“视图”菜单。 Unfortunately I can't see how to bind "visible" property of a window. 不幸的是,我看不到如何绑定窗口的“可见”属性。 Even I can't write translator, because I see no any predefined way to listen for this property: 甚至我也无法编写翻译器,因为我看不到任何预定义的方法来监听此属性:

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);




                }
            });

        }
    }

The method documentation for Component.addPropertyChangeListener clearly lists the properties that are being observed. Component.addPropertyChangeListener方法文档明确列出了正在观察的属性。 The visibility state is not listed. 可见性状态未列出。 And as a JFrame (or one of its super classes up to Component ) does not add any new behavior, you cannot observe changes to the visibility state on a JFrame . 而且,由于JFrame (或属于Component的其超类之一)没有添加任何新行为,因此您无法观察到JFrame上可见性状态的变化。

However, you could subclass JFrame with overriding the setVisible method. 但是,您可以通过重写setVisible方法来JFrame In this new implementation you can fire such a property change: 在这个新的实现中,您可以触发这样的属性更改:

public class VisibleAwareFrame extends JFrame {
    public void setVisible(boolean b) {
        boolean visible = isVisible();
        super.setVisible(b);
        firePropertyChange("visible", visible, b);
    }
}

Try Global AWT Event Listener 尝试全局AWT事件侦听器

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);

Here is the some outputs 这是一些输出

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)

You can put checks on source as well as event type on paramString . 您可以对源进行检查,也可以对paramString事件类型检查。 Check for COMPONENT_HIDDEN and COMPONENT_SHOWN event and based on event change or set the visible property. 检查COMPONENT_HIDDENCOMPONENT_SHOWN事件并基于事件更改或设置visible属性。 It might help you. 它可能会帮助您。

The visible property is not really bound to the WindowsListener , but to the ComponentListener because it belong to the Component class, not the Window class. visible属性不是真正绑定到WindowsListener ,而是绑定到ComponentListener因为它属于Component类,而不是Window类。

In order to listen to changes in the visible property, the componentShown(ComponentEvent e) method of the ComponentListener needs to be implmented. 为了侦听visible属性中的更改,需要使用ComponentListenercomponentShown(ComponentEvent e)方法。 It is always easier to inheret from the adapters, so in this case: 从适配器中插入总是比较容易的,因此在这种情况下:

frame2.addComponentListener(new ComponentAdapter() {

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

} }

The adapters have empty implementions of the listeners, eg ComponentAdapter class which has empty implementations of the methods in ComponentListener , and WindowAdapter from WindowListener . 适配器具有听众的空implementions,例如ComponentAdapter类,其具有的在所述方法中的空实现ComponentListener ,和WindowAdapterWindowListener

For more details, see Component Adapter , Component Listener , and How to Write a Component Listener and 有关更多详细信息,请参见组件适配器组件侦听器如何编写组件侦听器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM