package renamed

This commit is contained in:
bancika
2011-01-04 18:44:00 +00:00
parent b38bb5526e
commit 4e935aecc9
163 changed files with 305 additions and 265 deletions
@@ -0,0 +1,108 @@
package org.diylc;
import java.io.IOException;
import java.net.URL;
import java.util.Properties;
import javax.swing.UIManager;
import org.apache.log4j.PropertyConfigurator;
import org.diylc.gui.MainFrame;
import com.diyfever.gui.miscutils.PropertyInjector;
/**
*
* @author Branislav Stojkovic
*/
public class DIYLCStarter {
/**
* @param args
*/
public static void main(String[] args) {
URL url = DIYLCStarter.class.getResource("log4j.properties");
Properties properties = new Properties();
try {
properties.load(url.openStream());
PropertyConfigurator.configure(properties);
} catch (IOException e) {
e.printStackTrace();
}
url = DIYLCStarter.class.getResource("config.properties");
properties = new Properties();
try {
properties.load(url.openStream());
PropertyInjector.injectProperties(properties);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
MainFrame mainFrame = new MainFrame();
// Presenter p = new Presenter(mainFrame);
//
// p.installPlugin(new ToolBox());
// p.installPlugin(new FileManager());
// p.installPlugin(new ClipboardManager());
// p.installPlugin(new StatusBar());
// p.installPlugin(new CanvasPlugin());
//
// Project project = new Project();
// project.getComponents().add(new MockComponentInstance());
// p.loadProject(project);
// panel.setPreferredSize(new Dimension(2000, 1500));
// RulerScrollPane scrollPane = new RulerScrollPane(panel);
// JFrame f = new JFrame("Test");
// f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
// f.add(scrollPane);
// f.setPreferredSize(new Dimension(800, 600));
// f.pack();
// f.setLocationRelativeTo(null);
mainFrame.setLocationRelativeTo(null);
mainFrame.setVisible(true);
// List<Property> properties = ClassProcessor
// .extractProperties(MockComponent.class);
// MockComponent component = new MockComponent();
// for (Property p : properties) {
// try {
// p.readFrom(component);
// } catch (IllegalArgumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// }
// PropertyEditorDialog.showFor(null, properties);
// for (Property p : properties) {
// try {
// p.writeTo(component);
// } catch (IllegalArgumentException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (IllegalAccessException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// } catch (InvocationTargetException e) {
// // TODO Auto-generated catch block
// e.printStackTrace();
// }
// System.out.println(p);
// }
// System.out.println(p.getComponentTypes());
}
}
@@ -0,0 +1,7 @@
package org.diylc.common;
public class BadPositionException extends Exception {
private static final long serialVersionUID = 1L;
}
@@ -0,0 +1,52 @@
package org.diylc.common;
import java.awt.datatransfer.DataFlavor;
import java.awt.datatransfer.Transferable;
import java.awt.datatransfer.UnsupportedFlavorException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.diylc.model.IComponentInstance;
/**
* Represents component selection as a {@link List} of
* {@link IComponentInstance} objects. Implements {@link Transferable}, so it is
* suitable for clipboard usage.
*
* @author Branislav Stojkovic
*/
public class ComponentSelection extends ArrayList<IComponentInstance> implements Transferable {
private static final long serialVersionUID = 1L;
public static final DataFlavor listFlavor = new DataFlavor(List.class, "Java List");
public ComponentSelection() {
super();
}
public ComponentSelection(Collection<IComponentInstance> selectedComponents) {
super(selectedComponents);
}
@Override
public Object getTransferData(DataFlavor flavor) throws UnsupportedFlavorException, IOException {
if (flavor.equals(listFlavor)) {
return this;
}
throw new UnsupportedFlavorException(flavor);
}
@Override
public DataFlavor[] getTransferDataFlavors() {
return new DataFlavor[] { listFlavor };
}
@Override
public boolean isDataFlavorSupported(DataFlavor flavor) {
return flavor.equals(listFlavor);
}
}
@@ -0,0 +1,120 @@
package org.diylc.common;
import java.awt.Point;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.diylc.model.IComponentInstance;
import org.diylc.model.VisibilityPolicy;
/**
* Entity bean that represents a control point. Has methods for reading/writing
* {@link Point} value from/to a component.
*
* @author Branislav Stojkovic
*/
public class ControlPointWrapper {
private String name;
private Point value;
private Method setter;
private Method getter;
private boolean editable;
private boolean sticky;
private VisibilityPolicy visibilityPolicy;
public ControlPointWrapper(String name, Method getter, Method setter, boolean editable,
boolean sticky, VisibilityPolicy visibilityPolicy) {
super();
this.name = name;
this.getter = getter;
this.setter = setter;
this.editable = editable;
this.sticky = sticky;
this.visibilityPolicy = visibilityPolicy;
}
/**
* Reads value from the specified component by invoking it's
* <code>getter</code> method.
*
* @param component
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public void readFrom(IComponentInstance component) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
value = (Point) getter.invoke(component);
}
/**
* Writes the value into the specified component by invoking it's
* <code>setter</code> method.
*
* @param component
* @throws IllegalArgumentException
* @throws IllegalAccessException
* @throws InvocationTargetException
*/
public void writeTo(IComponentInstance component) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
setter.invoke(component, value);
}
public String getName() {
return name;
}
public boolean isEditable() {
return editable;
}
public boolean isSticky() {
return sticky;
}
public Point getValue() {
return value;
}
public void setValue(Point value) {
this.value = value;
}
public VisibilityPolicy getVisibilityPolicy() {
return visibilityPolicy;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
ControlPointWrapper other = (ControlPointWrapper) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
}
@@ -0,0 +1,36 @@
package org.diylc.common;
import java.awt.Graphics;
/**
* Enumerates all options that can be used when drawing a project.
*
* @see IPlugInPort#draw(java.awt.Graphics2D, java.util.EnumSet)
*
* @author Branislav Stojkovic
*/
public enum DrawOption {
/**
* Selection rectangle will be drawn when needed and selected components may
* be rendered differently.
*/
SELECTION,
/**
* Selected zoom level will be applied to scale the {@link Graphics} before
* drawing.
*/
ZOOM,
/**
* Grid lines are drawn.
*/
GRID,
/**
* Control points are drawn.
*/
CONTROL_POINTS,
/**
* Anti-aliasing is used when drawing.
*/
ANTIALIASING;
}
@@ -0,0 +1,56 @@
package org.diylc.common;
import java.awt.Rectangle;
import org.diylc.model.IComponentType;
import org.diylc.model.Project;
/**
* Enumerates all possible events between {@link IPlugInPort} and
* {@link IPlugIn}. Some events overlap so be careful which ones you subscribe
* for and how you process them.
*
* @author Branislav Stojkovic
*/
public enum EventType {
/**
* Called when zoom level changes. Typically only one parameter of type
* {@link Double} is passed with new zoom level.
*/
ZOOM_CHANGED,
/**
* Called when a new project is loaded. New {@link Project} is the first
* parameter. Boolean flag is the second parameter and it's true when new
* project is loaded, false when the same project has been either reloaded
* or loaded with undo/redo operations.
*/
PROJECT_LOADED,
/**
* Called when selection rectangle is changed. Object of type
* {@link Rectangle} is the only parameter and it contains the new selection
* rectangle.
*/
SELECTION_RECT_CHANGED,
/**
* Called when component selection is changed. New
* {@link ComponentSelection} is attached as a parameter.
*/
SELECTION_CHANGED,
/**
* Called when display needs to be repainted. No parameters are passed.
*/
REPAINT,
/**
* Called when new component slot has been changed. The only parameter is
* {@link IComponentType} and may be null.
*/
SLOT_CHANGED,
/**
* Called when the current project has been modified. Two instances of
* {@link Project} are passed as parameters, one before and one after the
* change. The third parameter is a string containing change description.
*/
PROJECT_MODIFIED, AVAILABLE_CTRL_POINTS_CHANGED, SELECTED_CTRL_POINTS_CHANGED, ;
}
@@ -0,0 +1,19 @@
package org.diylc.common;
import com.diyfever.gui.simplemq.IMessageListener;
/**
* Interface for plug-ins.
*
* @author Branislav Stojkovic
*/
public interface IPlugIn extends IMessageListener<EventType> {
/**
* Method that connects the plug-in with {@link IPlugInPort}. Called by the
* application when plug-in is installed.
*
* @param plugInPort
*/
void connect(IPlugInPort plugInPort);
}
@@ -0,0 +1,292 @@
package org.diylc.common;
import java.awt.Cursor;
import java.awt.Dimension;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.geom.Area;
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.swing.Action;
import javax.swing.JComponent;
import javax.swing.SwingConstants;
import javax.swing.JPopupMenu.Separator;
import org.diylc.model.ComponentLayer;
import org.diylc.model.IComponentInstance;
import org.diylc.model.IComponentType;
import org.diylc.model.Project;
import com.diyfever.gui.simplemq.IMessageListener;
import com.diyfever.gui.simplemq.MessageDispatcher;
import com.diyfever.gui.update.VersionNumber;
/**
* Interface for communication between plug-ins and the application. Plug-ins
* may acquire information or make changes through this interface. Application
* events are dispatched to plug-ins through {@link MessageDispatcher}
*
* @author Branislav Stojkovic
*
* @see IPlugIn
* @see MessageDispatcher
* @see IMessageListener
* @see EventType
*/
public interface IPlugInPort {
/**
* Returns size of the canvas that takes project dimensions into account as
* well as zoom level. Each dimension is calculated as the product of the
* actual size and the number of pixels per unit. If <code>useZoom</code> is
* set to true, the result is scaled by zoom factor.
*
* @param useZoom
*
* @return canvas dimensions
*/
Dimension getCanvasDimensions(boolean useZoom);
/**
* Returns an instance of {@link Cursor} that should be used at the
* specified location.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @return cursor
*/
Cursor getCursorAt(Point point);
/**
* Returns an instance of currently loaded project.
*
* @return
*/
Project getCurrentProject();
/**
* Loads specified {@link Project}.
*
* @param project
* @param freshStart
*/
void loadProject(Project project, boolean freshStart);
/**
* Returns all available {@link IComponentType}s classified by category.
* Result is a {@link Map} between category name to a {@link List} of all
* {@link IComponentType}s that share that category name.
*
* @return
*/
Map<String, List<IComponentType>> getComponentTypes();
/**
* Draws project on the provided {@link Graphics2D}.
*
* @param g2d
*/
void draw(Graphics2D g2d, Set<DrawOption> drawProperties);
/**
* Injects a custom GUI panels provided by the plug-in and desired position
* in the window. Application will layout plug-in panels accordingly. <br>
* Valid positions are:
* <ul>
* <li> {@link SwingConstants#TOP}</li>
* <li> {@link SwingConstants#BOTTOM}</li>
* <li> {@link SwingConstants#LEFT}</li>
* <li> {@link SwingConstants#RIGHT}</li>
* </ul>
*
* Center position is reserved for the main canvas panel and cannot be used.
*
* @param component
* @param position
* @throws BadPositionException
* in case invalid position is specified
*/
void injectGUIComponent(JComponent component, int position) throws BadPositionException;
/**
* Injects a custom menu action into application's main menu. If
* <code>action</code> is set to null {@link Separator} will be added. If
* the specified menu does not exist it will be automatically created.
*
* @param action
* {@link Action} to inser
* @param menuName
* name of the menu to insert into
*/
public void injectMenuAction(Action action, String menuName);
/**
* Returns current zoom level where <code>zoomLevel = 1.0d</code> means
* 100%.
*
* @return current zoom level
*/
double getZoomLevel();
/**
* Changes current zoom level where <code>zoomLevel = 1.0d</code> means 100%
*
* @param zoomLevel
* new zoom leve
*/
void setZoomLevel(double zoomLevel);
/**
* Notifies the presenter that mouse is clicked.
*
* Note: point coordinates are display based, i.e. scaled for zoom factor.
*
* @param point
* @param ctrlDown
* @param shiftDown
* @param altDown
*/
void mouseClicked(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
/**
* Notifies the presenter that mouse is moved.
*
* Note: point coordinates are display based, i.e. scaled for zoom factor.
*
* @param point
* @param ctrlDown
* @param shiftDown
* @param altDown
*/
void mouseMoved(Point point, boolean ctrlDown, boolean shiftDown, boolean altDown);
/**
* Returns the current {@link ComponentSelection}.
*
* @return
*/
ComponentSelection getSelectedComponents();
/**
* Returns the {@link Area} occupied by the component.
*
* @return
*/
Area getComponentArea(IComponentInstance component);
/**
* Notification that drag has been started from the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
*/
void dragStarted(Point point);
/**
* Checks if it's possible to drop over the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
* @return
*/
boolean dragOver(Point point);
/**
* Notification that drag has been ended in the specified point.
*
* Note: point coordinates are scaled for zoom factor.
*
* @param point
*/
void dragEnded(Point point);
/**
* Returns current version number.
*
* @return
*/
VersionNumber getCurrentVersionNumber();
/**
* Adds a list of components to the project.
*
* @param components
* @param preferredPoint
*/
void addComponents(List<IComponentInstance> components, Point preferredPoint);
/**
* Checks if a certain layer is locked for editing.
*
* @param layer
* @return
*/
boolean isLayerLocked(ComponentLayer layer);
/**
* Changes layer's locked state.
*
* @param layer
* @param locked
*/
void setLayerLocked(ComponentLayer layer, boolean locked);
/**
* Checks if a certain layer is visible.
*
* @param layer
* @return
*/
boolean isLayerVisible(ComponentLayer layer);
/**
* Changes layer visibility.
*
* @param layer
* @param visible
*/
void setLayerVisible(ComponentLayer layer, boolean visible);
/**
* Sets default value for the specified property name for currently selected
* component types.
*
* @param propertyName
* display name for property
* @param value
* new default value, must not be null
*/
void setDefaultPropertyValue(String propertyName, Object value);
/**
* Returns a list of properties that are mutual for all the selected
* components. Resulting list may be empty if selected components do not
* have mutual properties or can be null if the selection is empty.
*
* @return
*/
List<PropertyWrapper> getMutualSelectionProperties();
/**
* Applies specified properties to all the selected components. If some of
* the properties are not applicable to some of the selected components an
* exception will be thrown.
*
* @param properties
* @throws Exception
*/
void applyPropertiesToSelection(List<PropertyWrapper> properties) throws Exception;
// void setCursorIcon(Icon icon);
/**
* Sets the new component slot. Specified component type will be used to
* instantiate new component.
*/
void setNewComponentSlot(IComponentType componentType);
}
@@ -0,0 +1,144 @@
package org.diylc.common;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import org.diylc.model.IComponentInstance;
/**
* Entity class for editable properties extracted from component objects.
* Represents a single editable property together with it's current value.
*
* @author Branislav Stojkovic
*/
public class PropertyWrapper implements Cloneable {
private String name;
private Class<?> type;
private Object value;
private Method setter;
private Method getter;
private boolean defaultable;
public PropertyWrapper(String name, Class<?> type, Method getter, Method setter,
boolean defaultable) {
super();
this.name = name;
this.type = type;
this.getter = getter;
this.setter = setter;
this.defaultable = defaultable;
}
public void readFrom(IComponentInstance component) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
this.value = getter.invoke(component);
}
// public void readUniqueFrom(IComponentInstance component)
// throws IllegalArgumentException, IllegalAccessException,
// InvocationTargetException {
// Object newValue = getter.invoke(component);
// if (!newValue.equals(value)) {
// this.value = null;
// }
// }
public void writeTo(IComponentInstance component) throws IllegalArgumentException,
IllegalAccessException, InvocationTargetException {
setter.invoke(component, value);
}
public String getName() {
return name;
}
public Class<?> getType() {
return type;
}
public Object getValue() {
return value;
}
public void setValue(Object value) {
this.value = value;
}
public boolean isDefaultable() {
return defaultable;
}
public void setDefaultable(boolean defaultable) {
this.defaultable = defaultable;
}
// @Override
// public Object clone() throws CloneNotSupportedException {
// // Try to invoke clone method on value if possible.
// try {
// Method cloneMethod = value.getClass().getMethod("clone");
// return new Property(name, type, cloneMethod.invoke(value));
// } catch (Exception e) {
// }
// return new Property(name, type, value);
// }
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + (defaultable ? 1231 : 1237);
result = prime * result + ((getter == null) ? 0 : getter.hashCode());
result = prime * result + ((name == null) ? 0 : name.hashCode());
result = prime * result + ((setter == null) ? 0 : setter.hashCode());
result = prime * result + ((type == null) ? 0 : type.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
PropertyWrapper other = (PropertyWrapper) obj;
if (defaultable != other.defaultable)
return false;
if (getter == null) {
if (other.getter != null)
return false;
} else if (!getter.equals(other.getter))
return false;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (setter == null) {
if (other.setter != null)
return false;
} else if (!setter.equals(other.setter))
return false;
if (type == null) {
if (other.type != null)
return false;
} else if (!type.equals(other.type))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
@Override
public String toString() {
return name + " = " + value;
}
}
@@ -0,0 +1,42 @@
package org.diylc.gui;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.Icon;
import javax.swing.JComponent;
public class CustomGlassPane extends JComponent {
private static final long serialVersionUID = 1L;
private Icon icon;
public CustomGlassPane() {
super();
addMouseMotionListener(new MouseMotionAdapter() {
@Override
public void mouseMoved(MouseEvent e) {
if (icon != null) {
repaint();
}
}
});
}
public void setCursorIcon(Icon icon) {
this.icon = icon;
}
@Override
public void paint(Graphics g) {
Point cursor = getMousePosition();
if ((icon != null) && (cursor != null)) {
Graphics2D g2d = (Graphics2D) g;
icon.paintIcon(this, g2d, cursor.x + 10, cursor.y + 10);
}
}
}
@@ -0,0 +1,154 @@
package org.diylc.gui;
import java.io.File;
import java.util.List;
import javax.swing.Icon;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.filechooser.FileFilter;
import org.diylc.common.PropertyWrapper;
import org.diylc.gui.components.OverwritePromptFileChooser;
import org.diylc.gui.editor.PropertyEditorDialog;
import org.diylc.plugins.file.BomDialog;
import org.diylc.plugins.file.BomEntry;
import org.diylc.plugins.online.view.LoginDialog;
import org.diylc.plugins.online.view.NewUserDialog;
import org.diylc.plugins.online.view.UploadDialog;
import com.diyfever.gui.AboutDialog;
import com.diyfever.gui.IFileChooserAccessory;
import com.diyfever.gui.ProgressDialog;
import com.diyfever.gui.miscutils.ConfigurationManager;
public class DialogFactory {
private static DialogFactory instance;
private static final String PATH_KEY = "lastPath";
public static DialogFactory getInstance() {
if (instance == null) {
instance = new DialogFactory();
}
return instance;
}
private JFrame mainFrame;
private File lastDirectory;
private DialogFactory() {
}
/**
* Sets the frame to be used as dialog parent. This should be called prior
* to any other methods in this class.
*
* @param mainFrame
*/
public void initialize(JFrame mainFrame) {
this.mainFrame = mainFrame;
String lastDirectoryPath = (String) ConfigurationManager.getInstance()
.getConfigurationItem(PATH_KEY);
if (lastDirectoryPath != null) {
lastDirectory = new File(lastDirectoryPath);
}
}
public PropertyEditorDialog createPropertyEditorDialog(List<PropertyWrapper> properties) {
PropertyEditorDialog editor = new PropertyEditorDialog(mainFrame, properties);
return editor;
}
public BomDialog createBomDialog(List<BomEntry> bom) {
BomDialog dialog = new BomDialog(mainFrame, bom);
return dialog;
}
public File showOpenDialog(FileFilter fileFilter, File initialFile, String defaultExtension,
IFileChooserAccessory accessory) {
JFileChooser openFileChooser = new JFileChooser();
initializeFileChooser(openFileChooser, fileFilter, initialFile, defaultExtension, accessory);
int result = openFileChooser.showOpenDialog(mainFrame);
return processFileChooserResult(result, openFileChooser, defaultExtension);
}
public File showSaveDialog(FileFilter fileFilter, File initialFile, String defaultExtension,
IFileChooserAccessory accessory) {
JFileChooser saveFileChooser = new OverwritePromptFileChooser();
initializeFileChooser(saveFileChooser, fileFilter, initialFile, defaultExtension, accessory);
int result = saveFileChooser.showSaveDialog(mainFrame);
return processFileChooserResult(result, saveFileChooser, defaultExtension);
}
private void initializeFileChooser(JFileChooser fileChooser, FileFilter fileFilter,
File initialFile, String defaultExtension, IFileChooserAccessory accessory) {
if (accessory != null) {
accessory.install(fileChooser);
}
for (FileFilter filter : fileChooser.getChoosableFileFilters()) {
fileChooser.removeChoosableFileFilter(filter);
}
if (fileChooser instanceof OverwritePromptFileChooser) {
((OverwritePromptFileChooser) fileChooser).setFileFilter(fileFilter, defaultExtension);
} else {
fileChooser.setFileFilter(fileFilter);
}
if (lastDirectory != null) {
fileChooser.setCurrentDirectory(lastDirectory);
}
fileChooser.setSelectedFile(initialFile);
}
private File processFileChooserResult(int result, JFileChooser fileChooser,
String defaultExtension) {
fileChooser.setAccessory(null);
if (result == JFileChooser.APPROVE_OPTION) {
lastDirectory = fileChooser.getCurrentDirectory();
ConfigurationManager.getInstance().setConfigurationItem(PATH_KEY,
lastDirectory.getAbsolutePath());
if (fileChooser.getSelectedFile().getAbsolutePath().contains(".")) {
return fileChooser.getSelectedFile();
} else {
return new File(fileChooser.getSelectedFile().getAbsoluteFile() + "."
+ defaultExtension);
}
} else {
return null;
}
}
public AboutDialog createAboutDialog(String appName, Icon icon, String version, String author,
String url, String mail, String htmlContent) {
AboutDialog dialog = new AboutDialog(mainFrame, appName, icon, version, author, url, mail,
htmlContent);
return dialog;
}
public NewUserDialog createNewUserDialog() {
NewUserDialog dialog = new NewUserDialog(mainFrame);
return dialog;
}
public LoginDialog createLoginDialog() {
LoginDialog dialog = new LoginDialog(mainFrame);
return dialog;
}
public UploadDialog createUploadDialog() {
UploadDialog dialog = new UploadDialog(mainFrame);
return dialog;
}
public ProgressDialog createProgressDialog(String title, String[] buttonCaptions,
String description, boolean useProgress) {
ProgressDialog dialog = new ProgressDialog(mainFrame, title, buttonCaptions, description,
useProgress);
return dialog;
}
}
@@ -0,0 +1,44 @@
package org.diylc.gui;
import javax.swing.Action;
import javax.swing.Icon;
import javax.swing.JComponent;
import org.diylc.common.BadPositionException;
import org.diylc.common.IPlugInPort;
/**
* Base interface for the main GUI component.
*
* @author Branislav Stojkovic
*/
public interface IView {
/**
* Adds a component to the view.
*
* @param component
* component to insert
* @param position
* target position
* @throws BadPositionException
*
* @see IPlugInPort#injectGUIComponent
*/
void addComponent(JComponent component, int position) throws BadPositionException;
/**
* Adds a menu action.
*
* @param action
* action to insert
* @param menuName
* target menu name
*
* @see IPlugInPort#injectMenuAction
*/
void addMenuAction(Action action, String menuName);
void setCursorIcon(Icon icon);
}
@@ -0,0 +1,203 @@
package org.diylc.gui;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.HashMap;
import java.util.Map;
import javax.swing.Action;
import javax.swing.BoxLayout;
import javax.swing.Icon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.SwingConstants;
import javax.swing.Timer;
import org.diylc.common.BadPositionException;
import org.diylc.model.Project;
import org.diylc.plugins.canvas.CanvasPlugin;
import org.diylc.plugins.clipboard.ClipboardManager;
import org.diylc.plugins.file.FileManager;
import org.diylc.plugins.help.HelpManager;
import org.diylc.plugins.online.OnlineManager;
import org.diylc.plugins.statusbar.StatusBar;
import org.diylc.plugins.toolbox.ToolBox;
import org.diylc.presenter.Presenter;
public class MainFrame extends JFrame implements IView {
private static final long serialVersionUID = 1L;
private JPanel centerPanel;
private JPanel leftPanel;
private JPanel rightPanel;
private JPanel topPanel;
private JPanel bottomPanel;
private Presenter presenter;
private JMenuBar mainMenuBar;
private Map<String, JMenu> menuMap;
private CanvasPlugin canvasPlugin;
public MainFrame() {
super("DIYLC4");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(800, 600));
createBasePanels();
menuMap = new HashMap<String, JMenu>();
DialogFactory.getInstance().initialize(this);
this.presenter = new Presenter(this);
setTitle(getTitle() + " " + presenter.getCurrentVersionNumber());
presenter.installPlugin(new ToolBox());
presenter.installPlugin(new FileManager());
presenter.installPlugin(new ClipboardManager());
presenter.installPlugin(new OnlineManager());
presenter.installPlugin(new HelpManager());
presenter.installPlugin(new StatusBar());
canvasPlugin = new CanvasPlugin();
presenter.installPlugin(canvasPlugin);
Project project = new Project();
// project.getComponents().add(new MockComponentInstance());
presenter.loadProject(project, true);
addWindowListener(new WindowAdapter() {
@Override
public void windowClosed(WindowEvent e) {
presenter.dispose();
}
@Override
public void windowClosing(WindowEvent e) {
presenter.dispose();
}
});
// setGlassPane(new CustomGlassPane());
// getGlassPane().setVisible(true);
}
@Override
public void setVisible(boolean b) {
super.setVisible(b);
// TODO: hack to prevent painting issues in the scroll bar rulers. Find
// a better fix if possible.
Timer timer = new Timer(50, new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
canvasPlugin.refresh();
}
});
timer.setRepeats(false);
timer.start();
// if (b) {
// SwingUtilities.invokeLater(new Runnable() {
// @Override
// public void run() {
//
// }
// });
// }
}
private void createBasePanels() {
Container c = new Container();
c.setLayout(new BorderLayout());
centerPanel = new JPanel(new BorderLayout());
c.add(centerPanel, BorderLayout.CENTER);
topPanel = new JPanel();
topPanel.setLayout(new BoxLayout(topPanel, BoxLayout.Y_AXIS));
c.add(topPanel, BorderLayout.NORTH);
leftPanel = new JPanel();
leftPanel.setLayout(new BoxLayout(leftPanel, BoxLayout.X_AXIS));
c.add(leftPanel, BorderLayout.WEST);
bottomPanel = new JPanel();
bottomPanel.setLayout(new BoxLayout(bottomPanel, BoxLayout.Y_AXIS));
c.add(bottomPanel, BorderLayout.SOUTH);
rightPanel = new JPanel();
rightPanel.setLayout(new BoxLayout(rightPanel, BoxLayout.X_AXIS));
c.add(rightPanel, BorderLayout.EAST);
setContentPane(c);
}
private JMenuBar getMainMenuBar() {
if (mainMenuBar == null) {
mainMenuBar = new JMenuBar();
setJMenuBar(mainMenuBar);
}
return mainMenuBar;
}
// IView
@Override
public void addComponent(JComponent component, int position) throws BadPositionException {
switch (position) {
case SwingConstants.TOP:
topPanel.add(component);
break;
case SwingConstants.LEFT:
leftPanel.add(component);
break;
case SwingConstants.BOTTOM:
bottomPanel.add(component);
break;
case SwingConstants.RIGHT:
rightPanel.add(component);
break;
case SwingConstants.CENTER:
centerPanel.add(component, BorderLayout.CENTER);
break;
default:
throw new BadPositionException();
}
pack();
}
@Override
public void addMenuAction(Action action, String menuName) {
JMenu menu;
if (menuMap.containsKey(menuName)) {
menu = menuMap.get(menuName);
} else {
menu = new JMenu(menuName);
menuMap.put(menuName, menu);
getMainMenuBar().add(menu);
}
if (action == null) {
menu.addSeparator();
} else {
menu.add(action);
}
}
@Override
public void setCursorIcon(Icon icon) {
// TODO Auto-generated method stub
}
}
@@ -0,0 +1,38 @@
package org.diylc.gui.components;
import java.io.File;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;
public class OverwritePromptFileChooser extends JFileChooser {
private static final long serialVersionUID = 1L;
private String defaultExtension;
public void approveSelection() {
File lSelectedFile;
if (getSelectedFile().getAbsolutePath().contains(".")) {
lSelectedFile = getSelectedFile();
} else {
lSelectedFile = new File(getSelectedFile().getAbsoluteFile() + "." + defaultExtension);
}
if (lSelectedFile != null && lSelectedFile.exists()) {
int lResponse = JOptionPane.showConfirmDialog(this, lSelectedFile.getAbsolutePath()
+ " already exists.\nDo you " + "want to replace it?", "Warning",
JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE);
if (lResponse != JOptionPane.YES_OPTION) {
return;
}
}
super.approveSelection();
}
public void setFileFilter(FileFilter filter, String defaultExtension) {
this.defaultExtension = defaultExtension;
super.setFileFilter(filter);
}
}
@@ -0,0 +1,40 @@
package org.diylc.gui.editor;
import java.awt.Color;
import java.awt.Cursor;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.BorderFactory;
import javax.swing.JColorChooser;
import javax.swing.JLabel;
import javax.swing.SwingConstants;
import org.diylc.common.PropertyWrapper;
public class ColorEditor extends JLabel {
private static final long serialVersionUID = 1L;
public ColorEditor(final PropertyWrapper property) {
super("Click to edit");
setOpaque(true);
setHorizontalAlignment(SwingConstants.CENTER);
setBorder(BorderFactory.createEtchedBorder());
setBackground((Color) property.getValue());
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
Color newColor = JColorChooser.showDialog(ColorEditor.this, "Choose Color",
getBackground());
if (newColor != null) {
property.setValue(newColor);
setBackground(newColor);
}
}
});
}
}
@@ -0,0 +1,27 @@
package org.diylc.gui.editor;
import java.awt.Color;
import java.awt.Component;
import org.diylc.common.PropertyWrapper;
import org.diylc.model.measures.AbstractMeasure;
public class FieldEditorFactory {
public static Component createFieldEditor(PropertyWrapper property) {
if (property.getType().equals(String.class)) {
StringEditor editor = new StringEditor(property);
return editor;
}
if (property.getType().equals(Color.class)) {
ColorEditor editor = new ColorEditor(property);
return editor;
}
if (AbstractMeasure.class.isAssignableFrom(property.getType())) {
MeasureEditor editor = new MeasureEditor(property);
return editor;
}
return null;
}
}
@@ -0,0 +1,66 @@
package org.diylc.gui.editor;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import javax.swing.JComboBox;
import org.diylc.common.PropertyWrapper;
import org.diylc.model.measures.AbstractMeasure;
import com.diyfever.gui.DoubleTextField;
public class MeasureEditor extends Container {
private static final long serialVersionUID = 1L;
@SuppressWarnings("unchecked")
public MeasureEditor(final PropertyWrapper property) {
setLayout(new BorderLayout());
final AbstractMeasure measure = ((AbstractMeasure) property.getValue());
DoubleTextField valueField = new DoubleTextField(measure.getValue());
valueField.addPropertyChangeListener(DoubleTextField.VALUE_PROPERTY,
new PropertyChangeListener() {
@Override
public void propertyChange(PropertyChangeEvent evt) {
measure.setValue((Double) evt.getNewValue());
}
});
add(valueField, BorderLayout.CENTER);
try {
Method method = measure.getUnit().getClass().getMethod("values");
final JComboBox unitBox = new JComboBox((Object[]) method.invoke(measure.getUnit()));
unitBox.setSelectedItem(measure.getUnit());
unitBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
measure.setUnit((Enum) unitBox.getSelectedItem());
}
});
add(unitBox, BorderLayout.EAST);
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
@@ -0,0 +1,136 @@
package org.diylc.gui.editor;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.swing.BorderFactory;
import javax.swing.JCheckBox;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import org.apache.log4j.Logger;
import org.diylc.common.PropertyWrapper;
import com.diyfever.gui.ButtonDialog;
public class PropertyEditorDialog extends ButtonDialog {
private static final Logger LOG = Logger.getLogger(PropertyEditorDialog.class);
private static final long serialVersionUID = 1L;
private static final String DEFAULT_BOX_TOOLTIP = "<html>If this box is checked application will use the current value as a<br>default when creating new components of the same type</html>";
private List<PropertyWrapper> properties;
private Set<PropertyWrapper> defaultedProperties;
public PropertyEditorDialog(JFrame owner, List<PropertyWrapper> properties) {
super(owner, "Editor", new String[] { ButtonDialog.OK, ButtonDialog.CANCEL });
LOG.debug("Creating property editor for: " + properties);
this.properties = properties;
this.defaultedProperties = new HashSet<PropertyWrapper>();
setMinimumSize(new Dimension(240, 40));
layoutGui();
setLocationRelativeTo(owner);
//
// setModal(true);
//
// JPanel holderPanel = new JPanel();
// holderPanel.setLayout(new BorderLayout());
// holderPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
//
// holderPanel.add(createEditorFields(), BorderLayout.CENTER);
// holderPanel.add(createButtonPanel(), BorderLayout.SOUTH);
//
// setContentPane(holderPanel);
//
//
// pack();
// setLocationRelativeTo(owner);
}
private JPanel createEditorFields() {
JPanel editorPanel = new JPanel(new GridBagLayout());
editorPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridy = 0;
gbc.insets = new Insets(2, 2, 2, 2);
gbc.anchor = GridBagConstraints.LINE_START;
for (PropertyWrapper property : properties) {
gbc.gridx = 0;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
editorPanel.add(new JLabel(property.getName() + ": "), gbc);
gbc.gridx = 1;
gbc.fill = GridBagConstraints.HORIZONTAL;
gbc.weightx = 1;
editorPanel.add(FieldEditorFactory.createFieldEditor(property), gbc);
if (property.isDefaultable()) {
gbc.gridx = 2;
gbc.fill = GridBagConstraints.NONE;
gbc.weightx = 0;
editorPanel.add(createDefaultCheckBox(property), gbc);
}
gbc.gridy++;
}
return editorPanel;
}
private JCheckBox createDefaultCheckBox(final PropertyWrapper property) {
final JCheckBox checkBox = new JCheckBox();
checkBox.setToolTipText(DEFAULT_BOX_TOOLTIP);
checkBox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
if (checkBox.isSelected()) {
defaultedProperties.add(property);
} else {
defaultedProperties.remove(property);
}
}
});
return checkBox;
}
public Set<PropertyWrapper> getDefaultedProperties() {
return defaultedProperties;
}
public static boolean showFor(JFrame owner, List<PropertyWrapper> properties) {
PropertyEditorDialog editor = new PropertyEditorDialog(owner, properties);
editor.setVisible(true);
if (OK.equals(editor.getSelectedButtonCaption())) {
return true;
}
return false;
}
@Override
protected JComponent getMainComponent() {
return createEditorFields();
}
}
@@ -0,0 +1,41 @@
package org.diylc.gui.editor;
import javax.swing.JTextField;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import org.diylc.common.PropertyWrapper;
public class StringEditor extends JTextField {
private static final long serialVersionUID = 1L;
private final PropertyWrapper property;
public StringEditor(PropertyWrapper property) {
super(property.getValue() == null ? "" : (String) property.getValue());
this.property = property;
getDocument().addDocumentListener(new DocumentListener() {
@Override
public void changedUpdate(DocumentEvent e) {
textChanged();
}
@Override
public void insertUpdate(DocumentEvent e) {
textChanged();
}
@Override
public void removeUpdate(DocumentEvent e) {
textChanged();
}
});
}
private void textChanged() {
property.setValue(getText());
}
}
@@ -0,0 +1,41 @@
package org.diylc.images;
import javax.swing.Icon;
import javax.swing.ImageIcon;
/**
* Loads image resources as Icons.
*
* @author Branislav Stojkovic
*/
public enum IconLoader {
Delete("delete.png"), Add("add.png"), FolderOut("folder_out.png"), Garbage("garbage.png"), DiskBlue(
"disk_blue.png"), SaveAs("save_as.png"), Exit("exit.png"), DocumentPlainYellow(
"document_plain_yellow.png"), PhotoScenery("photo_scenery.png"), LightBulbOn(
"lightbulb_on.png"), LightBulbOff("lightbulb_off.png"), NotebookAdd("notebook_add.png"), FormGreen(
"form_green.png"), Gears("gears.png"), About("about.png"), Donate("donate.gif"), WindowColors(
"window_colors.png"), WindowGear("window_gear.png"), NavigateCheck("navigate_check.png"), Undo(
"undo.png"), Error("error.png"), Warning("warning.png"), ZoomSmall("zoom_small.png"), MoveSmall(
"move_small.png"), Print("print.png"), PDF("pdf.png"), Excel("excel.png"), CSV(
"csv.png"), HTML("html.png"), Image("image.png"), Cut("cut.png"), Copy("copy.png"), Paste(
"paste.png"), Selection("selection.png"), BOM("bom.png"), BlackBoard("blackboard.png"), IdCard(
"id_card.png"), IdCardAdd("id_card_add.png"), Chest("chest.png"), Upload("upload.png"), Wrench(
"wrench.png"), ;
protected String name;
private IconLoader(String name) {
this.name = name;
}
public Icon getIcon() {
java.net.URL imgURL = getClass().getResource(name);
if (imgURL != null) {
return new ImageIcon(imgURL, name);
} else {
System.err.println("Couldn't find file: " + name);
return null;
}
}
}
Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 749 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 707 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 714 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 993 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 863 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 960 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 595 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 781 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 914 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 876 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 853 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 596 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 696 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 597 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 928 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 892 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 751 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 834 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 842 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 910 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 875 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 694 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 773 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1004 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 995 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 656 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 675 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 708 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 832 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 852 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 894 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 789 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 785 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 798 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 733 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 747 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 709 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 728 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 835 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 895 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 947 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 766 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 376 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 879 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 857 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 844 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 816 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 541 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 775 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 847 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

