2011-08-28 212 views
1

我有一個JDesktopPane包含一些JInternalFrames。我希望菜單欄上的某些菜單隻有在選擇了其中一個JInternalFrame時才能激活。我已經嘗試使用VetoableChangeListener,在它下面的代碼:JInternalFrame選擇

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

但結果不出我所料 - 例如,菜單隻啓用了我第二次補充的框架。當我關閉所有框架時,它仍保持啓用狀態。

我該如何做這項工作?

回答

2

一定要仔細閱讀基礎教程關於JInternalFrames與鏈接到InternalFrameListener

但另一個看起來就像是更好的方法是通過程序加入PropertyChangeListener作爲顯示的例子就知道在所有情況下和evety次的事件Getting All Frames in a JDesktopPane Container ,加入PropertyChangeListener可以listeng爲these events

+0

正是醫生吩咐。所用的的PropertyChangeListener和周圍工作的第一次。謝謝! – Asaf

+0

很高興幫助 – mKorbel

1

我只想create a custom event and fire itJInternalFrame得到focus (isActivated)。 菜單項將偵聽此事件,攔截它並將其狀態設置爲啓用或禁用。 這裏的優點是,您不必處理哪些菜單項應該可用於哪些類型的內部框架,只需觸發適當的事件即可。如果您將來添加更多內部框架,它會讓您的生活更輕鬆。

1

爲每個添加到桌面窗格的內部框架添加InternalFrameListener,並且每次觸發事件時,執行您在問題中顯示的代碼。

此代碼,可以更好地寫,但:

  • setEnabled是一個原始的布爾作爲參數,而不是一個java.lang.Boolean。使用truefalse而不是Boolean.TRUEBoolean.FALSE
  • 表達式(selectedFrame != null)評估爲布爾值。只要寫的

imageMenu.setEnabled(selectedFrame != null);

代替

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

這個答案是基於@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 
* 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"); 
          } 
         }); 
        } 
       } 
      } 
     } 
    } 
}