001package horstmann.ch08_graphed;
002import java.awt.Color;
003import java.awt.Component;
004import java.awt.Graphics;
005import java.awt.Graphics2D;
006import java.awt.geom.AffineTransform;
007import java.util.ArrayList;
008
009import javax.swing.ButtonGroup;
010import javax.swing.Icon;
011import javax.swing.JPanel;
012import javax.swing.JToggleButton;
013
014/**
015   A tool bar that contains node and edge prototype icons.
016   Exactly one icon is selected at any time.
017 */
018@SuppressWarnings("serial")
019public class ToolBar extends JPanel
020{
021        /**
022      Constructs a tool bar with no icons.
023         */
024        public ToolBar(Graph graph)
025        {
026                group = new ButtonGroup();
027                tools = new ArrayList<Object>();
028
029                JToggleButton grabberButton = new JToggleButton(new
030                                Icon()
031                {
032                        public int getIconHeight() { return BUTTON_SIZE; }
033                        public int getIconWidth() { return BUTTON_SIZE; }
034                        public void paintIcon(Component c, Graphics g,
035                                        int x, int y)
036                        {
037                                Graphics2D g2 = (Graphics2D) g;
038                                GraphPanel.drawGrabber(g2, x + OFFSET, y + OFFSET);
039                                GraphPanel.drawGrabber(g2, x + OFFSET, y + BUTTON_SIZE - OFFSET);
040                                GraphPanel.drawGrabber(g2, x + BUTTON_SIZE - OFFSET, y + OFFSET);
041                                GraphPanel.drawGrabber(g2, x + BUTTON_SIZE - OFFSET, y + BUTTON_SIZE - OFFSET);
042                        }
043                });
044                group.add(grabberButton);
045                add(grabberButton);
046                grabberButton.setSelected(true);
047                tools.add(null);
048
049                Node[] nodeTypes = graph.getNodePrototypes();
050                for (Node n : nodeTypes)
051                        add(n);
052
053                Edge[] edgeTypes = graph.getEdgePrototypes();
054                for (Edge e : edgeTypes)
055                        add(e);
056        }
057
058        /**
059      Gets the node or edge prototype that is associated with
060      the currently selected button
061      @return a Node or Edge prototype
062         */
063        public Object getSelectedTool()
064        {
065                int i=0;
066                for (Object o : tools)
067                {
068                        JToggleButton button = (JToggleButton) getComponent(i++);
069                        if (button.isSelected()) return o;
070                }
071                return null;
072        }
073
074        /**
075      Adds a node to the tool bar.
076      @param n the node to add
077         */
078        public void add(final Node n)
079        {
080                JToggleButton button = new JToggleButton(new
081                                Icon()
082                {
083                        public int getIconHeight() { return BUTTON_SIZE; }
084                        public int getIconWidth() { return BUTTON_SIZE; }
085                        public void paintIcon(Component c, Graphics g,
086                                        int x, int y)
087                        {
088                                double width = n.getBounds().getWidth();
089                                double height = n.getBounds().getHeight();
090                                Graphics2D g2 = (Graphics2D) g;
091                                double scaleX = (BUTTON_SIZE - OFFSET)/ width;
092                                double scaleY = (BUTTON_SIZE - OFFSET)/ height;
093                                double scale = Math.min(scaleX, scaleY);
094
095                                AffineTransform oldTransform = g2.getTransform();
096                                g2.translate(x, y);
097                                g2.scale(scale, scale);
098                                g2.translate(Math.max((height - width) / 2, 0), Math.max((width - height) / 2, 0));
099                                g2.setColor(Color.black);
100                                n.draw(g2);
101                                g2.setTransform(oldTransform);
102                        }
103                });
104                group.add(button);
105                add(button);
106                tools.add(n);
107        }
108
109        /**
110      Adds an edge to the tool bar.
111      @param e the edge to add
112         */
113        public void add(final Edge e)
114        {
115                JToggleButton button = new JToggleButton(new
116                                Icon()
117                {
118                        public int getIconHeight() { return BUTTON_SIZE; }
119                        public int getIconWidth() { return BUTTON_SIZE; }
120                        public void paintIcon(Component c, Graphics g,
121                                        int x, int y)
122                        {
123                                Graphics2D g2 = (Graphics2D) g;
124                                PointNode p = new PointNode();
125                                p.translate(OFFSET, OFFSET);
126                                PointNode q = new PointNode();
127                                q.translate(BUTTON_SIZE - OFFSET, BUTTON_SIZE - OFFSET);
128                                e.connect(p, q);
129                                g2.translate(x, y);
130                                g2.setColor(Color.black);
131                                e.draw(g2);
132                                g2.translate(-x, -y);
133                        }
134                });
135                group.add(button);
136                add(button);
137                tools.add(e);
138        }
139
140        private ButtonGroup group;
141        private ArrayList<Object> tools;
142
143        private static final int BUTTON_SIZE = 25;
144        private static final int OFFSET = 4;
145}