001package jmri.util; 002 003import java.awt.Frame; 004import java.awt.event.ActionEvent; 005import java.util.ArrayList; 006import java.util.List; 007import javax.swing.AbstractAction; 008import javax.swing.JCheckBoxMenuItem; 009import javax.swing.JMenu; 010import javax.swing.JMenuItem; 011import javax.swing.JSeparator; 012import javax.swing.event.MenuEvent; 013import jmri.util.swing.WindowInterface; 014 015/** 016 * Creates a menu showing all open windows and allows to bring one in front 017 * 018 * @author Giorgio Terdina Copyright 2008 019 */ 020public class WindowMenu extends JMenu implements javax.swing.event.MenuListener { 021 022 private Frame parentFrame; // Keep note of the window containing the menu 023 024 private List<JmriJFrame> framesList; // Keep the list of windows, in order to find out which window was selected 025 026 private static List<String> ignoredFrames = new ArrayList<String>(); // list of frames to not display 027 028 public WindowMenu(WindowInterface wi) { 029 super(Bundle.getMessage("MenuWindow")); 030 parentFrame = wi.getFrame(); 031 addMenuListener(this); 032 } 033 034 /** 035 * Provide a list of JmriJFrame titles that will -not- appear 036 * in the Windows menu. Those frames may or may not remain visible, 037 * but they won't be selectable from the menu. 038 */ 039 public static void setIgnoredFrames(List<String> frames) { 040 ignoredFrames = new ArrayList<>(frames); 041 } 042 043 public static List<String> getIgnoredFrames() { 044 return new ArrayList<>(ignoredFrames); 045 } 046 047 @Override 048 public void menuSelected(MenuEvent e) { 049 String windowName; 050 List<JmriJFrame> tempList = JmriJFrame.getFrameList(); 051 removeAll(); 052 053 add(new AbstractAction(Bundle.getMessage("ButtonClose")) { 054 @Override 055 public void actionPerformed(ActionEvent e) { 056 if (parentFrame != null) { 057 parentFrame.dispatchEvent( 058 new java.awt.event.WindowEvent(parentFrame, 059 java.awt.event.WindowEvent.WINDOW_CLOSING)); 060 } 061 } 062 }); 063 add(new AbstractAction(Bundle.getMessage("MenuItemMinimize")) { 064 @Override 065 public void actionPerformed(ActionEvent e) { 066 // the next line works on Java 2, but not 1.1.8 067 if (parentFrame != null) { 068 parentFrame.setState(Frame.ICONIFIED); 069 } 070 } 071 }); 072 add(new JSeparator()); 073 074 framesList = new ArrayList<>(); 075 076 int framesNumber = tempList.size(); 077 for (int i = 0; i < framesNumber; i++) { 078 JmriJFrame iFrame = tempList.get(i); 079 windowName = iFrame.getTitle(); 080 081 if (windowName.equals("")) { 082 windowName = "Untitled"; 083 } 084 085 if (ignoredFrames.contains(windowName)) { 086 continue; 087 } 088 089 framesList.add(iFrame); 090 091 JCheckBoxMenuItem newItem = new JCheckBoxMenuItem(new AbstractAction(windowName) { 092 @Override 093 public void actionPerformed(ActionEvent e) { 094 JMenuItem selectedItem = (JMenuItem) e.getSource(); 095 // Since different windows can have the same name, look for the position of the selected menu item 096 int itemCount = getItemCount(); 097 // Skip possible other items at the top of the menu (for example, "Minimize") 098 int firstItem = itemCount - framesList.size(); 099 for (int i = firstItem; i < itemCount; i++) { 100 if (selectedItem == getItem(i)) { 101 i -= firstItem; 102 // Retrieve the corresponding window 103 if (i < framesList.size()) { // "i" should always be < framesList.size(), but it's better to make sure 104 framesList.get(i).setVisible(true); 105 framesList.get(i).setExtendedState(Frame.NORMAL); 106 return; 107 } 108 } 109 } 110 } 111 }); 112 if (iFrame == parentFrame) { 113 newItem.setState(true); 114 } 115 add(newItem); 116 } 117 } 118 119 @Override 120 public void menuDeselected(MenuEvent e) { 121 } 122 123 @Override 124 public void menuCanceled(MenuEvent e) { 125 } 126 127}