/*
* Copyright (C) 2007, 2008 Clam <clamisgood@gmail.com>
* Copyright (C) 2007 Quadduc <quadduc@gmail.com>
*
* This file is part of LateralGM.
* LateralGM is free software and comes with ABSOLUTELY NO WARRANTY.
* See LICENSE for details.
*/
package org.lateralgm.components.mdi;
import java.awt.Component;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.event.ContainerEvent;
import java.awt.event.ContainerListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyVetoException;
import java.util.WeakHashMap;
import javax.swing.ButtonGroup;
import javax.swing.JInternalFrame;
import javax.swing.JMenuItem;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.event.InternalFrameAdapter;
import javax.swing.event.InternalFrameEvent;
import org.lateralgm.components.GmMenu;
import org.lateralgm.messages.Messages;
import org.lateralgm.subframes.InstantiableResourceFrame;
public class MDIMenu extends GmMenu implements ActionListener,ContainerListener
{
private static final long serialVersionUID = 1L;
private MDIPane pane;
private final ButtonGroup group = new ButtonGroup();
protected final WeakHashMap<MDIFrame,FrameButton> frameButtons;
protected JMenuItem cascade;
protected JMenuItem arrangeIcons;
protected JMenuItem closeAll;
protected JMenuItem minimizeAll;
protected JMenuItem close;
protected JMenuItem closeOthers;
public MDIMenu(MDIPane pane)
{
super(Messages.getString("MDIMenu.WINDOW"));
this.pane = pane;
frameButtons = new WeakHashMap<MDIFrame,FrameButton>();
pane.addContainerListener(this);
cascade = addItem("MDIMenu.CASCADE",this); //$NON-NLS-1$
arrangeIcons = addItem("MDIMenu.ARRANGE_ICONS",this); //$NON-NLS-1$
closeAll = addItem("MDIMenu.CLOSE_ALL",this); //$NON-NLS-1$
minimizeAll = addItem("MDIMenu.MINIMIZE_ALL",this); //$NON-NLS-1$
addSeparator();
close = addItem("MDIMenu.CLOSE",this); //$NON-NLS-1$
closeOthers = addItem("MDIMenu.CLOSE_OTHERS",this); //$NON-NLS-1$
addSeparator();
}
public void actionPerformed(ActionEvent e)
{
if (e.getActionCommand().endsWith("CASCADE"))
{
pane.cascadeFrames();
return;
}
if (e.getActionCommand().endsWith("ARRANGE_ICONS"))
{
pane.arrangeDesktopIcons();
return;
}
if (e.getActionCommand().endsWith("CLOSE_ALL"))
{
pane.closeAll();
return;
}
if (e.getActionCommand().endsWith("MINIMIZE_ALL"))
{
pane.iconizeAll();
return;
}
if (e.getActionCommand().endsWith("CLOSE") && pane.getSelectedFrame() != null)
{
if (pane.getSelectedFrame() instanceof InstantiableResourceFrame<?,?>)
try
{
pane.getSelectedFrame().setClosed(true);
}
catch (PropertyVetoException e1)
{
e1.printStackTrace();
}
else
pane.getSelectedFrame().setVisible(false);
return;
}
if (e.getActionCommand().endsWith("CLOSE_OTHERS"))
{
pane.closeOthers();
return;
}
}
protected void addRadio(FrameButton item)
{
group.add(item);
add(item);
}
protected void removeRadio(FrameButton item)
{
group.remove(item);
remove(item);
}
public void componentAdded(ContainerEvent e)
{
Component c = e.getChild();
if (c instanceof MDIFrame) new FrameButton((MDIFrame) c);
}
public void componentRemoved(ContainerEvent e)
{
Component c = e.getChild();
FrameButton b = frameButtons.get(c);
if (b != null) b.dispose();
}
protected void fireMenuSelected()
{
boolean hasFrames = false;
boolean hasIcons = false;
for (int i = 0; i < pane.getComponentCount(); i++)
{
Component comp = pane.getComponent(i);
if (comp instanceof JInternalFrame && ((JInternalFrame) comp).isVisible())
{
hasFrames = true;
if (hasIcons) break;
}
else if (comp instanceof JInternalFrame.JDesktopIcon)
{
hasIcons = true;
if (hasFrames) break;
}
}
cascade.setEnabled(hasFrames);
arrangeIcons.setEnabled(hasIcons);
closeAll.setEnabled(hasFrames);
minimizeAll.setEnabled(hasFrames);
boolean hasSelected = pane.getSelectedFrame() != null;
close.setEnabled(hasSelected);
closeOthers.setEnabled(hasSelected);
super.fireMenuSelected();
}
private class FrameButton extends JRadioButtonMenuItem implements PropertyChangeListener
{
private static final long serialVersionUID = 1L;
private IFListener ifl = new IFListener();
private CListener cl = new CListener();
protected MDIFrame mdif;
public FrameButton(MDIFrame f)
{
mdif = f;
frameButtons.put(f,this);
addRadio(this);
f.addInternalFrameListener(ifl);
f.addPropertyChangeListener(this);
f.addComponentListener(cl);
update();
setVisible(mdif.isVisible());
addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
mdif.toTop();
}
});
}
public void dispose()
{
frameButtons.remove(mdif);
removeRadio(this);
mdif.removeInternalFrameListener(ifl);
mdif.removePropertyChangeListener(this);
mdif.removeComponentListener(cl);
}
private void update()
{
setText(mdif.getTitle());
setIcon(mdif.getFrameIcon());
}
public void propertyChange(PropertyChangeEvent evt)
{
update();
}
private class IFListener extends InternalFrameAdapter
{
public IFListener()
{
super();
}
public void internalFrameActivated(InternalFrameEvent e)
{
setSelected(true);
}
}
private class CListener extends ComponentAdapter
{
public CListener()
{
super();
}
public void componentHidden(ComponentEvent e)
{
setVisible(false);
}
public void componentShown(ComponentEvent e)
{
setVisible(true);
}
}
}
}