Выбор JInternalFrame - PullRequest
       9

Выбор JInternalFrame

1 голос
/ 28 августа 2011

У меня есть JDesktopPane, содержащая некоторые JInternalFrames. Я хочу, чтобы некоторые меню на панели меню были активированы, только когда выбран один из JInternalFrames. Я попытался использовать VetoableChangeListener, со следующим кодом в нем:

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

Но результаты не те, что я ожидал - например, меню включается только при втором добавлении кадра когда я закрываю все кадры, он остается включенным.

Как я могу сделать эту работу?

Ответы [ 4 ]

2 голосов
/ 28 августа 2011

Вы должны прочитать базовый учебник о JInternalFrames со ссылкой на InternalFrameListener ,

но еще один и выглядит, как лучший способ программно узнать это событие во всех случаях и каждый раз, добавив PropertyChangeListener , как показывает примеры Получение всех кадров в контейнере JDesktopPane добавив PropertyChangeListener вы можете прослушивать эти события

1 голос
/ 28 августа 2011

Добавьте InternalFrameListener к каждому внутреннему фрейму, добавленному на панель рабочего стола, и при каждом запуске события выполняйте код, показанный в вашем вопросе.

Этот код может быть лучше написан, хотя:

  • setEnabled принимает в качестве аргумента примитивное логическое значение, а не java.lang.Boolean. Используйте true и false вместо Boolean.TRUE и Boolean.FALSE.
  • Выражение (selectedFrame != null) оценивается как логическое значение. Просто напишите

imageMenu.setEnabled(selectedFrame != null);

вместо

if ((selectedFrame != null)) {  
    imageMenu.setEnabled(Boolean.TRUE);         
} else {
    imageMenu.setEnabled(Boolean.FALSE);            
}
1 голос
/ 28 августа 2011

Я бы просто создал пользовательское событие и запустил его , когда JInternalFrame получает фокус (isActivated) . Пункты меню будут прослушивать это событие, перехватывать его и устанавливать их статус включенным или отключенным соответственно. Преимущество здесь в том, что вам не нужно обрабатывать, какие пункты меню должны быть доступны для каких типов внутренних фреймов, просто запустите соответствующее событие. Это сделает вашу жизнь проще, если вы добавите больше внутренних рамок в будущем.

0 голосов
/ 21 августа 2015

Этот ответ основан на ответе @mKorbel. Этот пример показывает один из способов обнаружения фокуса между внутренними кадрами, как показано здесь:

JInternalFrame Window Focus Listener Example

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
 * /4942768/vybor-jinternalframe
 * 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");
                            }
                        });
                    }
                }
            }
        }
    }
}
...