/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, * software distributed under the License is distributed on an * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * KIND, either express or implied. See the License for the * specific language governing permissions and limitations * under the License. */ package org.apache.felix.example.extenderbased.host; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Cursor; import java.awt.Dimension; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.event.MouseMotionListener; import java.util.HashMap; import java.util.Map; import javax.swing.Icon; import javax.swing.JButton; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JToolBar; import org.apache.felix.example.extenderbased.host.extension.SimpleShape; /** * This class represents the main application class, which is a JFrame subclass * that manages a toolbar of shapes and a drawing canvas. This class does not * directly interact with the underlying OSGi framework; instead, it is injected * with the available <tt>SimpleShape</tt> instances to eliminate any * dependencies on the OSGi application programming interfaces. **/ public class DrawingFrame extends JFrame implements MouseListener, MouseMotionListener { private static final long serialVersionUID = 1L; private static final int BOX = 54; private final JToolBar m_toolbar; private String m_selected; private final JPanel m_panel; private ShapeComponent m_selectedComponent; private final Map<String, ShapeInfo> m_shapes = new HashMap<String, ShapeInfo>(); private final SimpleShape m_defaultShape = new DefaultShape(); private final ActionListener m_reusableActionListener = new ShapeActionListener(); /** * Default constructor that populates the main window. **/ public DrawingFrame() { super("Extender-Based Host"); m_toolbar = new JToolBar("Toolbar"); m_panel = new JPanel(); m_panel.setBackground(Color.WHITE); m_panel.setLayout(null); m_panel.setMinimumSize(new Dimension(400, 400)); m_panel.addMouseListener(this); getContentPane().setLayout(new BorderLayout()); getContentPane().add(m_toolbar, BorderLayout.NORTH); getContentPane().add(m_panel, BorderLayout.CENTER); setSize(400, 400); } /** * This method sets the currently selected shape to be used for drawing * on the canvas. * @param name The name of the shape to use for drawing on the canvas. **/ public void selectShape(String name) { m_selected = name; } /** * Retrieves the available <tt>SimpleShape</tt> associated with the given name. * @param name The name of the <tt>SimpleShape</tt> to retrieve. * @return The corresponding <tt>SimpleShape</tt> instance if available or * <tt>null</tt>. **/ public SimpleShape getShape(String name) { ShapeInfo info = m_shapes.get(name); if (info == null) { return m_defaultShape; } else { return info.m_shape; } } /** * Injects an available <tt>SimpleShape</tt> into the drawing frame. * @param name The name of the injected <tt>SimpleShape</tt>. * @param icon The icon associated with the injected <tt>SimpleShape</tt>. * @param shape The injected <tt>SimpleShape</tt> instance. **/ public void addShape(String name, Icon icon, SimpleShape shape) { m_shapes.put(name, new ShapeInfo(name, icon, shape)); JButton button = new JButton(icon); button.setActionCommand(name); button.addActionListener(m_reusableActionListener); if (m_selected == null) { button.doClick(); } m_toolbar.add(button); m_toolbar.validate(); repaint(); } /** * Removes a no longer available <tt>SimpleShape</tt> from the drawing frame. * @param name The name of the <tt>SimpleShape</tt> to remove. **/ public void removeShape(String name) { m_shapes.remove(name); if ((m_selected != null) && m_selected.equals(name)) { m_selected = null; } for (int i = 0; i < m_toolbar.getComponentCount(); i++) { JButton sb = (JButton) m_toolbar.getComponent(i); if (sb.getActionCommand().equals(name)) { m_toolbar.remove(i); m_toolbar.invalidate(); validate(); repaint(); break; } } if ((m_selected == null) && (m_toolbar.getComponentCount() > 0)) { ((JButton) m_toolbar.getComponent(0)).doClick(); } } /** * Implements method for the <tt>MouseListener</tt> interface to * draw the selected shape into the drawing canvas. * @param evt The associated mouse event. **/ public void mouseClicked(MouseEvent evt) { if (m_selected == null) { return; } if (m_panel.contains(evt.getX(), evt.getY())) { ShapeComponent sc = new ShapeComponent(this, m_selected); sc.setBounds(evt.getX() - BOX / 2, evt.getY() - BOX / 2, BOX, BOX); m_panel.add(sc, 0); m_panel.validate(); m_panel.repaint(sc.getBounds()); } } /** * Implements an empty method for the <tt>MouseListener</tt> interface. * @param evt The associated mouse event. **/ public void mouseEntered(MouseEvent evt) { } /** * Implements an empty method for the <tt>MouseListener</tt> interface. * @param evt The associated mouse event. **/ public void mouseExited(MouseEvent evt) { } /** * Implements method for the <tt>MouseListener</tt> interface to initiate * shape dragging. * @param evt The associated mouse event. **/ public void mousePressed(MouseEvent evt) { Component c = m_panel.getComponentAt(evt.getPoint()); if (c instanceof ShapeComponent) { m_selectedComponent = (ShapeComponent) c; m_panel.setCursor(Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR)); m_panel.addMouseMotionListener(this); m_selectedComponent.repaint(); } } /** * Implements method for the <tt>MouseListener</tt> interface to complete * shape dragging. * @param evt The associated mouse event. **/ public void mouseReleased(MouseEvent evt) { if (m_selectedComponent != null) { m_panel.removeMouseMotionListener(this); m_panel.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); m_selectedComponent.setBounds( evt.getX() - BOX / 2, evt.getY() - BOX / 2, BOX, BOX); m_selectedComponent.repaint(); m_selectedComponent = null; } } /** * Implements method for the <tt>MouseMotionListener</tt> interface to * move a dragged shape. * @param evt The associated mouse event. **/ public void mouseDragged(MouseEvent evt) { m_selectedComponent.setBounds( evt.getX() - BOX / 2, evt.getY() - BOX / 2, BOX, BOX); } /** * Implements an empty method for the <tt>MouseMotionListener</tt> * interface. * @param evt The associated mouse event. **/ public void mouseMoved(MouseEvent evt) { } /** * Simple action listener for shape tool bar buttons that sets * the drawing frame's currently selected shape when receiving * an action event. **/ private class ShapeActionListener implements ActionListener { public void actionPerformed(ActionEvent evt) { selectShape(evt.getActionCommand()); } } /** * This class is used to record the various information pertaining to * an available shape. **/ private static class ShapeInfo { public String m_name; public Icon m_icon; public SimpleShape m_shape; public ShapeInfo(String name, Icon icon, SimpleShape shape) { m_name = name; m_icon = icon; m_shape = shape; } } }