3

有一个 bean 属性“可见”,它由class 中的 getterisVisible()和 setter表示。setVisible()Window

如何监听这个值?

我想用绑定库的复选框实现流行的“视图”菜单。不幸的是,我看不到如何绑定窗口的“可见”属性。即使我不会编写翻译器,因为我看不到任何预定义的方式来监听这个属性:

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




                }
            });

        }
    }
4

3 回答 3

2

方法文档Component.addPropertyChangeListener清楚地列出了正在观察的属性。可见性状态未列出。并且由于 a JFrame(或其超类之一Component)不添加任何新行为,因此您无法观察到 a 上可见性状态的变化JFrame

但是,您可以JFrame通过覆盖该setVisible方法进行子类化。在这个新实现中,您可以触发这样的属性更改:

public class VisibleAwareFrame extends JFrame {
    public void setVisible(boolean b) {
        boolean visible = isVisible();
        super.setVisible(b);
        firePropertyChange("visible", visible, b);
    }
}
于 2014-03-28T13:10:44.913 回答
2

visible属性并没有真正绑定到WindowsListener,而是绑定到 ,ComponentListener因为它属于Component类,而不是Window类。

为了监听visible属性的变化,需要实现的componentShown(ComponentEvent e)方法。ComponentListener从适配器继承总是更容易,所以在这种情况下:

frame2.addComponentListener(new ComponentAdapter() {

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

}

适配器具有侦听器的空实现,例如具有 in和fromComponentAdapter方法的空实现的类。ComponentListenerWindowAdapterWindowListener

有关详细信息,请参阅组件适配器组件侦听器如何编写组件侦听器

于 2016-04-16T20:34:43.283 回答
1

尝试全局 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);

这是一些输出

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_HIDDENCOMPONENT_SHOWN事件并基于事件更改或设置visible属性。它可能会帮助你。

于 2014-03-28T14:18:22.160 回答