1

いくつかの JInternalFrames を含む JDesktopPane があります。JInternalFrames の 1 つが選択されている場合にのみ、メニューバーのいくつかのメニューをアクティブにしたいと考えています。次のコードを含む VetoableChangeListener を使用してみました。

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

しかし、結果は期待したものではありません。たとえば、フレームを 2 回目に追加したときにのみメニューが有効になります。すべてのフレームを閉じても、有効のままです。

どうすればこれを機能させることができますか?

4

4 に答える 4

2

InternalFrameListenerへのリンクを含むJInternalFramesに関する基本的なチュートリアルを読む必要があります。

しかし、別のより良い方法のように見えるのは、すべてのケースでこれらのイベントをプログラムで知ることであり、すべての場合に、PropertyChangeListener追加することです。

于 2011-08-28T09:00:10.967 に答える
1

カスタム イベントを作成し、JInternalFrame aがfocus( isActivated)を取得したときにそれを起動するだけです。メニュー項目はこのイベントをリッスンし、インターセプトして、それに応じてステータスを有効または無効に設定します。ここでの利点は、どのタイプの内部フレームでどのメニュー項目を使用できるようにするかを処理する必要がなく、適切なイベントを発生させるだけでよいことです。将来的に内部フレームを追加すると、生活が楽になります。

于 2011-08-28T09:06:29.187 に答える
1

デスクトップ ペインに追加InternalFrameListenerされた各内部フレームに を追加し、イベントがトリガーされるたびに、質問に示したコードを実行します。

ただし、このコードはより適切に記述できます。

  • setEnabledではなく、プリミティブブール値を引数として取りますjava.lang.Booleantrueandfalseではなく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 による回答に基づいています。この例は、ここに示されているように、内部フレーム間のフォーカスを検出する方法の 1 つを示しています。

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 に答える