@@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<classpath>
|
||||
<classpathentry kind="src" path="src"/>
|
||||
<classpathentry kind="src" path="test"/>
|
||||
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/>
|
||||
<classpathentry kind="lib" path="lib/log4j-1.2.15.jar"/>
|
||||
<classpathentry kind="lib" path="lib/xstream-1.3.1.jar"/>
|
||||
<classpathentry kind="lib" path="lib/junit-4.7.jar"/>
|
||||
<classpathentry kind="lib" path="lib/iText-2.1.7.jar"/>
|
||||
<classpathentry kind="lib" path="lib/cloning-1.5.jar"/>
|
||||
<classpathentry kind="lib" path="lib/objenesis-1.1.jar"/>
|
||||
<classpathentry combineaccessrules="false" kind="src" path="/GUI-Framework"/>
|
||||
<classpathentry kind="output" path="bin"/>
|
||||
</classpath>
|
||||
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<projectDescription>
|
||||
<name>DIYLC</name>
|
||||
<comment></comment>
|
||||
<projects>
|
||||
</projects>
|
||||
<buildSpec>
|
||||
<buildCommand>
|
||||
<name>org.eclipse.jdt.core.javabuilder</name>
|
||||
<arguments>
|
||||
</arguments>
|
||||
</buildCommand>
|
||||
</buildSpec>
|
||||
<natures>
|
||||
<nature>org.eclipse.jdt.core.javanature</nature>
|
||||
</natures>
|
||||
</projectDescription>
|
||||
@@ -0,0 +1,31 @@
|
||||
<map>
|
||||
<entry>
|
||||
<string>defaults</string>
|
||||
<map>
|
||||
<entry>
|
||||
<string>com.diyfever.diylc.components.MockComponentInstance:C</string>
|
||||
<com.diyfever.diylc.model.measures.Capacitance>
|
||||
<value>22.0</value>
|
||||
<unit class="com.diyfever.diylc.model.measures.CapacitanceUnit">uF</unit>
|
||||
</com.diyfever.diylc.model.measures.Capacitance>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>com.diyfever.diylc.components.MockComponentInstance:Color</string>
|
||||
<awt-color>
|
||||
<red>255</red>
|
||||
<green>0</green>
|
||||
<blue>0</blue>
|
||||
<alpha>255</alpha>
|
||||
</awt-color>
|
||||
</entry>
|
||||
</map>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>lastPath</string>
|
||||
<string>C:\Documents and Settings\Branislav Stojkovic\Desktop</string>
|
||||
</entry>
|
||||
<entry>
|
||||
<string>metric</string>
|
||||
<boolean>true</boolean>
|
||||
</entry>
|
||||
</map>
|
||||
@@ -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,86 @@
|
||||
package com.diyfever.diylc;
|
||||
|
||||
import javax.swing.UIManager;
|
||||
|
||||
import org.apache.log4j.PropertyConfigurator;
|
||||
|
||||
import com.diyfever.diylc.gui.MainFrame;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Branislav Stojkovic
|
||||
*/
|
||||
public class DIYLCStarter {
|
||||
|
||||
/**
|
||||
* @param args
|
||||
*/
|
||||
public static void main(String[] args) {
|
||||
PropertyConfigurator.configure("log4j.properties");
|
||||
|
||||
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,66 @@
|
||||
package com.diyfever.diylc.common;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.beans.PropertyChangeListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
public class ActivePoint extends Point {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private List<PropertyChangeListener> listeners = new ArrayList<PropertyChangeListener>();
|
||||
|
||||
public ActivePoint() {
|
||||
super();
|
||||
}
|
||||
|
||||
public ActivePoint(int x, int y) {
|
||||
super(x, y);
|
||||
}
|
||||
|
||||
public ActivePoint(Point p) {
|
||||
super(p);
|
||||
}
|
||||
|
||||
public void addPropertyChangeListener(PropertyChangeListener element) {
|
||||
listeners.add(element);
|
||||
}
|
||||
|
||||
public boolean removePropertyChangeListener(Object o) {
|
||||
return listeners.remove(o);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(double x, double y) {
|
||||
this.setLocation(new Point2D.Double(x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(int x, int y) {
|
||||
this.setLocation(new Point(x, y));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setLocation(Point p) {
|
||||
for (PropertyChangeListener listener : listeners) {
|
||||
listener.propertyChange(new PropertyChangeEvent(this, "value",
|
||||
this, p));
|
||||
}
|
||||
super.setLocation(p);
|
||||
}
|
||||
|
||||
public void setLocationSilent(double x, double y) {
|
||||
super.setLocation(x, y);
|
||||
}
|
||||
|
||||
public void setLocationSilent(int x, int y) {
|
||||
super.setLocation(x, y);
|
||||
}
|
||||
|
||||
public void setLocationSilent(Point p) {
|
||||
super.setLocation(p);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package com.diyfever.diylc.common;
|
||||
|
||||
public class BadPositionException extends Exception {
|
||||
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
package com.diyfever.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 com.diyfever.diylc.model.IComponentInstance;
|
||||
|
||||
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,102 @@
|
||||
package com.diyfever.diylc.common;
|
||||
|
||||
import java.awt.Point;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.diyfever.diylc.model.IComponentInstance;
|
||||
import com.diyfever.diylc.model.VisibilityPolicy;
|
||||
|
||||
public class ControlPointWrapper {
|
||||
|
||||
private String name;
|
||||
private ActivePoint 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;
|
||||
}
|
||||
|
||||
public void readFrom(IComponentInstance component)
|
||||
throws IllegalArgumentException, IllegalAccessException,
|
||||
InvocationTargetException {
|
||||
Object object = getter.invoke(component);
|
||||
if (object instanceof ActivePoint) {
|
||||
value = (ActivePoint) getter.invoke(component);
|
||||
} else {
|
||||
value = new ActivePoint((Point) object);
|
||||
}
|
||||
}
|
||||
|
||||
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 ActivePoint getValue() {
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(ActivePoint 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,6 @@
|
||||
package com.diyfever.diylc.common;
|
||||
|
||||
public enum DrawOption {
|
||||
|
||||
SELECTION, ZOOM, GRID, CONTROL_POINTS, ANTIALIASING;
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
package com.diyfever.diylc.common;
|
||||
|
||||
import java.awt.Rectangle;
|
||||
|
||||
import com.diyfever.diylc.model.IComponentType;
|
||||
import com.diyfever.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;
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.diyfever.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,277 @@
|
||||
package com.diyfever.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.EnumSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.JComponent;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.JPopupMenu.Separator;
|
||||
|
||||
import com.diyfever.diylc.model.ComponentLayer;
|
||||
import com.diyfever.diylc.model.IComponentInstance;
|
||||
import com.diyfever.diylc.model.IComponentType;
|
||||
import com.diyfever.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, EnumSet<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);
|
||||
|
||||
/**
|
||||
* Note: point coordinates are scaled for zoom factor.
|
||||
*
|
||||
* @param point
|
||||
*/
|
||||
void pointClickedOn(Point point, boolean ctrlDown, boolean shiftDown,
|
||||
boolean altDown);
|
||||
|
||||
/**
|
||||
* Returns a list of currently selected components.
|
||||
*
|
||||
* @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,139 @@
|
||||
package com.diyfever.diylc.common;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.lang.reflect.Method;
|
||||
|
||||
import com.diyfever.diylc.model.IComponentInstance;
|
||||
|
||||
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 com.diyfever.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,162 @@
|
||||
package com.diyfever.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 com.diyfever.diylc.common.PropertyWrapper;
|
||||
import com.diyfever.diylc.gui.components.OverwritePromptFileChooser;
|
||||
import com.diyfever.diylc.gui.editor.PropertyEditorDialog;
|
||||
import com.diyfever.diylc.plugins.file.BomDialog;
|
||||
import com.diyfever.diylc.plugins.file.BomEntry;
|
||||
import com.diyfever.diylc.plugins.online.view.LoginDialog;
|
||||
import com.diyfever.diylc.plugins.online.view.NewUserDialog;
|
||||
import com.diyfever.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 com.diyfever.diylc.gui;
|
||||
|
||||
import javax.swing.Action;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JComponent;
|
||||
|
||||
import com.diyfever.diylc.common.BadPositionException;
|
||||
import com.diyfever.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,173 @@
|
||||
package com.diyfever.diylc.gui;
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Container;
|
||||
import java.awt.Dimension;
|
||||
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 com.diyfever.diylc.common.BadPositionException;
|
||||
import com.diyfever.diylc.components.MockComponentInstance;
|
||||
import com.diyfever.diylc.model.Project;
|
||||
import com.diyfever.diylc.plugins.canvas.CanvasPlugin;
|
||||
import com.diyfever.diylc.plugins.clipboard.ClipboardManager;
|
||||
import com.diyfever.diylc.plugins.file.FileManager;
|
||||
import com.diyfever.diylc.plugins.help.HelpManager;
|
||||
import com.diyfever.diylc.plugins.online.OnlineManager;
|
||||
import com.diyfever.diylc.plugins.statusbar.StatusBar;
|
||||
import com.diyfever.diylc.plugins.toolbox.ToolBox;
|
||||
import com.diyfever.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;
|
||||
|
||||
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());
|
||||
presenter.installPlugin(new 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);
|
||||
}
|
||||
|
||||
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,41 @@
|
||||
package com.diyfever.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,39 @@
|
||||
package com.diyfever.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 com.diyfever.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,26 @@
|
||||
package com.diyfever.diylc.gui.editor;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Component;
|
||||
|
||||
import com.diyfever.diylc.common.PropertyWrapper;
|
||||
import com.diyfever.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 com.diyfever.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 com.diyfever.diylc.common.PropertyWrapper;
|
||||
import com.diyfever.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,140 @@
|
||||
package com.diyfever.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 com.diyfever.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,40 @@
|
||||
package com.diyfever.diylc.gui.editor;
|
||||
|
||||
import javax.swing.JTextField;
|
||||
import javax.swing.event.DocumentEvent;
|
||||
import javax.swing.event.DocumentListener;
|
||||
|
||||
import com.diyfever.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,71 @@
|
||||
package com.diyfever.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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
After Width: | Height: | Size: 875 B |
|
After Width: | Height: | Size: 729 B |
|
After Width: | Height: | Size: 749 B |
|
After Width: | Height: | Size: 736 B |
|
After Width: | Height: | Size: 707 B |
|
After Width: | Height: | Size: 714 B |
|
After Width: | Height: | Size: 993 B |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 863 B |
|
After Width: | Height: | Size: 708 B |
|
After Width: | Height: | Size: 960 B |
|
After Width: | Height: | Size: 728 B |
|
After Width: | Height: | Size: 595 B |
|
After Width: | Height: | Size: 781 B |
|
After Width: | Height: | Size: 914 B |
|
After Width: | Height: | Size: 876 B |
|
After Width: | Height: | Size: 853 B |
|
After Width: | Height: | Size: 596 B |
|
After Width: | Height: | Size: 696 B |
|
After Width: | Height: | Size: 597 B |
|
After Width: | Height: | Size: 1.7 KiB |
|
After Width: | Height: | Size: 928 B |
|
After Width: | Height: | Size: 892 B |
|
After Width: | Height: | Size: 751 B |
|
After Width: | Height: | Size: 834 B |
|
After Width: | Height: | Size: 857 B |
|
After Width: | Height: | Size: 842 B |
|
After Width: | Height: | Size: 910 B |
|
After Width: | Height: | Size: 875 B |
|
After Width: | Height: | Size: 694 B |
|
After Width: | Height: | Size: 773 B |
|
After Width: | Height: | Size: 1004 B |
|
After Width: | Height: | Size: 995 B |
|
After Width: | Height: | Size: 4.1 KiB |
|
After Width: | Height: | Size: 656 B |
|
After Width: | Height: | Size: 675 B |
|
After Width: | Height: | Size: 708 B |
|
After Width: | Height: | Size: 832 B |
|
After Width: | Height: | Size: 852 B |
|
After Width: | Height: | Size: 894 B |
|
After Width: | Height: | Size: 728 B |
|
After Width: | Height: | Size: 789 B |
|
After Width: | Height: | Size: 785 B |
|
After Width: | Height: | Size: 798 B |
|
After Width: | Height: | Size: 733 B |
|
After Width: | Height: | Size: 1.2 KiB |
|
After Width: | Height: | Size: 747 B |
|
After Width: | Height: | Size: 709 B |
|
After Width: | Height: | Size: 816 B |
|
After Width: | Height: | Size: 783 B |
|
After Width: | Height: | Size: 1.4 KiB |
|
After Width: | Height: | Size: 728 B |
|
After Width: | Height: | Size: 835 B |
|
After Width: | Height: | Size: 895 B |
|
After Width: | Height: | Size: 947 B |
|
After Width: | Height: | Size: 766 B |
|
After Width: | Height: | Size: 376 B |
|
After Width: | Height: | Size: 879 B |
|
After Width: | Height: | Size: 857 B |
|
After Width: | Height: | Size: 844 B |
|
After Width: | Height: | Size: 816 B |
|
After Width: | Height: | Size: 541 B |
|
After Width: | Height: | Size: 775 B |
|
After Width: | Height: | Size: 858 B |
|
After Width: | Height: | Size: 847 B |