@@ -0,0 +1,9 @@
log4j.rootLogger = DEBUG, fileout, stdout
log4j.appender.fileout = com.diyfever.gui.miscutils.NewLogForEachRunFileAppender
log4j.appender.fileout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
log4j.appender.fileout.layout = org.apache.log4j.PatternLayout
log4j.appender.fileout.File = log/log.log
log4j.appender.stdout = org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout.ConversionPattern = %d{ABSOLUTE} %5p [%t] %c{1} - %m%n
log4j.appender.stdout.layout = org.apache.log4j.PatternLayout
@@ -0,0 +1,11 @@
package org.diylc.model;
/**
* Enumerates all drawing layers.
*
* @author Branislav Stojkovic
*/
public enum ComponentLayer {
BELOW_CHASSIS, CHASSIS, ABOVE_CHASSIS, BELOW_BOARD, BOARD, TRACE, COMPONENT, ABOVE_COMPONENT;
}
@@ -0,0 +1,11 @@
package org.diylc.model;
/**
* Enumerates all possible states that a component can be in.
*
* @author Branislav Stojkovic
*/
public enum ComponentState {
NORMAL, SELECTED, LOCKED, DRAGGING
}
@@ -0,0 +1,26 @@
package org.diylc.model;
import java.awt.Graphics2D;
import java.io.Serializable;
/**
* Interface for component instance. Implementation classes of this interface
* will be instantiated by the application when component is added to the
* canvas. <br>
* <br>
* <b>Note: </b>Implementing classes must have an empty constructor.
*
* @author Branislav Stojkovic
*
* @see IComponentType
*/
public interface IComponentInstance extends Serializable {
/**
* Draws the component onto the {@link Graphics2D}.
*
* @param g2d
* @param componentState
*/
void draw(Graphics2D g2d, ComponentState componentState);
}
@@ -0,0 +1,65 @@
package org.diylc.model;
import javax.swing.Icon;
/**
* Interface used to describe a component type.
*
* @author Branislav Stojkovic
*
* @see IComponentInstance
*/
public interface IComponentType {
/**
* Returns component type name.
*
* @return
*/
String getName();
/**
* Returns component instance name prefix, e.g. "R" for resistors, "C" for
* capacitors, etc.
*
* @return
*/
String getInstanceNamePrefix();
/**
* Returns component category.
*
* @return
*/
String getCategory();
/**
* Returns component type description that may contain HTML tags.
*
* @return
*/
String getDescription();
/**
* Returns an {@link Icon} used to represent component type.
*
* @return
*/
Icon getIcon();
/**
* Returns a {@link ComponentLayer} where this component belongs.
*
* @return
*/
ComponentLayer getComponentLayer();
/**
* Returns class that represents component instances of this component type.
* Application will instantiate objects of this class when components are
* created.
*
* @return
*/
Class<? extends IComponentInstance> getComponentInstanceClass();
}
@@ -0,0 +1,168 @@
package org.diylc.model;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import org.diylc.model.annotations.EditableProperty;
import org.diylc.model.measures.Size;
import org.diylc.model.measures.SizeUnit;
/**
* Entity class that defines a project. Contains project properties and a
* collection of components.This class is serialized to file. Some filed getters
* are tagged with {@link EditableProperty} to enable for user to edit them.
*
* @author Branislav Stojkovic
*/
public class Project implements Serializable {
private static final long serialVersionUID = 1L;
public static String DEFAULT_TITLE = "New Project";
public static Size DEFAULT_WIDTH = new Size(29d, SizeUnit.cm);
public static Size DEFAULT_HEIGHT = new Size(21d, SizeUnit.cm);
private String title;
private String author;
private String description;
private Size width;
private Size height;
private List<IComponentInstance> components;
public Project() {
components = new ArrayList<IComponentInstance>();
title = DEFAULT_TITLE;
author = System.getProperty("user.name");
width = DEFAULT_WIDTH;
height = DEFAULT_HEIGHT;
}
public Project(String title, String author, String description, Size width, Size height,
List<IComponentInstance> components) {
super();
this.title = title;
this.author = author;
this.description = description;
this.width = width;
this.height = height;
this.components = components;
}
@EditableProperty
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
@EditableProperty
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
@EditableProperty
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@EditableProperty
public Size getWidth() {
return width;
}
public void setWidth(Size width) {
this.width = width;
}
@EditableProperty
public Size getHeight() {
return height;
}
public void setHeight(Size height) {
this.height = height;
}
public List<IComponentInstance> getComponents() {
return components;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((author == null) ? 0 : author.hashCode());
result = prime * result + ((components == null) ? 0 : components.hashCode());
result = prime * result + ((description == null) ? 0 : description.hashCode());
result = prime * result + ((height == null) ? 0 : height.hashCode());
result = prime * result + ((title == null) ? 0 : title.hashCode());
result = prime * result + ((width == null) ? 0 : width.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Project other = (Project) obj;
if (author == null) {
if (other.author != null)
return false;
} else if (!author.equals(other.author))
return false;
if (components == null) {
if (other.components != null)
return false;
} else if (!components.equals(other.components))
return false;
if (description == null) {
if (other.description != null)
return false;
} else if (!description.equals(other.description))
return false;
if (height == null) {
if (other.height != null)
return false;
} else if (!height.equals(other.height))
return false;
if (title == null) {
if (other.title != null)
return false;
} else if (!title.equals(other.title))
return false;
if (width == null) {
if (other.width != null)
return false;
} else if (!width.equals(other.width))
return false;
return true;
}
// @Override
// public Project clone() throws CloneNotSupportedException {
// List<IComponentInstance> clonedComponents = new
// ArrayList<IComponentInstance>();
// for (IComponentInstance component : components) {
// clonedComponents.add(component.clone());
// }
// Project project = new Project(title, author, description,
// width.clone(), height.clone(), clonedComponents);
// return project;
// }
}
@@ -0,0 +1,22 @@
package org.diylc.model;
/**
* Enumerates control point visibility policies.
*
* @author Branislav Stojkovic
*/
public enum VisibilityPolicy {
/**
* Control point should be rendered all the time.
*/
ALWAYS,
/**
* Control point should be rendered only when the component is selected.
*/
WHEN_SELECTED,
/**
* Control point should not be rendered regardless of component selection.
*/
NEVER;
}
@@ -0,0 +1,15 @@
package org.diylc.model.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Annotates getter for the component name that will be shown in the BOM. Only
* one getter per class may be tagged with this annotation.
*
* @author Branislav Stojkovic
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface BomName {
}
@@ -0,0 +1,15 @@
package org.diylc.model.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Annotates getter for the component value that will be shown in the BOM. Only
* one getter per class may be tagged with this annotation.
*
* @author Branislav Stojkovic
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface BomValue {
}
@@ -0,0 +1,9 @@
package org.diylc.model.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
public @interface ComponentName {
}
@@ -0,0 +1,49 @@
package org.diylc.model.annotations;
import java.awt.Point;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import org.diylc.model.VisibilityPolicy;
/**
* Annotation for control points. This annotation may be added fields of type
* {@link Point} only when both getters and setters exist. Annotation is added
* always on the getter.
*
* @author Branislav Stojkovic
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface ControlPoint {
/**
* Determines when should the control point be rendered on the screen.
*
* @return
*/
VisibilityPolicy visibilityPolicy() default VisibilityPolicy.ALWAYS;
/**
* If true, application will allow the user to edit the control point.
*
* @return
*/
boolean editable() default true;
/**
* If true, the control point may be joined with other components' control
* points.
*
* @return
*/
boolean sticky() default true;
// /**
// * If true, the control point is the main control point for the component.
// * There cannot be more than one control point for a single component.
// *
// * @return
// */
// boolean main() default false;
}
@@ -0,0 +1,31 @@
package org.diylc.model.annotations;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Used to annotate editable component property. Editable property XYZ must have
* both getter and setter named <code>getXYZ</code> and <code>setXYZ</code>
* respectively and this annotation must be placed on the getter method.
*
* @author Branislav Stojkovic
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface EditableProperty {
/**
* Returns property name. If left blank property name will be extracted from
* the getter name, e.g. getter <code>getXYZ</code> will induce property
* name <code>XYZ</code>.
*
* @return
*/
String name() default "";
/**
* If true, application may set default value for this property.
*
* @return
*/
boolean defaultable() default false;
}
@@ -0,0 +1,76 @@
package org.diylc.model.measures;
import java.io.Serializable;
import java.text.DecimalFormat;
import java.text.Format;
public class AbstractMeasure<T extends Enum<? extends Unit>> implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
protected static final Format format = new DecimalFormat("#.00##");
protected Double value;
protected T unit;
public AbstractMeasure() {
}
public AbstractMeasure(Double value, T unit) {
super();
this.value = value;
this.unit = unit;
}
public Double getValue() {
return value;
}
public void setValue(Double value) {
this.value = value;
}
public T getUnit() {
return unit;
}
public void setUnit(T multiplier) {
this.unit = multiplier;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((unit == null) ? 0 : unit.hashCode());
result = prime * result + ((value == null) ? 0 : value.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
AbstractMeasure<?> other = (AbstractMeasure<?>) obj;
if (unit == null) {
if (other.unit != null)
return false;
} else if (!unit.equals(other.unit))
return false;
if (value == null) {
if (other.value != null)
return false;
} else if (!value.equals(other.value))
return false;
return true;
}
@Override
public String toString() {
return format.format(value) + " " + unit;
}
}

Some files were not shown because too many files have changed in this diff Show More