1

我有一个包含一些 JInternalFrames 的 JDesktopPane。我希望仅在选择 JInternalFrames 之一时才激活菜单栏上的某些菜单。我尝试使用 VetoableChangeListener,其中包含以下代码:

JInternalFrame selectedFrame = desk.getSelectedFrame(); 
if ((selectedFrame != null)) {  
    imageMenu.setEnabled(Boolean.TRUE);         
} else {
    imageMenu.setEnabled(Boolean.FALSE);            
}

但结果不是我所期望的——例如,仅在我第二次添加框架时才启用菜单。当我关闭所有框架时,它仍然处于启用状态。

我怎样才能使这项工作?

4

4 回答 4

2

您必须阅读有关JInternalFrames的基本教程,其中包含指向InternalFrameListener的链接,

但另一种看起来更好的方法是以编程方式在所有情况下了解这些事件,并且事件时间是通过添加PropertyChangeListener如示例获取 JDesktopPane Container 中的所有帧,通过添加PropertyChangeListener您可以侦听这些事件

于 2011-08-28T09:00:10.967 回答
1

我只会创建一个自定义事件并在 aJInternalFrame获得焦点 ( isActivated)时触发它。菜单项将侦听此事件,拦截它并相应地设置其状态启用或禁用。这里的优点是您不必处理哪些菜单项应该可用于哪些类型的内部框架,只需触发适当的事件。如果您将来添加更多内部框架,它将使您的生活更轻松。

于 2011-08-28T09:06:29.187 回答
1

向添加到桌面窗格的每个内部框架添加一个InternalFrameListener,每次触发事件时,执行您在问题中显示的代码。

这段代码可以写得更好:

  • setEnabled将原始布尔值作为参数,而不是java.lang.Boolean. 使用trueandfalse而不是Boolean.TRUEand Boolean.FALSE
  • 表达式(selectedFrame != null)计算为布尔值。写吧

imageMenu.setEnabled(selectedFrame != null);

代替

if ((selectedFrame != null)) {  
    imageMenu.setEnabled(Boolean.TRUE);         
} else {
    imageMenu.setEnabled(Boolean.FALSE);            
}
于 2011-08-28T09:07:38.620 回答
0

该答案基于@mKorbel 的答案。此示例显示了一种检测内部帧之间焦点的方法,如下所示:

JInternalFrame 窗口焦点监听器示例

package com.apexroot.sandbox;

import java.awt.Dimension;
import java.awt.EventQueue;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.JDesktopPane;
import javax.swing.JFrame;
import javax.swing.JInternalFrame;
import javax.swing.JLabel;

/**
 * author grants unlimited license to modify, reuse and redistribute. based on 
 * the suggestion by @mKorbel on stackoverflow at
 * http://stackoverflow.com/questions/7219860/jinternalframe-selection
 * please keep a URL to the original version in the source code.
 * http://javajon.blogspot.com/2015/08/windowfocuslistener-for-jinternalframe.html
 *
 * @author Apexroot
 */
public class InternalFrameFocusListenerExample {

    public static final String INTERNAL_FRAME_FOCUS_EVENT_PROPERTY = "selected";

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {

                final JFrame jFrame = new JFrame();
                final JDesktopPane jDesktopPane = new JDesktopPane();
                final JInternalFrame[] jInternalFrames = new FocusInternalFrame[3];
                for (int i = 0; i < jInternalFrames.length; i++) {
                    jInternalFrames[i] = new FocusInternalFrame();
                }
                jFrame.dispose();
                jFrame.setContentPane(jDesktopPane);
                jDesktopPane.setPreferredSize(new Dimension(400, 200));
                jFrame.pack();
                jFrame.setVisible(true);
                for (int i = 0; i < jInternalFrames.length; i++) {
                    jDesktopPane.add(jInternalFrames[i]);
                    jInternalFrames[i].setLocation(10 + 60 * i, 10 + 40 * i);
                    jInternalFrames[i].setVisible(true);
                }

            }

        });

    }

    public static class FocusInternalFrame extends JInternalFrame {

        public FocusInternalFrame() {

            final JLabel jLabel = new JLabel("placeholder for pack();");
            setContentPane(jLabel);
            pack();

            this.addPropertyChangeListener(
                    INTERNAL_FRAME_FOCUS_EVENT_PROPERTY,
                    new LabelFocusListener(jLabel));

        }

    }

    private static class LabelFocusListener implements PropertyChangeListener {

        private final JLabel jLabel;

        public LabelFocusListener(JLabel jLabel) {
            this.jLabel = jLabel;
        }

        @Override
        public void propertyChange(PropertyChangeEvent evt) {
            // please keep a URL to the original version in the source code.
            // http://javajon.blogspot.com/2015/08/windowfocuslistener-for-jinternalframe.html
            if (INTERNAL_FRAME_FOCUS_EVENT_PROPERTY.equals(
                    evt.getPropertyName())) {
                final Object oldValue = evt.getOldValue();
                final Object newValue = evt.getNewValue();
                if (oldValue instanceof Boolean
                        && newValue instanceof Boolean) {
                    boolean wasInFocus = (Boolean) oldValue;
                    boolean isInFocus = (Boolean) newValue;
                    if (isInFocus && !wasInFocus) {
                        EventQueue.invokeLater(new Runnable() {
                            @Override
                            public void run() {

                                // focus gained
                                jLabel.setText("focus gained");
                            }
                        });
                    } else if (wasInFocus && !isInFocus) {
                        EventQueue.invokeLater(new Runnable() {
                            @Override
                            public void run() {

                                // focus lost
                                jLabel.setText("focus lost");
                            }
                        });
                    }
                }
            }
        }
    }
}
于 2015-08-21T16:15:31.823 回答