// **********************************************************************
//
// <copyright>
//
// BBN Technologies
// 10 Moulton Street
// Cambridge, MA 02138
// (617) 873-8000
//
// Copyright (C) BBNT Solutions LLC. All rights reserved.
//
// </copyright>
// **********************************************************************
//
// $Source: /cvs/distapps/openmap/src/openmap/com/bbn/openmap/omGraphics/BasicStrokeEditorMenu.java,v $
// $RCSfile: BasicStrokeEditorMenu.java,v $
// $Revision: 1.2.2.6 $
// $Date: 2007/10/02 12:56:50 $
// $Author: phelinek $
//
// **********************************************************************
package com.bbn.openmap.omGraphics;
/* Java Core */
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.beans.PropertyChangeSupport;
import java.util.Enumeration;
import java.util.Vector;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JMenu;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButtonMenuItem;
import com.bbn.openmap.Environment;
import com.bbn.openmap.I18n;
import com.bbn.openmap.util.PropUtils;
/**
*/
public class BasicStrokeEditorMenu extends JPopupMenu {
protected BasicStroke basicStroke = null;
protected PropertyChangeSupport pcs = new PropertyChangeSupport(this);
protected float width; // must be >= 0f
protected int endCaps; //CAP_ROUND, CAP_BUTT, CAP_SQUARE
protected int lineJoins; //JOIN_BEVEL, JOIN_MITER, JOIN_ROUND
protected float miterLimit; // 10f default, must be >= 1f
protected float[] dash;
protected float dashPhase;
private I18n i18n = Environment.getI18n();
protected JButton launchButton;
public BasicStrokeEditorMenu() {
this(new BasicStroke(1f));
}
public BasicStrokeEditorMenu(BasicStroke bs) {
if (bs != null) {
basicStroke = bs;
} else {
basicStroke = new BasicStroke(1f);
}
setBasicStroke(basicStroke);
}
public void setLaunchButton(JButton lb) {
launchButton = lb;
}
public JButton getLaunchButton() {
if (launchButton == null) {
float buttonHeight = 20;
ImageIcon icon = createIcon(getBasicStroke(),
50,
(int) buttonHeight,
true);
launchButton = new JButton(icon);
launchButton.setToolTipText(i18n.get(BasicStrokeEditorMenu.class, "Modify_Line_Parameters", "Modify Line Parameters"));
launchButton.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
JButton button = getLaunchButton();
JPopupMenu popup = new JPopupMenu();
setGUI(popup);
popup.show(button, button.getWidth(), 0);
}
});
}
return launchButton;
}
public void resetStroke() {
BasicStroke oldStroke = basicStroke;
setMiterLimit(miterLimit);
basicStroke = new BasicStroke(width, endCaps, lineJoins, miterLimit, dash, dashPhase);
if (launchButton != null) {
launchButton.setIcon(createIcon(basicStroke, 50, 20, true));
}
pcs.firePropertyChange("line", oldStroke, basicStroke);
}
public void show(java.awt.Component invoker, int x, int y) {
this.removeAll();
setGUI(this);
super.show(invoker, x, y);
}
public JPopupMenu setGUI(JPopupMenu popup) {
//////// Line Cap
JMenu capMenu = new JMenu(i18n.get(BasicStrokeEditorMenu.class, "Cap_Decoration", "Cap Decoration"));
ActionListener listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String command = ae.getActionCommand();
try {
setEndCaps(Integer.parseInt(command));
resetStroke();
} catch (NumberFormatException e) {
}
}
};
ButtonGroup group = new ButtonGroup();
JRadioButtonMenuItem button = new JRadioButtonMenuItem(i18n.get(BasicStrokeEditorMenu.class, "Butt", "Butt"), endCaps == BasicStroke.CAP_BUTT);
button.setActionCommand(String.valueOf(BasicStroke.CAP_BUTT));
group.add(button);
button.addActionListener(listener);
capMenu.add(button);
button = new JRadioButtonMenuItem(i18n.get(BasicStrokeEditorMenu.class, "Round", "Round"), endCaps == BasicStroke.CAP_ROUND);
button.setActionCommand(String.valueOf(BasicStroke.CAP_ROUND));
group.add(button);
button.addActionListener(listener);
capMenu.add(button);
button = new JRadioButtonMenuItem(i18n.get(BasicStrokeEditorMenu.class, "Square", "Square"), endCaps == BasicStroke.CAP_SQUARE);
button.setActionCommand(String.valueOf(BasicStroke.CAP_SQUARE));
group.add(button);
button.addActionListener(listener);
capMenu.add(button);
//////// Line Joins
JMenu joinMenu = new JMenu(i18n.get(BasicStrokeEditorMenu.class, "Joint_Decoration", "Joint Decoration"));
listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String command = ae.getActionCommand();
try {
setLineJoins(Integer.parseInt(command));
resetStroke();
} catch (NumberFormatException e) {
}
}
};
group = new ButtonGroup();
button = new JRadioButtonMenuItem(i18n.get(BasicStrokeEditorMenu.class, "Miter", "Miter"), lineJoins == BasicStroke.JOIN_MITER);
button.setActionCommand(String.valueOf(BasicStroke.JOIN_MITER));
group.add(button);
button.addActionListener(listener);
joinMenu.add(button);
button = new JRadioButtonMenuItem(i18n.get(BasicStrokeEditorMenu.class, "Round", "Round"), lineJoins == BasicStroke.JOIN_ROUND);
button.setActionCommand(String.valueOf(BasicStroke.JOIN_ROUND));
group.add(button);
button.addActionListener(listener);
joinMenu.add(button);
button = new JRadioButtonMenuItem(i18n.get(BasicStrokeEditorMenu.class, "Bevel", "Bevel"), lineJoins == BasicStroke.JOIN_BEVEL);
button.setActionCommand(String.valueOf(BasicStroke.JOIN_BEVEL));
group.add(button);
button.addActionListener(listener);
joinMenu.add(button);
//////// Line Width
JMenu widthMenu = new JMenu(i18n.get(BasicStrokeEditorMenu.class, "Line_Width", "Line_Width"));
listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String command = ae.getActionCommand();
try {
setStrokeWidth((float) Integer.parseInt(command));
resetStroke();
} catch (NumberFormatException e) {
}
}
};
group = new ButtonGroup();
ImageIcon ii;
int i;
for (i = 1; i < 13; i++) {
ii = createIcon(new BasicStroke(i), 50, 20, true);
button = new JRadioButtonMenuItem(" ", ii, (int) width == i);//without the space as a parameter these instances look strange with some Look&Feel
button.setActionCommand(String.valueOf(i));
group.add(button);
button.addActionListener(listener);
button.setMargin( new java.awt.Insets(0,10,0,10));
button.setPreferredSize(new java.awt.Dimension(70,20));
widthMenu.add(button);
}
//////// Dash Pattern
JMenu dashMenu = new JMenu(i18n.get(BasicStrokeEditorMenu.class, "Dash_Pattern", "Dash Pattern"));
listener = new ActionListener() {
public void actionPerformed(ActionEvent ae) {
String command = ae.getActionCommand();
try {
setDash(stringToDashArray(command));
resetStroke();
} catch (NumberFormatException e) {
}
}
};
group = new ButtonGroup();
String[] patterns = new String[] { NONE, "1.0 3.0", "3.0 3.0", "12.0 10.0",
"12.0 10.0 6.0 10.0", "20.0 10.0", "20.0 10.0 6.0 10.0", "20.0 10.0 6.0 10.0 6.0 10.0" };
String currentDash = dashArrayToString(getDash());
for (i = 0; i < patterns.length; i++) {
BasicStroke dashStroke = new BasicStroke(1.0f, BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER, 10.0f, stringToDashArray(patterns[i]), 0.0f);
ii = createIcon(dashStroke, 90, 10, true);
button = new JRadioButtonMenuItem(" ", ii, currentDash.equals(patterns[i]));
button.setActionCommand(patterns[i]);
group.add(button);
button.addActionListener(listener);
button.setMargin( new java.awt.Insets(0,10,0,10));
button.setPreferredSize(new java.awt.Dimension(110,20));
dashMenu.add(button);
}
popup.add(widthMenu);
popup.add(dashMenu);
popup.add(capMenu);
popup.add(joinMenu);
return popup;
}
public final static String NONE = "No Dash Pattern";
public static String dashArrayToString(float[] da) {
if (da == null) {
return NONE;
}
StringBuffer sb = new StringBuffer();
for (int i = 0; i < da.length; i++) {
sb.append(Float.toString(da[i]) + " ");
}
return sb.toString().trim();
}
public static float[] stringToDashArray(String das) {
if (das == null || das.equals(NONE) || das.equals("")) {
return null;
}
Vector floats = PropUtils.parseSpacedMarkers(das);
float[] ret = new float[floats.size()];
int index = 0;
Enumeration thing = floats.elements();
while (thing.hasMoreElements()) {
String f = (String) thing.nextElement();
try {
ret[index++] = (new Float(f)).floatValue();
} catch (NumberFormatException nfe) {
return null;
}
}
return ret;
}
public BasicStroke getBasicStroke() {
return basicStroke;
}
public void setBasicStroke(BasicStroke bs) {
basicStroke = bs;
setStrokeWidth(basicStroke.getLineWidth());
setMiterLimit(basicStroke.getMiterLimit());
setDash(basicStroke.getDashArray());
setDashPhase(basicStroke.getDashPhase());
setLineJoins(basicStroke.getLineJoin());
setEndCaps(basicStroke.getEndCap());
}
public void setPropertyChangeSupport(
PropertyChangeSupport propertyChangeSupport) {
pcs = propertyChangeSupport;
}
public PropertyChangeSupport getPropertyChangeSupport() {
return pcs;
}
/**
* Given a BasicStroke, create an ImageIcon that shows it.
*
* @param stroke the BasicStroke to draw on the Icon.
* @param width the width of the icon.
* @param height the height of the icon.
* @param horizontalOrientation if true, draw line on the icon
* horizontally, else draw it vertically.
*/
public static ImageIcon createIcon(BasicStroke stroke, int width,
int height, boolean horizontalOrientation) {
BufferedImage bigImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) bigImage.getGraphics();
g.setBackground(OMColor.clear);
g.setPaint(OMColor.clear);
g.fillRect(0, 0, width, height);
g.setPaint(Color.black);
g.setStroke(stroke);
if (horizontalOrientation) {
g.drawLine(0, height / 2, width, height / 2);
} else {
g.drawLine(width / 2, 0, width / 2, height);
}
return new ImageIcon(bigImage);
}
/**
* Given a BasicStroke, create an ImageIcon that shows it.
*
* @param stroke the BasicStroke to draw on the Icon.
* @param width the width of the icon.
* @param height the height of the icon.
* @param horizontalOrientation if true, draw line on the icon
* horizontally, else draw it vertically.
*/
public static ImageIcon createColorIcon(BasicStroke stroke, int width,
int height, boolean horizontalOrientation,
Color color, Color background, Color matting) {
BufferedImage bigImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = (Graphics2D) bigImage.getGraphics();
g.setBackground(OMColor.clear);
g.setPaint(OMColor.clear);
g.fillRect(0, 0, width, height);
g.setPaint(background);
g.fillRect(0, 0, width, height);
if (matting != null) {
BasicStroke mattedStroke=new BasicStroke(((BasicStroke) stroke).getLineWidth() + 2f);
g.setStroke(mattedStroke);
g.setPaint(matting);
g.drawLine(0,height/2,width,height/2);
}
g.setPaint(color);
g.setStroke(stroke);
if (horizontalOrientation) {
g.drawLine(0, height / 2, width, height / 2);
} else {
g.drawLine(width / 2, 0, width / 2, height);
}
return new ImageIcon(bigImage);
}
public void setStrokeWidth(float w) {
if (w < 1)
w = 1;
width = w;
}
public float getStrokeWidth() {
return width;
}
public void setMiterLimit(float ml) {
if (ml < 1f)
miterLimit = 10f;
else
miterLimit = ml;
}
public float getMiterLimit() {
return miterLimit;
}
public void setDash(float[] da) {
dash = da;
}
public float[] getDash() {
return dash;
}
public void setDashPhase(float dp) {
dashPhase = dp;
}
public float getDashPhase() {
return dashPhase;
}
public void setEndCaps(int ec) {
endCaps = ec;
}
public int getEndCaps() {
return endCaps;
}
public void setLineJoins(int lj) {
lineJoins = lj;
}
public int getLineJoins() {
return lineJoins;
}
}