package net.xoetrope.optional.laf.synth;
import java.awt.Graphics;
import java.awt.Insets;
import java.lang.reflect.Field;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import javax.swing.*;
import javax.swing.plaf.basic.BasicMenuUI;
import javax.swing.plaf.synth.SynthContext;
import javax.swing.plaf.synth.SynthPainter;
import net.xoetrope.xui.XProject;
import net.xoetrope.xui.XProjectManager;
/**
* Synth painter for Menus
* <p>Copyright: Copyright (c) Xoetrope Ltd., 2001-2005<br>
* License: see license.txt
* $Revision: 1.4 $
*/
public class MenuPainter extends SynthPainter
{
private static HashSet opaqued = new HashSet();
private static HashSet allMenus = new HashSet();
private XProject currentProject = XProjectManager.getCurrentProject();
private static HashMap painters = new HashMap();
/**
* Paints the menu separator.
*
* @param context SynthContext identifying the <code>JComponent</code> and
* <code>Region</code> to paint to
* @param g <code>Graphics</code> to paint to
* @param x X coordinate of the area to paint to
* @param y Y coordinate of the area to paint to
* @param w Width of the area to paint to
* @param h Height of the area to paint to
*/
public void paintSeparatorBorder( SynthContext context, Graphics g, int x, int y, int w, int h )
{
g.setColor( context.getComponent().getForeground());
g.drawLine( x, y, x + w, y );
}
/**
* Paints the popup menu background.
*
* @param context SynthContext identifying the <code>JComponent</code> and
* <code>Region</code> to paint to
* @param g <code>Graphics</code> to paint to
* @param x X coordinate of the area to paint to
* @param y Y coordinate of the area to paint to
* @param w Width of the area to paint to
* @param h Height of the area to paint to
*/
public void paintPopupMenuBackground( SynthContext context, Graphics g, int x, int y, int w, int h )
{
JPopupMenu popup = ( JPopupMenu ) context.getComponent();
JPanel panel = ( JPanel ) popup.getParent();
if ( !opaqued.contains( popup ) ) {
popup.setOpaque( false );
panel.setOpaque( false );
( ( JComponent ) popup.getParent() ).setOpaque( false );
panel.repaint();
opaqued.add( popup );
}
if ( popup.getName() != null && popup.getName().startsWith( "ComboPopup" ) )
return;
else {
String imagePath = ( String ) UIManager.get( "PopupMenu.background" );
Insets sourceInsets = new Insets( 7, 7, 7, 7 );
Insets destInsets = new Insets( 7, 7, 7, 7 );
popup.setOpaque( false );
( ( JComponent ) popup.getParent() ).setOpaque( false );
ImagePainter imagePainter = (ImagePainter)painters.get( imagePath );
if ( imagePainter == null ) {
imagePainter = new ImagePainter( context, g, x, y, w, h, imagePath, sourceInsets, destInsets, true, true );
painters.put( imagePath, imagePainter );
}
imagePainter.paint( g );
return;
}
}
/**
* Paints the menu background.
*
* @param context SynthContext identifying the <code>JComponent</code> and
* <code>Region</code> to paint to
* @param g <code>Graphics</code> to paint to
* @param x X coordinate of the area to paint to
* @param y Y coordinate of the area to paint to
* @param w Width of the area to paint to
* @param h Height of the area to paint to
*/
public void paintMenuBackground( SynthContext context, Graphics g, int x, int y, int w, int h )
{
URL url = null;
String imagePath = null;
ImagePainter imagePainter = null;
try {
if ( ( context.getComponentState() & 0x200 ) > 0 )
imagePath = ( String ) UIManager.get( "Menu.subMenuIcon.selected" );
else
imagePath = ( String ) UIManager.get( "Menu.subMenuIcon.default" );
url = currentProject.getUrl( imagePath );
imagePainter = (ImagePainter)painters.get( imagePath );
if ( imagePainter == null ) {
Insets sourceInsets = new Insets( 0, 0, 0, 0 );
Insets destInsets = new Insets( 0, 0, 0, 0 );
imagePainter = new ImagePainter( context, g, x, y, w, h, imagePath, sourceInsets, destInsets, true, true, true );
painters.put( imagePath, imagePainter );
}
Icon arrow = new ImageIcon( imagePainter.getImage( imagePath ));
BasicMenuUI ui = ( BasicMenuUI ) ( ( JMenu ) context.getComponent() ).getUI();
Class clazz = Class.forName( "javax.swing.plaf.basic.BasicMenuItemUI" );
Field field = clazz.getDeclaredField( "arrowIcon" );
field.setAccessible( true );
field.set( ui, arrow );
}
catch ( Exception e ) {
System.out.println( imagePath );
e.printStackTrace();
}
JMenu m = ( JMenu ) context.getComponent();
if ( m.isTopLevelMenu() ) {
imagePath = null;
if ( ( context.getComponentState() & 0x200 ) > 0 )
imagePath = ( String ) UIManager.get( "Menu.bar.background.selected" );
else
imagePath = ( String ) UIManager.get( "Menu.bar.background.default" );
Insets sourceInsets = new Insets( 0, 0, 0, 0 );
Insets destInsets = new Insets( 0, 0, 0, 0 );
imagePainter = (ImagePainter)painters.get( imagePath );
if ( imagePainter == null ) {
imagePainter = new ImagePainter( context, g, x, y, w, h, imagePath, sourceInsets, destInsets, true, true );
painters.put( imagePath, imagePainter );
}
imagePainter.paint( g );
}
if ( !allMenus.contains( m ) ) {
allMenus.add( m );
boolean menuHasIcons = false;
for ( int i = 0; i < m.getMenuComponentCount(); i++ ) {
java.awt.Component mc = m.getMenuComponent( i );
if ( ! ( mc instanceof JMenuItem ) ||
( ( JMenuItem ) mc ).getIcon() == null && ! ( mc instanceof JRadioButtonMenuItem ) && ! ( mc instanceof JCheckBoxMenuItem ) )
continue;
menuHasIcons = true;
break;
}
if ( menuHasIcons ) {
int iconGap = ( ( Integer ) UIManager.get( "Menu.iconGap" ) ).intValue();
for ( int i = 0; i < m.getMenuComponentCount(); i++ ) {
java.awt.Component mc = m.getMenuComponent( i );
if ( ! ( mc instanceof JRadioButtonMenuItem ) && ! ( mc instanceof JCheckBoxMenuItem ) && ( mc instanceof JMenuItem ) ) {
JMenuItem item = ( JMenuItem ) mc;
Insets insets = item.getInsets();
int iconTextGap = insets.left - item.getIconTextGap();
if ( item.getIcon() == null )
iconTextGap += iconGap;
item.setBorder( BorderFactory.createEmptyBorder( insets.top, iconTextGap, insets.bottom, insets.right ) );
}
}
}
}
}
/**
* Paints the popup menu background.
*
* @param context SynthContext identifying the <code>JComponent</code> and
* <code>Region</code> to paint to
* @param g <code>Graphics</code> to paint to
* @param x X coordinate of the area to paint to
* @param y Y coordinate of the area to paint to
* @param w Width of the area to paint to
* @param h Height of the area to paint to
*/
public void paintMenuBarBackground( SynthContext context, Graphics g, int x, int y, int w, int h )
{
String imagePath = ( String ) UIManager.get( "MenuBar.background" );
Insets sourceInsets = new Insets( 0, 0, 0, 0 );
Insets destInsets = new Insets( 0, 0, 0, 0 );
ImagePainter imagePainter = (ImagePainter)painters.get( imagePath );
if ( imagePainter == null ) {
imagePainter = new ImagePainter( context, g, x, y, w, h, imagePath, sourceInsets, destInsets, true, true );
painters.put( imagePath, imagePainter );
}
imagePainter.paint( g );
}
}