? image/src/org/netbeans/modules/image/arc.gif ? image/src/org/netbeans/modules/image/arrow.gif ? image/src/org/netbeans/modules/image/brush.gif ? image/src/org/netbeans/modules/image/brushCircle.gif ? image/src/org/netbeans/modules/image/brushCursor.gif ? image/src/org/netbeans/modules/image/brushLeft.gif ? image/src/org/netbeans/modules/image/brushLongLeft.gif ? image/src/org/netbeans/modules/image/brushLongRight.gif ? image/src/org/netbeans/modules/image/brushRight.gif ? image/src/org/netbeans/modules/image/brushSquare.gif ? image/src/org/netbeans/modules/image/eraser.gif ? image/src/org/netbeans/modules/image/fill.gif ? image/src/org/netbeans/modules/image/fillCursor.gif ? image/src/org/netbeans/modules/image/fillEllipse.gif ? image/src/org/netbeans/modules/image/fillRect.gif ? image/src/org/netbeans/modules/image/line.gif ? image/src/org/netbeans/modules/image/noFillEllipse.gif ? image/src/org/netbeans/modules/image/noFillRect.gif ? image/src/org/netbeans/modules/image/noLineEllipse.gif ? image/src/org/netbeans/modules/image/noLineRect.gif ? image/src/org/netbeans/modules/image/oval.gif ? image/src/org/netbeans/modules/image/pen.gif ? image/src/org/netbeans/modules/image/penCursor.gif ? image/src/org/netbeans/modules/image/polygon.gif ? image/src/org/netbeans/modules/image/rect.gif ? image/src/org/netbeans/modules/image/spray.gif ? image/src/org/netbeans/modules/image/sprayCursor.gif Index: image/src/org/netbeans/modules/image/BitmapAirbrush.java =================================================================== RCS file: image/src/org/netbeans/modules/image/BitmapAirbrush.java diff -N image/src/org/netbeans/modules/image/BitmapAirbrush.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/BitmapAirbrush.java 5 Jul 2005 11:24:32 -0000 @@ -0,0 +1,69 @@ +package org.netbeans.modules.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.BasicStroke; +import java.awt.Point; +import java.awt.Shape; + +import java.awt.geom.Ellipse2D; +import java.awt.geom.GeneralPath; + +import java.util.Enumeration; + +import java.lang.Math; + +/** + * Implementation of the airbrush tool + * + * @author Timothy Boyce + */ +class BitmapAirbrush extends BitmapTool { + protected GeneralPath brushShape; + Ellipse2D.Float brushArea; + protected int brushSize; + protected int brushSparcity; + + public BitmapAirbrush(int xVal, int yVal, Color c, int size, int sparcity){ + super(xVal, yVal, c); + + brushSize = size; + brushSparcity = sparcity; + } + + public void writeToGraphic(Graphics2D g){ + g.setStroke(new BasicStroke(1)); + g.setColor(getFillColor()); + g.setPaintMode(); + + Enumeration e = pathTrace.elements(); + Point p = null; + Point l = null; + Point x = null; + + while(e.hasMoreElements()){ + p = (Point)e.nextElement(); + moveBrush(p); + g.draw(brushShape); + } + + pathTrace.removeAllElements(); + if(p != null) pathTrace.addElement(p); + } + + private void moveBrush(Point p){ + brushShape = new GeneralPath(); + brushArea = new Ellipse2D.Float(((float)p.x - (brushSize/2)),(float)(p.y - (brushSize/2)), (float)brushSize, (float)brushSize); + + /* Choose random pixils in the area */ + int i; + for(i=0; i= 0 && yVal >= 0 && xVal < imageObject.getWidth() && yVal < imageObject.getHeight()); + } + + private void dumpStack(){ + while(!pixelStack.empty()){ + Point p = (Point)pixelStack.pop(); + imageObject.setRGB(p.x, p.y, DstRGBColor); + } + } + + public void setDragPoint(int xVal, int yVal){ + } + + public void setReleasePoint(int xVal, int yVal){ + } + + public void setClickPoint(int xVal, int yVal){ + } + + /* Return the tool status */ + public boolean getToolStatus(){ + return true; + } + + public boolean getMemoryless(){ + return false; + } + + public void writeToGraphic(Graphics2D g){ + } +} Index: image/src/org/netbeans/modules/image/BitmapFreehandBrush.java =================================================================== RCS file: image/src/org/netbeans/modules/image/BitmapFreehandBrush.java diff -N image/src/org/netbeans/modules/image/BitmapFreehandBrush.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/BitmapFreehandBrush.java 5 Jul 2005 11:24:33 -0000 @@ -0,0 +1,115 @@ +package org.netbeans.modules.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.Shape; +import java.awt.Rectangle; +import java.awt.BasicStroke; + +import java.awt.geom.Ellipse2D; +import java.awt.geom.Line2D; + +import java.util.Enumeration; + +/** + * Implementation of the brush tool + * + * @author Timothy Boyce + */ +class BitmapFreehandBrush extends BitmapTool { + protected Shape brushShape; + protected int brushSize; + protected int brushSlant; + protected int brushType; + + public static final int BRUSH_BOX = 1; + public static final int BRUSH_CIRC = 2; + public static final int BRUSH_LINE_135 = 3; + public static final int BRUSH_LINE_45 = 4; + + private final int BRUSH_LINE = 5; + private final int SLANT_135 = 1; + private final int SLANT_45 = 2; + + public BitmapFreehandBrush(int xVal, int yVal, Color c, int size){ + super(xVal, yVal, c); + + brushSlant = SLANT_45; + brushSize = size; + brushType = BRUSH_BOX; + } + + public BitmapFreehandBrush(int xVal, int yVal, Color c, int size, int type){ + super(xVal, yVal, c); + + if(type == BRUSH_LINE_135){ + brushSlant = SLANT_135; + brushType = BRUSH_LINE; + } + else if(type == BRUSH_LINE_45){ + brushSlant = SLANT_45; + brushType = BRUSH_LINE; + } + else{ + brushType = type; + brushSlant = 0; + } + + brushSize = size; + } + + public void writeToGraphic(Graphics2D g){ + g.setStroke(new BasicStroke(1)); + g.setColor(getFillColor()); + g.setPaintMode(); + + Enumeration e = pathTrace.elements(); + Point p = null; + Point l = null; + Point x = null; + + while(e.hasMoreElements()){ + p = (Point)e.nextElement(); + + Enumeration subPoints = joinPoints(p, l).elements(); + + while(subPoints.hasMoreElements()){ + x = (Point)subPoints.nextElement(); + moveBrush(x); + g.fill(brushShape); + g.draw(brushShape); + } + + l = new Point(p.x, p.y); + } + + pathTrace.removeAllElements(); + if(p != null) pathTrace.addElement(p); + } + + private void moveBrush(Point p){ + switch(brushType){ + case BRUSH_BOX: + brushShape = new Rectangle(p.x - (brushSize/2), p.y - (brushSize/2), brushSize, brushSize); + return; + + case BRUSH_CIRC: + brushShape = new Ellipse2D.Float(((float)p.x - (brushSize/2)),(float)(p.y - (brushSize/2)), (float)brushSize, (float)brushSize); + return; + + case BRUSH_LINE: + BasicStroke b = new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); + if(brushSlant == SLANT_135) + brushShape = b.createStrokedShape(new Line2D.Float((float)(p.x - brushSize/2), (float)(p.y - brushSize/2), (float)(p.x + brushSize/2), (float)(p.y + brushSize/2))); + else + brushShape = b.createStrokedShape(new Line2D.Float((float)(p.x + brushSize/2), (float)(p.y - brushSize/2), (float)(p.x - brushSize/2), (float)(p.y + brushSize/2))); + return; + + default: + brushType = BRUSH_BOX; + brushShape = new Rectangle(p.x - (brushSize/2), p.y - (brushSize/2), brushSize, brushSize); + return; + } + } +} Index: image/src/org/netbeans/modules/image/BitmapFreehandLine.java =================================================================== RCS file: image/src/org/netbeans/modules/image/BitmapFreehandLine.java diff -N image/src/org/netbeans/modules/image/BitmapFreehandLine.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/BitmapFreehandLine.java 5 Jul 2005 11:24:33 -0000 @@ -0,0 +1,91 @@ +package org.netbeans.modules.image; + +import java.awt.Graphics2D; +import java.awt.BasicStroke; +import java.awt.Point; +import java.awt.Color; +import java.awt.geom.GeneralPath; +import java.util.Vector; + +/** + * Implimentation of the Pencil Edit Tool + * + * @author Timothy Boyce + */ +class BitmapFreehandLine implements EditTool{ + + /** Vector containing the last 3 points of the freehand line */ + protected Vector linePoints = new Vector(){ + public void addElement(Object obj){ + if(this.size() >= 3) + this.removeElementAt(0); + super.addElement(obj); + } + }; + + /** General Path used for drawing */ + protected GeneralPath linePath; + + /** Line Color used */ + protected Color lineColor; + + /** Tool status boolean */ + protected boolean toolStatus = false; + + /** Use the default super class constructior */ + public BitmapFreehandLine(int xVal, int yVal, Color c){ + linePoints.addElement(new Point(xVal, yVal)); + lineColor = c; + } + + public boolean getToolStatus(){ + return toolStatus; + } + + public boolean getMemoryless(){ + return true; + } + + public void setDragPoint(int xVal, int yVal){ + linePoints.addElement(new Point(xVal, yVal)); + } + + public void setClickPoint(int xVal, int yVal){ + linePoints.addElement(new Point(xVal, yVal)); + } + + public void setReleasePoint(int xVal, int yVal){ + linePoints.addElement(new Point(xVal, yVal)); + toolStatus = true; + } + + + public void writeToGraphic(Graphics2D g){ + Point p1, p2, p3; + + g.setStroke(new BasicStroke(1)); + g.setPaintMode(); + g.setColor(lineColor); + + linePath = new GeneralPath(); + + p1 = (Point)linePoints.firstElement(); + linePath.moveTo(p1.x, p1.y); + + if(linePoints.size() == 3) + p2 = (Point)linePoints.get(1); + else + p2 = (Point)linePoints.lastElement(); + + linePath.lineTo(p2.x, p2.y); + + if(linePoints.size() == 2) + p3 = (Point)linePoints.firstElement(); + else + p3 = (Point)linePoints.lastElement(); + + linePath.lineTo(p3.x, p3.y); + + g.draw(linePath); + } +} Index: image/src/org/netbeans/modules/image/BitmapTool.java =================================================================== RCS file: image/src/org/netbeans/modules/image/BitmapTool.java diff -N image/src/org/netbeans/modules/image/BitmapTool.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/BitmapTool.java 5 Jul 2005 11:24:34 -0000 @@ -0,0 +1,112 @@ +package org.netbeans.modules.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Point; + +import java.util.Vector; + +import java.lang.Math; + +/** + * BitmapTool + * + * @author Timothy Boyce + */ +abstract class BitmapTool implements EditTool{ + protected Color fillColor; + protected Vector pathTrace; + + protected boolean toolStatus = false; + + public BitmapTool(int xVal, int yVal, Color c){ + pathTrace = new Vector(); + pathTrace.addElement(new Point(xVal, yVal)); + + fillColor = c; + } + + public void setDragPoint(int xVal, int yVal){ + pathTrace.addElement(new Point(xVal, yVal)); + } + + /* Default action taken on a release */ + public void setReleasePoint(int xVal, int yVal){ + pathTrace.addElement(new Point(xVal, yVal)); + toolStatus = true; + } + + /* Default action taken on a Click */ + public void setClickPoint(int xVal, int yVal){ + } + + /* Return the tool status */ + public boolean getToolStatus(){ + return toolStatus; + } + + protected Color getFillColor(){ + return fillColor; + } + + public boolean getMemoryless(){ + return true; + } + + /* Writes the current tool to the graphis object */ + public abstract void writeToGraphic(Graphics2D g); + + protected Vector joinPoints(Point p1, Point p2){ + Point start, end; + Vector subPath = new Vector(); + float m; + int b; + int tx, ty; + + if(p1 == null) + return subPath; + + if(p2 == null){ + subPath.addElement(p1); + return subPath; + } + + if(p1.x - p2.x == 0){ + /* Vertical Line */ + start = (p1.y < p2.y) ? p1 : p2; + end = (p1.y > p2.y) ? p1 : p2; + tx = start.x; + + for(ty=start.y+1; ty 1){ + /* Use Y Method */ + start = (p1.y < p2.y) ? p1 : p2; + end = (p1.y > p2.y) ? p1 : p2; + + for(ty=start.y+1; ty p2.x) ? p1 : p2; + + for(tx=start.x+1; tx 11) + toolSelected = TOOL_DEFAULT; + else + toolSelected = newTool; + }; + + public int getToolType(){ + return toolSelected; + } + + public void setRoundingFactor(int newFactor){ + if(newFactor < 0 || newFactor > 100) + roundingFactor = 0; + else + roundingFactor = newFactor; + } + + public int getRoundingFactor(){ + return roundingFactor; + } + + public void setSubTool(int newSubTool){ + if(newSubTool < 1 || newSubTool > 3) + subTool = SUB_LINEONLY; + else + subTool = newSubTool; + } + + public int getSubTool(){ + return subTool; + } + + public void setLineWidth(int newWidth){ + lineWidth = newWidth; + } + + public int getLineWidth(){ + return lineWidth; + } + + public void setBrushType(int newType){ + if(newType < 1 || newType > 4) + brushShape = BitmapFreehandBrush.BRUSH_BOX; + else + brushShape = newType; + } + + public int getBrushType(){ + return brushShape; + } + + public void setCustomCursor(Cursor newCursor){ + editCursor = newCursor; + setCursor(editCursor); + }; + + /** Set the scaling factor of the image */ + public void setScale(double newScale){ + this.currentScale = newScale; + repaint(0, 0, getHeight(), getWidth()); + }; + + public double getScale(){ + return currentScale; + } + + /* Return the pixel value after applying the current + zoom scale */ + protected int getScaledValue(int value, double scale){ + return (int)(value/scale); + } + + public void paint(Graphics g){ + /** Paint the component before anything else occurs */ + this.paintComponent(g); + + Graphics2D g2D = (Graphics2D)g; + + if (getSize().width <= 0 || getSize().height <= 0) + return; + + /** Draw this edit tool if the is one in use */ + if(currentTool != null){ + Graphics2D offScreenGraphics = (Graphics2D)offScreenImage.getGraphics(); + AffineTransform oldTransform = g2D.getTransform(); + g2D.transform(AffineTransform.getScaleInstance(currentScale, currentScale)); + + /** Drawing method for non-memoryless tools */ + if(!currentTool.getMemoryless()){ + currentTool.writeToGraphic(offScreenGraphics); + + g2D.drawImage(offScreenImage, 0, 0, null); + + offScreenGraphics.setComposite(AlphaComposite.getInstance(AlphaComposite.CLEAR, 0)); + offScreenGraphics.fillRect(0, 0, offScreenImage.getWidth(), offScreenImage.getHeight()); + + if(currentTool.getToolStatus()){ + currentTool.writeToGraphic((Graphics2D)imageObject.getGraphics()); + nonOScreenImage.setData(imageObject.getData()); + currentTool = null; + obs.setChanged(); + obs.notifyObservers(); + g2D.setTransform(oldTransform); + this.paintComponent(g); + } + } + else{ + /** Drawing method for memoryless tools */ + currentTool.writeToGraphic(offScreenGraphics); + + g2D.drawImage(offScreenImage, + 0, + 0, + (int)(imageObject.getWidth()), + (int)(imageObject.getHeight()), + 0, + 0, + imageObject.getWidth(), + imageObject.getHeight(), + this + ); + + if(currentTool.getToolStatus()){ + imageObject.setData(offScreenImage.getData()); + currentTool = null; + obs.setChanged(); + obs.notifyObservers(); + } + } + g2D.setTransform(oldTransform); + } + + /* Draw the grid onto the screen, if it is visable */ + if(showGrid) + drawGrid(g, imageObject.getWidth(), imageObject.getHeight()); + } + + /** Paint the currently visable, unedited image to the component */ + protected void paintComponent(Graphics g) { + super.paintComponent(g); + g.drawImage( + imageObject, + 0, + 0, + (int)(getScale() * imageObject.getWidth()), + (int)(getScale() *imageObject.getHeight()), + 0, + 0, + imageObject.getWidth(), + imageObject.getHeight(), + this + ); + } + + /** Attempt to draw a grid to the graphics object */ + private void drawGrid(Graphics g, int iconWidth, int iconHeight){ + int x = (int)(getScale () * iconWidth); + int y = (int)(getScale () * iconHeight); + + double gridDistance = getScale(); + + if(gridDistance < 2) + // Disable painting of grid if no image pixels would be visible. + return; + + g.setColor(gridColor); + + double actualDistance = gridDistance; + for(int i = (int)actualDistance; i < x ;actualDistance += gridDistance, i = (int)actualDistance) { + g.drawLine(i,0,i,(y-1)); + } + + actualDistance = gridDistance; + for(int j = (int)actualDistance; j < y; actualDistance += gridDistance, j = (int)actualDistance) { + g.drawLine(0,j,(x-1),j); + } + } + + /** Replace the Image object in the image display editor, with a new image object */ + public void reload(NBImageIcon newImage){ + this.imageObject = (BufferedImage)newImage.getImage(); + repaint(0, 0, getWidth(), getHeight()); + } +} Index: image/src/org/netbeans/modules/image/ImageHelp.html =================================================================== RCS file: image/src/org/netbeans/modules/image/ImageHelp.html diff -N image/src/org/netbeans/modules/image/ImageHelp.html --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/ImageHelp.html 5 Jul 2005 11:24:48 -0000 @@ -0,0 +1,16 @@ + + + +Creates a new image file. You can edit the file in the IDE's Image Editor. + Index: image/src/org/netbeans/modules/image/ImageOpenSupport.java =================================================================== RCS file: /cvs/image/src/org/netbeans/modules/image/ImageOpenSupport.java,v retrieving revision 1.13 diff -u -r1.13 ImageOpenSupport.java --- image/src/org/netbeans/modules/image/ImageOpenSupport.java 26 Jan 2005 14:04:12 -0000 1.13 +++ image/src/org/netbeans/modules/image/ImageOpenSupport.java 5 Jul 2005 11:24:49 -0000 @@ -172,4 +172,3 @@ } } // End of nested Environment class. } - Index: image/src/org/netbeans/modules/image/ImageSaveSupport.java =================================================================== RCS file: image/src/org/netbeans/modules/image/ImageSaveSupport.java diff -N image/src/org/netbeans/modules/image/ImageSaveSupport.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/ImageSaveSupport.java 5 Jul 2005 11:24:50 -0000 @@ -0,0 +1,139 @@ +package org.netbeans.modules.image; + +import java.awt.Component; +import java.awt.Image; +import java.awt.image.RenderedImage; +import java.io.IOException; +import java.io.File; +import java.util.Iterator; +import java.util.List; +import javax.imageio.IIOImage; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriteParam; +import javax.imageio.ImageWriter; +import javax.imageio.metadata.IIOMetadata; +import javax.imageio.stream.FileImageOutputStream; +import javax.swing.JOptionPane; + +import org.openide.cookies.SaveCookie; +import org.openide.util.NbBundle; +import org.openide.windows.TopComponent; + + +/** + * Support for saving images + * + * @author Jason Solomon + */ +public class ImageSaveSupport implements SaveCookie { + + private ImageDataObject imageDataObject; + + private Image image; + + private String format; + + /** Creates a new instance of ImageSaveSupport */ + public ImageSaveSupport(ImageDataObject ido) { + imageDataObject = ido; + } + + /** Invoke the save operation. + * @throws IOException if the object could not be saved + */ + public void save () throws java.io.IOException { + format = imageDataObject.getFormat(); + image = imageDataObject.getImage(); + + if(saveFile()) { + imageDataObject.reloadImage(); + imageDataObject.notifyUnmodified(); + } + else { + IOException ex = new IOException(NbBundle.getMessage(ImageSaveSupport.class, "MSG_UserAbortSave", imageDataObject.getPath())); + throw ex; + } + } + + private boolean saveFile() throws IOException { + boolean compressionSupported; + Iterator writers = ImageIO.getImageWritersByFormatName(format); + if(!writers.hasNext()) { + if(JOptionPane.showConfirmDialog(null, NbBundle.getMessage(ImageSaveSupport.class, "MSG_NoSaveSupportConfirm", format), NbBundle.getMessage(ImageSaveSupport.class, "LBL_NoSaveSupport"), JOptionPane.YES_NO_OPTION) == JOptionPane.YES_OPTION) { + TopComponent curComponent = TopComponent.getRegistry().getActivated(); + if(curComponent instanceof ImageViewer) { + ImageViewer currComponent = (ImageViewer) TopComponent.getRegistry().getActivated(); + imageDataObject.convertTo(currComponent); + } + } + IOException ex = new IOException(NbBundle.getMessage(ImageSaveSupport.class, "MSG_NoSaveSupport", format)); + throw ex; + } + ImageWriter writer = (ImageWriter)writers.next(); + ImageWriteParam iwp = writer.getDefaultWriteParam(); + + try { + compressionSupported = true; + iwp.setCompressionMode(ImageWriteParam.MODE_EXPLICIT); + } catch (UnsupportedOperationException e) { + compressionSupported = false; + iwp = writer.getDefaultWriteParam(); + } + + if(compressionSupported) { + return getCompression(writer, iwp); + } + else { + return writeFile(writer, iwp, (float)0.00); + } + } + + private boolean getCompression(ImageWriter writer, ImageWriteParam iwp) throws IOException { + String compressionStr; + float compression; + String dialogTitle = new String(NbBundle.getMessage(ImageSaveSupport.class, "LBL_CompressionLevel")); + String dialogLabel = new String(NbBundle.getMessage(ImageSaveSupport.class, "MSG_CompressionLevel")); + int i; + + String[] qualityDescTemp = iwp.getCompressionQualityDescriptions(); + float qualityValsTemp[] = iwp.getCompressionQualityValues(); + String[] qualityDesc = new String[qualityDescTemp.length + 1]; + float qualityVals[] = new float[qualityValsTemp.length + 1]; + for(i = 0; i < qualityDescTemp.length; i++) { + qualityDesc[i] = qualityDescTemp[i]; + qualityVals[i] = qualityValsTemp[i]; + } + qualityDesc[qualityDesc.length - 1] = "Default"; + qualityVals[qualityVals.length - 1] = (float)0.00; + + compressionStr = (String)JOptionPane.showInputDialog((Component)null, dialogLabel, + dialogTitle, JOptionPane.QUESTION_MESSAGE, null, qualityDesc, qualityDesc[qualityDesc.length - 1]); + + if(compressionStr != null) { + for(i = 0; i < qualityDesc.length; i++) { + if(compressionStr.equals(qualityDesc[i])) + break; + } + + compression = qualityVals[i]; + + return writeFile(writer, iwp, compression); + } + return false; + } + + private boolean writeFile(ImageWriter writer, ImageWriteParam iwp, float compression) throws IOException { + String filePath = imageDataObject.getPath(); + IIOImage iioImage; + FileImageOutputStream output; + + if(compression != (float)0.00) { + iwp.setCompressionQuality(compression); + } + iioImage = new IIOImage((RenderedImage)image, (List)null, (IIOMetadata)null); + output = new FileImageOutputStream(new File(filePath)); + writer.setOutput(output); + writer.write((IIOMetadata)null, iioImage, iwp); + return true; + } +} Index: image/src/org/netbeans/modules/image/ImageViewer.java =================================================================== RCS file: /cvs/image/src/org/netbeans/modules/image/ImageViewer.java,v retrieving revision 1.48 diff -u -r1.48 ImageViewer.java --- image/src/org/netbeans/modules/image/ImageViewer.java 16 Feb 2005 14:42:50 -0000 1.48 +++ image/src/org/netbeans/modules/image/ImageViewer.java 5 Jul 2005 11:25:04 -0000 @@ -13,15 +13,30 @@ package org.netbeans.modules.image; +import java.awt.AlphaComposite; +import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; +import java.awt.Cursor; import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.Font; import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.Point; +import java.awt.GridBagLayout; +import java.awt.GridBagConstraints; +import java.awt.GridLayout; import java.awt.Image; +import java.awt.Rectangle; +import java.awt.Shape; import java.awt.Toolkit; import java.awt.event.ActionListener; import java.awt.event.ActionEvent; +import java.awt.geom.Line2D; +import java.awt.geom.Ellipse2D; +import java.awt.geom.RoundRectangle2D; import java.beans.PropertyChangeEvent; import java.beans.PropertyChangeListener; import java.io.IOException; @@ -29,18 +44,32 @@ import java.io.ObjectOutput; import java.util.ArrayList; import java.util.Collection; +import java.util.Enumeration; import java.util.HashSet; import java.util.Iterator; import java.util.Set; +import java.util.Observer; +import java.util.Observable; +import javax.swing.AbstractButton; import javax.swing.Action; +import javax.swing.ButtonGroup; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.JFormattedTextField; import javax.swing.JLabel; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JScrollPane; +import javax.swing.JSpinner; +import javax.swing.JTextField; import javax.swing.JToggleButton; import javax.swing.JToolBar; +import javax.swing.SpinnerModel; +import javax.swing.SpinnerNumberModel; import org.openide.filesystems.FileObject; import org.openide.filesystems.FileUtil; @@ -57,10 +86,10 @@ /** * Top component providing a viewer for images. - * @author Petr Hamernik, Ian Formanek, Lukas Tadial + * @author Petr Hamernik, Ian Formanek, Lukas Tadial, Dragan Mandic, Jason Solomon, Timothy Boyce * @author Marian Petras */ -public class ImageViewer extends CloneableTopComponent { +public class ImageViewer extends CloneableTopComponent implements Observer { /** Serialized version UID. */ static final long serialVersionUID =6960127954234034486L; @@ -72,28 +101,60 @@ private NBImageIcon storedImage; /** Component showing image. */ - private JPanel panel; + private ImageDisplayEdit panel; /** Scale of image. */ private double scale = 1.0D; - /** On/off grid. */ - private boolean showGrid = false; - /** Increase/decrease factor. */ private final double changeFactor = Math.sqrt(2.0D); - /** Grid color. */ - private final Color gridColor = Color.black; - /** Listens for name changes. */ private PropertyChangeListener nameChangeL; /** collection of all buttons in the toolbar */ private final Collection/**/ toolbarButtons = new ArrayList/**/(11); - - + /** All the custom cursors used in the ImageViewer */ + private Cursor sprayCursor; + private Cursor penCursor; + private Cursor fillCursor; + private Cursor brushCursor; + + /** These panels contain buttons that appear or + disappear depending on what tool is selected */ + private class ExtButtonGroup extends ButtonGroup{ + public void setVisible(boolean b){ + Enumeration e = getElements(); + while(e.hasMoreElements()) + ((AbstractButton)e.nextElement()).setVisible(b); + } + + public void triggerSelectedAction(){ + Enumeration e = getElements(); + AbstractButton b; + while(e.hasMoreElements()){ + b = ((AbstractButton)e.nextElement()); + if(b.isSelected()){ + b.doClick(); + return; + } + } + } + } + private ExtButtonGroup bgGroup; + private ExtButtonGroup bgRect; + private ExtButtonGroup bgEllipse; + private ExtButtonGroup bgBrush; + + private JPanel cornerRoundingPanel; + private JPanel linePanel; + + + /** Color Choosers */ + private JColorChooser fgColor = new JColorChooser(); + private JColorChooser bgColor = new JColorChooser(); + /** Default constructor. Must be here, used during de-externalization */ public ImageViewer () { super(); @@ -123,6 +184,9 @@ TopComponent.NodeName.connect (this, obj.getNodeDelegate ()); storedObject = obj; + + /* Add an observer */ + storedObject.addObserver(this); // force closing panes in all workspaces, default is in current only setCloseOperation(TopComponent.CLOSE_EACH); @@ -130,8 +194,12 @@ /* try to load the image: */ String errMsg = loadImage(storedObject); + /* Create any custome cursors that are going to be used */ + initialiseCustomCursors(); + /* compose the whole panel: */ JToolBar toolbar = createToolBar(); + JToolBar edittoolbar = createEditToolBar(); Component view; if (storedImage != null) { view = createImageView(); @@ -142,6 +210,7 @@ setLayout(new BorderLayout()); add(view, BorderLayout.CENTER); add(toolbar, BorderLayout.NORTH); + add(edittoolbar, BorderLayout.WEST); getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACS_ImageViewer")); @@ -157,51 +226,19 @@ obj.addPropertyChangeListener(WeakListeners.propertyChange(nameChangeL, obj)); } + /** Laods all the custom cursors */ + private void initialiseCustomCursors(){ + Toolkit tk = Toolkit.getDefaultToolkit(); + sprayCursor = tk.createCustomCursor(new ImageIcon(getClass().getResource("/org/netbeans/modules/image/sprayCursor.gif")).getImage(), new Point(0, 13), "Airbrush"); // Local + penCursor = tk.createCustomCursor(new ImageIcon(getClass().getResource("/org/netbeans/modules/image/penCursor.gif")).getImage(), new Point(1, 14), "Pencil"); // Local + fillCursor = tk.createCustomCursor(new ImageIcon(getClass().getResource("/org/netbeans/modules/image/fillCursor.gif")).getImage(), new Point(1, 12), "Paint Bucket"); // Local + brushCursor = tk.createCustomCursor(new ImageIcon(getClass().getResource("/org/netbeans/modules/image/brushCursor.gif")).getImage(), new Point(0, 14), "Brush"); // Local + } + /** */ private Component createImageView() { - panel = new JPanel() { - protected void paintComponent(Graphics g) { - super.paintComponent(g); - g.drawImage( - storedImage.getImage(), - 0, - 0, - (int)(getScale () * storedImage.getIconWidth ()), - (int)(getScale () * storedImage.getIconHeight ()), - 0, - 0, - storedImage.getIconWidth(), - storedImage.getIconHeight(), - this - ); - - if(showGrid) { - int x = (int)(getScale () * storedImage.getIconWidth ()); - int y = (int)(getScale () * storedImage.getIconHeight ()); - - double gridDistance = getScale(); - - if(gridDistance < 2) - // Disable painting of grid if no image pixels would be visible. - return; - - g.setColor(gridColor); - - double actualDistance = gridDistance; - for(int i = (int)actualDistance; i < x ;actualDistance += gridDistance, i = (int)actualDistance) { - g.drawLine(i,0,i,(y-1)); - } - - actualDistance = gridDistance; - for(int j = (int)actualDistance; j < y; actualDistance += gridDistance, j = (int)actualDistance) { - g.drawLine(0,j,(x-1),j); - } - } - - } - - }; + panel = new ImageDisplayEdit(storedImage, getScale()); storedImage.setImageObserver(panel); panel.setPreferredSize(new Dimension(storedImage.getIconWidth(), storedImage.getIconHeight() )); JScrollPane scroll = new JScrollPane(panel); @@ -344,10 +381,281 @@ toolBar.addSeparator(new Dimension(11,2)); toolBar.add(button = getGridButton()); toolbarButtons.add(button); + toolBar.addSeparator(new Dimension(11,2)); + toolBar.add(button = getConvertButton()); + toolbarButtons.add(button); return toolBar; } + //** Creates edittoolbar. */ + private JToolBar createEditToolBar() + { + bgGroup = new ExtButtonGroup(); + bgRect = new ExtButtonGroup(); + bgEllipse = new ExtButtonGroup(); + bgBrush = new ExtButtonGroup(); + + JToolBar editToolBar = new javax.swing.JToolBar(); + + editToolBar.setName (NbBundle.getBundle(ImageViewer.class).getString("ACSN_EditToolbar")); + editToolBar.setOrientation(1); + + GridBagLayout buttonLayout = new GridBagLayout(); + GridBagConstraints myConstraints = new GridBagConstraints(); + editToolBar.setLayout(buttonLayout); + + myConstraints.gridwidth = GridBagConstraints.REMAINDER; + myConstraints.fill = GridBagConstraints.BOTH; + myConstraints.weighty = 0; + + editToolBar.setFloatable (false); + + /* Add buttons to the Toolbar */ + JToggleButton newJButton = getToolButton(ImageDisplayEdit.TOOL_DEFAULT, + new Cursor(Cursor.DEFAULT_CURSOR), + "LBL_Select", + "/org/netbeans/modules/image/arrow.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + newJButton.setSelected(true); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_POLYGON, + new Cursor(Cursor.CROSSHAIR_CURSOR), + "LBL_Polygon", + "/org/netbeans/modules/image/polygon.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_PEN, + penCursor, + "LBL_Pen", + "/org/netbeans/modules/image/pen.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_BRUSH, + brushCursor, + "LBL_Brush", + "/org/netbeans/modules/image/brush.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_ERASER, + new Cursor(Cursor.CROSSHAIR_CURSOR), + "LBL_Eraser", + "/org/netbeans/modules/image/eraser.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_ARC, + new Cursor(Cursor.CROSSHAIR_CURSOR), + "LBL_Arc", + "/org/netbeans/modules/image/arc.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_LINE, + new Cursor(Cursor.CROSSHAIR_CURSOR), + "LBL_Line", + "/org/netbeans/modules/image/line.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_RECTANGLE, + new Cursor(Cursor.CROSSHAIR_CURSOR), + "LBL_Rectangle", + "/org/netbeans/modules/image/rect.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_ELLIPSE, + new Cursor(Cursor.CROSSHAIR_CURSOR), + "LBL_Ellipse", + "/org/netbeans/modules/image/oval.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_FILL, + fillCursor, + "LBL_Fill", + "/org/netbeans/modules/image/fill.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + newJButton = getToolButton(ImageDisplayEdit.TOOL_SPRAY, + sprayCursor, + "LBL_Spray", + "/org/netbeans/modules/image/spray.gif" + ); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgGroup.add(newJButton); + + bgGroup.setVisible(true); + + //editToolBar.addSeparator(new Dimension(2,4)); + + JButton foregroundButton = getForegroundButton(); + buttonLayout.setConstraints(foregroundButton, myConstraints); + editToolBar.add(foregroundButton); + + //editToolBar.addSeparator(new Dimension(2,2)); + + JButton backgroundButton = getBackgroundButton(); + buttonLayout.setConstraints(backgroundButton, myConstraints); + editToolBar.add(backgroundButton); + + //editToolBar.addSeparator(new Dimension(2,4)); + + newJButton = getBrushButton(BitmapFreehandBrush.BRUSH_BOX, "/org/netbeans/modules/image/brushSquare.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + newJButton.setSelected(true); + bgBrush.add(newJButton); + + newJButton = getBrushButton(BitmapFreehandBrush.BRUSH_CIRC, "/org/netbeans/modules/image/brushCircle.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgBrush.add(newJButton); + + newJButton = getBrushButton(BitmapFreehandBrush.BRUSH_LINE_135, "/org/netbeans/modules/image/brushLeft.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgBrush.add(newJButton); + + newJButton = getBrushButton(BitmapFreehandBrush.BRUSH_LINE_45, "/org/netbeans/modules/image/brushRight.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgBrush.add(newJButton); + + bgBrush.setVisible(false); + + + newJButton = getSubToolButton(ImageDisplayEdit.SUB_LINEONLY, "/org/netbeans/modules/image/noFillRect.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgRect.add(newJButton); + newJButton.setSelected(true); + + newJButton = getSubToolButton(ImageDisplayEdit.SUB_BOTH, "/org/netbeans/modules/image/fillRect.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgRect.add(newJButton); + + newJButton = getSubToolButton(ImageDisplayEdit.SUB_FILLONLY, "/org/netbeans/modules/image/noLineRect.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgRect.add(newJButton); + bgRect.setVisible(false); + + newJButton = getSubToolButton(ImageDisplayEdit.SUB_LINEONLY, "/org/netbeans/modules/image/noFillEllipse.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgEllipse.add(newJButton); + newJButton.setSelected(true); + + newJButton = getSubToolButton(ImageDisplayEdit.SUB_BOTH, "/org/netbeans/modules/image/fillEllipse.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgEllipse.add(newJButton); + + newJButton = getSubToolButton(ImageDisplayEdit.SUB_FILLONLY, "/org/netbeans/modules/image/noLineEllipse.gif"); + buttonLayout.setConstraints(newJButton, myConstraints); + editToolBar.add(newJButton); + bgEllipse.add(newJButton); + bgEllipse.setVisible(false); + + //editToolBar.addSeparator(new Dimension(2,2)); + + linePanel = new JPanel(){ + public void paint(Graphics g){ + super.paint(g); + changeLine(g); + } + }; + + linePanel.setLayout(new GridLayout(4,1)); + + SpinnerModel lineWidthModel = new SpinnerNumberModel(1, 1, 40, 1); + final JSpinner toolSize = new JSpinner(lineWidthModel); + + toolSize.addChangeListener(new ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + panel.setLineWidth(((Integer)(toolSize.getValue())).intValue()); + linePanel.repaint(); + } + }); + + JFormattedTextField bs = ((JSpinner.DefaultEditor)toolSize.getEditor()).getTextField(); + bs.setEditable(false); + bs.setFont(new Font("Arial Narrow", 0, 10)); + bs.setBackground(Color.white); + + linePanel.add(toolSize); + linePanel.setVisible(false); + + cornerRoundingPanel = new JPanel(){ + public void paint(Graphics g){ + super.paint(g); + drawRoundigFactor(g); + } + } + ; + cornerRoundingPanel.setLayout(new GridLayout(4,1)); + + SpinnerModel cornerRoundingModel = new SpinnerNumberModel(0, 0, 99, 3); + final JSpinner cornerRounding = new JSpinner(cornerRoundingModel); + cornerRounding.addChangeListener(new ChangeListener() { + public void stateChanged(javax.swing.event.ChangeEvent evt) { + panel.setRoundingFactor(((Integer)(cornerRounding.getValue())).intValue()); + cornerRoundingPanel.repaint(); + } + }); + + JFormattedTextField tf = ((JSpinner.DefaultEditor)cornerRounding.getEditor()).getTextField(); + tf.setEditable(false); + tf.setFont(new Font("Arial Narrow", 0, 10)); + tf.setBackground(Color.white); + + cornerRoundingPanel.add(cornerRounding); + cornerRoundingPanel.setVisible(false); + + buttonLayout.setConstraints(linePanel, myConstraints); + editToolBar.add(linePanel); + //editToolBar.addSeparator(new Dimension(2,2)); + buttonLayout.setConstraints(cornerRoundingPanel, myConstraints); + editToolBar.add(cornerRoundingPanel); + add(editToolBar); + + myConstraints.weighty = 3; + JPanel fillerPanel = new JPanel(); + buttonLayout.setConstraints(fillerPanel, myConstraints); + editToolBar.add(fillerPanel); + + return editToolBar; + } + /** Updates the name and tooltip of this top component according to associated data object. */ private void updateName () { // update name @@ -541,6 +849,7 @@ SystemAction.get(ZoomInAction.class), SystemAction.get(ZoomOutAction.class), SystemAction.get(CustomZoomAction.class), + SystemAction.get(ConvertToAction.class), null}, oldValue); } @@ -609,6 +918,7 @@ resizePanel(); panel.repaint(0, 0, panel.getWidth(), panel.getHeight()); + panel.setScale(scale); } /** Return zooming factor.*/ @@ -619,6 +929,7 @@ /** Change proportion "out"*/ private void scaleOut() { scale = scale / changeFactor; + panel.setScale(scale); } /** Change proportion "in"*/ @@ -632,6 +943,21 @@ if (newComputedScale == oldComputedScale) // Has to increase. scale = newComputedScale + 1.0D; + + panel.setScale(scale); + } + + public void convertTo() { + try { + storedObject.convertTo(this); + } catch(IOException e) { + JOptionPane.showMessageDialog(null, NbBundle.getMessage(ImageViewer.class, "MSG_CouldNotConvert"), NbBundle.getMessage(ImageViewer.class, "LBL_CouldNotConvert"), JOptionPane.ERROR_MESSAGE); + } + } + + public void update(Observable o, Object arg){ + updateView(storedObject); + panel.reload(storedImage); } /** Gets zoom button. */ @@ -676,12 +1002,215 @@ button.setMnemonic(NbBundle.getBundle(ImageViewer.class).getString("ACS_Grid_BTN_Mnem").charAt(0)); button.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent evt) { - showGrid = !showGrid; + panel.toggleGrid(); panel.repaint(0, 0, panel.getWidth(), panel.getHeight()); } }); return button; + } + + private JButton getConvertButton() { + // PENDING buttons should have their own icons. + JButton button = new JButton(NbBundle.getMessage(CustomZoomAction.class, "LBL_ConvertTo")); + button.getAccessibleContext().setAccessibleDescription(NbBundle.getBundle(ImageViewer.class).getString("ACS_Convert_BTN")); + button.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + ConvertToAction sa = (ConvertToAction) SystemAction.get(ConvertToAction.class); + sa.performAction(); + } + }); + + return button; + } + + /** Gets the standard tool button **/ + private JToggleButton getToolButton(final int toolType, final Cursor cursorType, String toolTipText, String iconResourcePath){ + JToggleButton toolButton = new JToggleButton(); + toolButton.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString(toolTipText)); + toolButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(iconResourcePath))); + + toolButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt){ + panel.setToolType(toolType); + panel.setCustomCursor(cursorType); + setSubtoolsVisible(); + } + }); + + return toolButton; + } + + /** Gets foreground button.*/ + private JButton getForegroundButton(){ + final JButton foregroundButton = new JButton(" "); + foregroundButton.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_SetLineColor")); + foregroundButton.setBackground(panel.getDefaultPrimaryColor()); + foregroundButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent evt) + { + Color newColor = fgColor.showDialog(null,"Choose Foreground Color", foregroundButton.getForeground()); + foregroundButton.setBackground(newColor); + + panel.setPrimaryColor(newColor); + } + }); + + return foregroundButton; + } + + /** Gets background button.*/ + private JButton getBackgroundButton(){ + final JButton backgroundButton = new JButton(" "); + backgroundButton.setBackground(panel.getDefaultSecondaryColor()); + backgroundButton.setToolTipText (NbBundle.getBundle(ImageViewer.class).getString("LBL_SetFillColor")); + backgroundButton.addActionListener(new ActionListener() + { + public void actionPerformed(ActionEvent evt) + { + Color newColor = bgColor.showDialog(null,"Choose Background Color", backgroundButton.getBackground()); + backgroundButton.setBackground(newColor); + + panel.setSecondayColor(newColor); + } + }); + + return backgroundButton; + } + + /** Get subtool buttons */ + private JToggleButton getSubToolButton(final int subTool, String resourcePath){ + JToggleButton newButton = new JToggleButton(); + newButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(resourcePath))); + + newButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + panel.setSubTool(subTool); + } + }); + return newButton; + } + + /** Get brushShape buttons */ + private JToggleButton getBrushButton(final int brushShape, String resourcePath){ + JToggleButton newButton = new JToggleButton(); + newButton.setIcon(new javax.swing.ImageIcon(getClass().getResource(resourcePath))); + + newButton.addActionListener(new ActionListener() { + public void actionPerformed(ActionEvent evt) { + panel.setBrushType(brushShape); + linePanel.repaint(); + } + }); + return newButton; + } + + /** changes the line width display */ + private void changeLine(Graphics g) { + Graphics2D g2D = (Graphics2D)g; + + g2D.setColor(Color.WHITE); + g2D.fillRect(0, 20, 32, 40); + g2D.setClip(0, 20, 32, 40); + + /* Line Displaye for Spay can */ + if (panel.getToolType() == ImageDisplayEdit.TOOL_SPRAY){ + g2D.setColor(Color.BLACK); + Ellipse2D testEllipse = new Ellipse2D.Float(10 - (panel.getLineWidth() / 2), 34 - (panel.getLineWidth() / 2), (float)panel.getLineWidth() + 10, (float)panel.getLineWidth() + 10); + g2D.draw(testEllipse); + /* Brush Shape displays */ + }else if(panel.getToolType() == ImageDisplayEdit.TOOL_BRUSH){ + g2D.setColor(Color.BLACK); + BasicStroke b = new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND); + Shape brushShape; + switch(panel.getBrushType()){ + case BitmapFreehandBrush.BRUSH_BOX: + brushShape = new Rectangle(15 - (panel.getLineWidth() / 2), 38 - (panel.getLineWidth() / 2), panel.getLineWidth() + 1, panel.getLineWidth() + 1); + g2D.fill(brushShape); + break; + case BitmapFreehandBrush.BRUSH_CIRC: + brushShape = new Ellipse2D.Float(15 - (panel.getLineWidth() / 2), 38 - (panel.getLineWidth() / 2), (float)panel.getLineWidth() + 1, (float)panel.getLineWidth() + 1); + g2D.fill(brushShape); + break; + case BitmapFreehandBrush.BRUSH_LINE_135: + brushShape = b.createStrokedShape(new Line2D.Float((float)(15 - panel.getLineWidth()/2), (float)(38 - panel.getLineWidth()/2), (float)(15 + panel.getLineWidth()/2), (float)(38 + panel.getLineWidth()/2))); + g2D.draw(brushShape); + g2D.fill(brushShape); + break; + case BitmapFreehandBrush.BRUSH_LINE_45: + brushShape = b.createStrokedShape(new Line2D.Float((float)(15 + panel.getLineWidth()/2), (float)(38 - panel.getLineWidth()/2), (float)(15 - panel.getLineWidth()/2), (float)(38 + panel.getLineWidth()/2))); + g2D.draw(brushShape); + g2D.fill(brushShape); + break; + } + } + /* Anything else (line, box, ellipse, polygon) */ + else{ + g2D.setColor(Color.BLACK); + Line2D testLine = new Line2D.Float(new Point(0, 40), new Point(32, 40)); + g2D.setStroke(new BasicStroke(panel.getLineWidth())); + g2D.draw(testLine); + } } + private void drawRoundigFactor(Graphics g){ + Graphics2D g2D = (Graphics2D)g; + + g2D.setColor(Color.WHITE); + g2D.fillRect(0, 20, 32, 30); + g2D.setClip(0, 20, 32, 30); + + g2D.setColor(Color.BLACK); + Shape r; + + if(panel.getRoundingFactor() == 0) + r = new Rectangle(5, 25, 100, 100); + else + r = new RoundRectangle2D.Float(5, 25, 100, 100, panel.getRoundingFactor(), panel.getRoundingFactor()); + + g2D.draw(r); + } + + /** set the lines widths visible */ + private void setSubtoolsVisible(){ + if (panel.getToolType() == ImageDisplayEdit.TOOL_RECTANGLE){ + bgRect.setVisible(true); + bgRect.triggerSelectedAction(); + cornerRoundingPanel.setVisible(true); + cornerRoundingPanel.repaint(); + }else{ + bgRect.setVisible(false); + cornerRoundingPanel.setVisible(false); + } + + if (panel.getToolType() == ImageDisplayEdit.TOOL_ELLIPSE){ + bgEllipse.setVisible(true); + bgEllipse.triggerSelectedAction(); + } + else + bgEllipse.setVisible(false); + + if (panel.getToolType() == ImageDisplayEdit.TOOL_BRUSH) + bgBrush.setVisible(true); + else + bgBrush.setVisible(false); + + switch (panel.getToolType()){ + case ImageDisplayEdit.TOOL_POLYGON: + case ImageDisplayEdit.TOOL_BRUSH: + case ImageDisplayEdit.TOOL_ARC: + case ImageDisplayEdit.TOOL_LINE: + case ImageDisplayEdit.TOOL_RECTANGLE: + case ImageDisplayEdit.TOOL_ELLIPSE: + case ImageDisplayEdit.TOOL_ERASER: + case ImageDisplayEdit.TOOL_SPRAY: + linePanel.setVisible(true); + linePanel.repaint(); + break; + default: + linePanel.setVisible(false); + break; + } + } } Index: image/src/org/netbeans/modules/image/ImageWizardPanel.java =================================================================== RCS file: image/src/org/netbeans/modules/image/ImageWizardPanel.java diff -N image/src/org/netbeans/modules/image/ImageWizardPanel.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/ImageWizardPanel.java 5 Jul 2005 11:25:07 -0000 @@ -0,0 +1,365 @@ +package org.netbeans.modules.image; + +import java.awt.BorderLayout; +import java.awt.Color; +import java.awt.Component; +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.io.File; +import java.util.HashSet; +import java.util.Iterator; +import java.util.Set; +import javax.imageio.ImageIO; +import javax.swing.DefaultComboBoxModel; +import javax.swing.JButton; +import javax.swing.JColorChooser; +import javax.swing.JComboBox; +import javax.swing.JFileChooser; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JTextField; +import javax.swing.border.LineBorder; +import javax.swing.event.ChangeEvent; +import javax.swing.event.ChangeListener; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import org.openide.WizardDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; +import org.openide.util.HelpCtx; +import org.openide.util.NbBundle; + +/** + * JPanel used by the NewImageFileWizardIterator + * + * @author Jason Solomon + */ +final public class ImageWizardPanel extends JPanel implements WizardDescriptor.FinishablePanel, DocumentListener { + + private transient Set listeners = new HashSet(1); + + private Color bgColor = Color.white; + + // Swing Components + private JButton btnBrowse; + private JButton btnBackground; + private JColorChooser chBackground; + private JComboBox cmbExt; + private JFileChooser chFolder; + private JLabel lblFileName; + private JLabel lblExt; + private JLabel lblFolder; + private JLabel lblWidth; + private JLabel lblHeight; + private JPanel pnlTop; + private JPanel pnlMid; + private JPanel pnlBottom; + private JPanel pnlBackground; + private JTextField jtfFileName; + private JTextField jtfFolder; + private JTextField jtfWidth; + private JTextField jtfHeight; + + public ImageWizardPanel() { + setName(NbBundle.getMessage(ImageWizardPanel.class, "LBL_ImageProperties")); + initComponents(); + } + + public Component getComponent() { + return this; + } + + public boolean isFinishPanel() { + return true; + } + + public boolean isValid() { + try { + if(jtfFileName.getText().equals("")) + return false; + + File tempFile = new File(jtfFolder.getText()); + if (!tempFile.isDirectory()) + return false; + + int testWidth = Integer.parseInt(jtfWidth.getText()); + int testHeight = Integer.parseInt(jtfHeight.getText()); + if(testWidth <= 0 || testHeight <= 0) + return false; + + return true; + } catch(IllegalArgumentException e) { + return false; + } + } + + public HelpCtx getHelp() { + return null; + } + + public void addChangeListener(ChangeListener l) { + synchronized(listeners) { + listeners.add(l); + } + } + + public void removeChangeListener(ChangeListener l) { + synchronized(listeners) { + listeners.remove(l); + } + } + + public void storeSettings(Object settings) { + } + + public void readSettings(Object settings) { + } + + public String getFileName() { + return jtfFileName.getText(); + } + + public String getExt() { + return (String)cmbExt.getSelectedItem(); + } + + public File getFolder() { + return new File(jtfFolder.getText()); + } + + public int getImageWidth() { + return Integer.parseInt(jtfWidth.getText()); + } + + public int getImageHeight() { + return Integer.parseInt(jtfHeight.getText()); + } + + public Color getBackground() { + return bgColor; + } + + private void initComponents() { + GridBagConstraints gridBagConstraints; + + String tempWriterTypes[] = ImageIO.getWriterFormatNames(); + String writerTypes[] = new String[tempWriterTypes.length]; + + for(int i = 0; i < writerTypes.length; i++) + writerTypes[i] = new String(""); + + int z = 0; + boolean found = false; + for(int x = 0; x < tempWriterTypes.length; x++) { + if(x == 0) { + writerTypes[z] = tempWriterTypes[x].toLowerCase(); + z++; + } + else { + for(int y = 0; y < writerTypes.length; y++) { + if(writerTypes[y].equals(tempWriterTypes[x].toLowerCase())) + found = true; + } + if(!found) { + writerTypes[z] = tempWriterTypes[x].toLowerCase(); + z++; + } + } + } + + chBackground = new JColorChooser(); + + chFolder = new JFileChooser(); + chFolder.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); + chFolder.setDialogTitle(NbBundle.getMessage(ImageWizardPanel.class, "LBL_FolderChooser")); + + DefaultComboBoxModel cmbModel = new DefaultComboBoxModel(); + + int j = 0; + while(!writerTypes[j].equals("")) { + cmbModel.addElement(writerTypes[j]); + j++; + } + + pnlTop = new JPanel(); + lblFileName = new JLabel(); + jtfFileName = new JTextField(); + lblExt = new JLabel(); + cmbExt = new JComboBox(cmbModel); + lblFolder = new JLabel(); + jtfFolder = new JTextField(); + btnBrowse = new JButton(); + pnlMid = new JPanel(); + lblWidth = new JLabel(); + jtfWidth = new JTextField(); + lblHeight = new JLabel(); + jtfHeight = new JTextField(); + pnlBottom = new JPanel(); + btnBackground = new JButton(); + pnlBackground = new JPanel(); + + jtfFileName.getDocument().addDocumentListener(this); + jtfFolder.getDocument().addDocumentListener(this); + jtfWidth.getDocument().addDocumentListener(this); + jtfHeight.getDocument().addDocumentListener(this); + + btnBackground.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + Color newBGColor = chBackground.showDialog(null, NbBundle.getMessage(ImageWizardPanel.class, "LBL_ColorChooser"), Color.white); + if(newBGColor != null) { + bgColor = newBGColor; + } + pnlBackground.setBackground(bgColor); + } + } + ); + + btnBrowse.addActionListener( + new ActionListener() { + public void actionPerformed(ActionEvent e) { + if(chFolder.showDialog(null, NbBundle.getMessage(ImageWizardPanel.class, "LBL_FolderChooserBtn")) == JFileChooser.APPROVE_OPTION) { + File tempFolder = chFolder.getSelectedFile(); + jtfFolder.setText(tempFolder.getPath()); + } + } + } + ); + + setLayout(new BorderLayout()); + + pnlTop.setLayout(new GridBagLayout()); + + lblFileName.setText(NbBundle.getMessage(ImageWizardPanel.class, "LBL_FileName")); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.anchor = GridBagConstraints.WEST; + gridBagConstraints.insets = new Insets(30, 12, 0, 0); + pnlTop.add(lblFileName, gridBagConstraints); + + jtfFileName.setText("newImage"); + jtfFileName.setPreferredSize(new Dimension(200, 23)); + jtfFileName.setMinimumSize(new Dimension(200, 23)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 1.0; + gridBagConstraints.insets = new Insets(29, 11, 0, 11); + pnlTop.add(jtfFileName, gridBagConstraints); + + lblExt.setText(NbBundle.getMessage(ImageWizardPanel.class, "LBL_Ext")); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(30, 12, 0, 0); + pnlTop.add(lblExt, gridBagConstraints); + + cmbExt.setPreferredSize(new Dimension(60, 22)); + cmbExt.setMinimumSize(new Dimension(60, 22)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(29, 11, 0, 11); + pnlTop.add(cmbExt, gridBagConstraints); + + lblFolder.setText(NbBundle.getMessage(ImageWizardPanel.class, "LBL_Folder")); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 0; + gridBagConstraints.gridy = 1; + gridBagConstraints.anchor = GridBagConstraints.WEST; + gridBagConstraints.insets = new Insets(12, 12, 0, 0); + pnlTop.add(lblFolder, gridBagConstraints); + + jtfFolder.setPreferredSize(new Dimension(250, 23)); + jtfFolder.setMinimumSize(new Dimension(250, 23)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 1; + gridBagConstraints.gridy = 1; + gridBagConstraints.gridwidth = 2; + gridBagConstraints.fill = GridBagConstraints.HORIZONTAL; + gridBagConstraints.weightx = 2.0; + gridBagConstraints.insets = new Insets(12, 11, 0, 11); + pnlTop.add(jtfFolder, gridBagConstraints); + + btnBrowse.setText(NbBundle.getMessage(ImageWizardPanel.class, "LBL_BrowseBtn")); + btnBrowse.setPreferredSize(new Dimension(75, 27)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.gridx = 3; + gridBagConstraints.gridy = 1; + gridBagConstraints.insets = new Insets(12, 11, 0, 11); + pnlTop.add(btnBrowse, gridBagConstraints); + + add(pnlTop, BorderLayout.NORTH); + + pnlMid.setLayout(new GridBagLayout()); + + lblWidth.setText(NbBundle.getMessage(ImageWizardPanel.class, "LBL_Width")); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.anchor = GridBagConstraints.WEST; + gridBagConstraints.insets = new Insets(20, 100, 0, 0); + pnlMid.add(lblWidth, gridBagConstraints); + + jtfWidth.setText("200"); + jtfWidth.setPreferredSize(new Dimension(60, 23)); + jtfWidth.setMinimumSize(new Dimension(60, 23)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(19, 11, 0, 11); + pnlMid.add(jtfWidth, gridBagConstraints); + + lblHeight.setText(NbBundle.getMessage(ImageWizardPanel.class, "LBL_Height")); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(20, 12, 0, 0); + pnlMid.add(lblHeight, gridBagConstraints); + + jtfHeight.setText("200"); + jtfHeight.setPreferredSize(new Dimension(60, 23)); + jtfHeight.setMinimumSize(new Dimension(60, 23)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(19, 11, 0, 100); + pnlMid.add(jtfHeight, gridBagConstraints); + + add(pnlMid, BorderLayout.CENTER); + + pnlBottom.setLayout(new GridBagLayout()); + + btnBackground.setText(NbBundle.getMessage(ImageWizardPanel.class, "LBL_BackgroundBtn")); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(30, 11, 30, 11); + pnlBottom.add(btnBackground, gridBagConstraints); + + pnlBackground.setLayout(null); + + pnlBackground.setBackground(Color.white); + pnlBackground.setBorder(new LineBorder(Color.black)); + pnlBackground.setPreferredSize(new Dimension(40, 40)); + gridBagConstraints = new GridBagConstraints(); + gridBagConstraints.insets = new Insets(0, 0, 2, 0); + pnlBottom.add(pnlBackground, gridBagConstraints); + + add(pnlBottom, BorderLayout.SOUTH); + } + + public void insertUpdate(DocumentEvent e) { + ChangeEvent ce = new ChangeEvent(this); + Iterator it = listeners.iterator(); + while (it.hasNext()) { + ((ChangeListener)it.next()).stateChanged(ce); + } + } + + public void removeUpdate(DocumentEvent e) { + ChangeEvent ce = new ChangeEvent(this); + Iterator it = listeners.iterator(); + while (it.hasNext()) { + ((ChangeListener)it.next()).stateChanged(ce); + } + } + + public void changedUpdate(DocumentEvent e) { + ChangeEvent ce = new ChangeEvent(this); + Iterator it = listeners.iterator(); + while (it.hasNext()) { + ((ChangeListener)it.next()).stateChanged(ce); + } + } + +} Index: image/src/org/netbeans/modules/image/Layer.xml =================================================================== RCS file: /cvs/image/src/org/netbeans/modules/image/Layer.xml,v retrieving revision 1.6 diff -u -r1.6 Layer.xml --- image/src/org/netbeans/modules/image/Layer.xml 29 Oct 2004 16:11:08 -0000 1.6 +++ image/src/org/netbeans/modules/image/Layer.xml 5 Jul 2005 11:25:07 -0000 @@ -19,15 +19,30 @@ - + + - + + + + + + + + + + + + + + + Index: image/src/org/netbeans/modules/image/NBImageIcon.java =================================================================== RCS file: /cvs/image/src/org/netbeans/modules/image/NBImageIcon.java,v retrieving revision 1.16 diff -u -r1.16 NBImageIcon.java --- image/src/org/netbeans/modules/image/NBImageIcon.java 26 Jan 2005 14:04:12 -0000 1.16 +++ image/src/org/netbeans/modules/image/NBImageIcon.java 5 Jul 2005 11:25:08 -0000 @@ -24,7 +24,7 @@ /** * ImageIcon with serialization. * - * @author Petr Hamernik, Michael Wever + * @author Petr Hamernik, Michael Wever, Jason Solomon * @author Marian Petras */ class NBImageIcon extends ImageIcon implements Serializable { @@ -96,4 +96,9 @@ (image != null) ? image : new ImageIcon().getImage()); } } // End of nested class ResolvableHelper. + + protected ImageDataObject getIDO() { + return obj; + } + } Index: image/src/org/netbeans/modules/image/NewImageFileWizardIterator.java =================================================================== RCS file: image/src/org/netbeans/modules/image/NewImageFileWizardIterator.java diff -N image/src/org/netbeans/modules/image/NewImageFileWizardIterator.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/NewImageFileWizardIterator.java 5 Jul 2005 11:25:09 -0000 @@ -0,0 +1,156 @@ +package org.netbeans.modules.image; + +import java.awt.Component; +import java.awt.Color; +import java.awt.Graphics; +import java.awt.image.BufferedImage; +import java.awt.image.RenderedImage; +import java.io.File; +import java.io.IOException; +import java.util.Collections; +import java.util.HashSet; +import java.util.Iterator; +import java.util.NoSuchElementException; +import java.util.Set; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriter; +import javax.imageio.stream.FileImageOutputStream; +import javax.swing.JComponent; +import javax.swing.event.ChangeListener; + +import org.openide.WizardDescriptor; +import org.openide.filesystems.FileObject; +import org.openide.filesystems.FileUtil; + +/** + * Wizard to create a new Image file. + * + * @author Jason Solomon + */ +public class NewImageFileWizardIterator implements WizardDescriptor.InstantiatingIterator { + + private transient WizardDescriptor wizard; + + private transient WizardDescriptor.Panel[] panels; + + private transient int index; + + private transient Set listeners = new HashSet(1); + + /** Create a new wizard iterator. */ + public NewImageFileWizardIterator() { + } + + public void initialize(WizardDescriptor wizard) { + this.wizard = wizard; + index = 0; + + panels = new ImageWizardPanel[1]; + panels[0] = new ImageWizardPanel(); + + // Make sure list of steps is accurate. + String[] beforeSteps = null; + Object prop = wizard.getProperty ("WizardPanel_contentData"); + if (prop != null && prop instanceof String[]) { + beforeSteps = (String[])prop; + } + + assert panels != null; + + int diff = 0; + if (beforeSteps == null) { + beforeSteps = new String[0]; + } else if (beforeSteps.length > 0) { + diff = ("...".equals(beforeSteps[beforeSteps.length - 1])) ? 1 : 0; + } + String[] steps = new String[(beforeSteps.length - diff) + panels.length]; + for (int i = 0; i < steps.length; i++) { + if (i < (beforeSteps.length - diff)) { + steps[i] = beforeSteps[i]; + } else { + steps[i] = panels[i - beforeSteps.length + diff].getComponent().getName(); + } + } + for (int i = 0; i < panels.length; i++) { + Component c = panels[i].getComponent(); + if (steps[i] == null) { + steps[i] = c.getName(); + } + if (c instanceof JComponent) { + JComponent jc = (JComponent)c; + jc.putClientProperty("WizardPanel_contentSelectedIndex", new Integer(i)); + jc.putClientProperty("WizardPanel_contentData", steps); + } + } + } + + public Set instantiate() throws IOException { + String fileName = ((ImageWizardPanel)(panels[index])).getFileName(); + String ext = ((ImageWizardPanel)(panels[index])).getExt(); + File folder = ((ImageWizardPanel)(panels[index])).getFolder(); + int width = ((ImageWizardPanel)(panels[index])).getImageWidth(); + int height = ((ImageWizardPanel)(panels[index])).getImageHeight(); + Color bgColor = ((ImageWizardPanel)(panels[index])).getBackground(); + + File newFile = new File(folder, fileName + "." + ext); + BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); + Graphics g = newImage.getGraphics(); + g.setColor(bgColor); + g.fillRect(0, 0, width, height); + Iterator writers = ImageIO.getImageWritersByFormatName(ext); + ImageWriter writer = (ImageWriter)writers.next(); + FileImageOutputStream output = new FileImageOutputStream(newFile); + writer.setOutput(output); + writer.write((RenderedImage)newImage); + FileObject pf = FileUtil.toFileObject(newFile); + + return Collections.singleton(pf); + } + + public void uninitialize(WizardDescriptor wizard) { + this.wizard = null; + } + + public String name() { + return ""; + } + + public final void addChangeListener(ChangeListener l) { + synchronized(listeners) { + listeners.add(l); + } + } + + public final void removeChangeListener(ChangeListener l) { + synchronized(listeners) { + listeners.remove(l); + } + } + + public boolean hasNext() { + return index < panels.length - 1; + } + + public boolean hasPrevious() { + return index > 0; + } + + public void nextPanel() { + if (!hasNext()) throw new NoSuchElementException(); + index++; + } + + public void previousPanel() { + if (!hasPrevious()) throw new NoSuchElementException(); + index--; + } + + public WizardDescriptor.Panel current() { + return panels[index]; + } + + public static WizardDescriptor.InstantiatingIterator createImageTemplateIterator() { + return new NewImageFileWizardIterator (); + } + +} Index: image/src/org/netbeans/modules/image/ObservableImage.java =================================================================== RCS file: image/src/org/netbeans/modules/image/ObservableImage.java diff -N image/src/org/netbeans/modules/image/ObservableImage.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/ObservableImage.java 5 Jul 2005 11:25:09 -0000 @@ -0,0 +1,14 @@ +package org.netbeans.modules.image; + +import java.util.Observable; + +/** + * Allows a public call to the setChanged() method of Observable + * + * @author Jason Solomon + */ +public class ObservableImage extends Observable { + public void setChanged() { + super.setChanged(); + } +} Index: image/src/org/netbeans/modules/image/VectorArc.java =================================================================== RCS file: image/src/org/netbeans/modules/image/VectorArc.java diff -N image/src/org/netbeans/modules/image/VectorArc.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/VectorArc.java 5 Jul 2005 11:25:10 -0000 @@ -0,0 +1,54 @@ +package org.netbeans.modules.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.BasicStroke; +import java.awt.Point; +import java.awt.Dimension; +import java.awt.Shape; +import java.awt.Rectangle; +import java.awt.geom.Arc2D; +import java.lang.Math; + +/** + * Implimentation of the Vector Arc tool. Draws a + * 90 degree line joining both points + * + * @author Timothy Boyce + */ +class VectorArc extends VectorTool{ + + /** Simply use the supercalss default constructor */ + public VectorArc(int xVal, int yVal, Color c, int w){ + super(xVal, yVal, c, w); + } + + /** Draw an arc on the graphics context + between the start and end clicks */ + public void writeToGraphic(Graphics2D g){ + g.setStroke(new BasicStroke(getLineWidth())); + g.setPaintMode(); + g.setColor(getLineColor()); + + Arc2D.Float thisArc = new Arc2D.Float(); + + /* Calculate the bounding rectangle */ + double top, left, direction; + top = (getStart().getY() < getEnd().getY()) ? getTopLeft().getY() - getDimension().getHeight() : getTopLeft().getY(); + left = (getStart().getX() > getEnd().getX()) ? getTopLeft().getX() - getDimension().getWidth() : getTopLeft().getX(); + direction = (getStart().getX() - getEnd().getX()) * (getStart().getY() - getEnd().getY()); + direction = -(Math.abs(direction) / direction); + + Point topLeft = new Point((int)left, (int)top); + Dimension rectDim = new Dimension((int)(2 * getDimension().getWidth()),(int)(2 * getDimension().getHeight())); + + /* Sets the arcs bounds */ + thisArc.setFrame(new Rectangle(topLeft, rectDim)); + + /* Set the angle extent and start */ + thisArc.setAngleStart((getEnd().getY() < getStart().getY()) ? 90 : 270); + thisArc.setAngleExtent(direction * 90); + + g.draw(thisArc); + } +} Index: image/src/org/netbeans/modules/image/VectorEllipse.java =================================================================== RCS file: image/src/org/netbeans/modules/image/VectorEllipse.java diff -N image/src/org/netbeans/modules/image/VectorEllipse.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/VectorEllipse.java 5 Jul 2005 11:25:10 -0000 @@ -0,0 +1,44 @@ +package org.netbeans.modules.image; + +import java.awt.Graphics2D; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.Shape; +import java.awt.geom.Ellipse2D; + +/** + * Implimentation of the Ellipse Edit Tool + * + * @author Timothy Boyce + */ +class VectorEllipse extends VectorTool{ + /** The fill color of the Ellipse */ + private Color fillColor; + + /** Constructor for a line ellipse */ + public VectorEllipse(int xVal, int yVal, Color c, int w){ + super(xVal, yVal, c, w); + fillColor = null; + } + + /** Constructor for a filled ellipse */ + public VectorEllipse(int xVal, int yVal, Color line, Color fill, int w){ + super(xVal, yVal, line, w); + fillColor = fill; + } + + public void writeToGraphic(Graphics2D g){ + g.setStroke(new BasicStroke(getLineWidth())); + g.setPaintMode(); + + Ellipse2D.Float thisEllipse = new Ellipse2D.Float((float)getTopLeft().getX(), (float)getTopLeft().getY(), (float)getDimension().getWidth(), (float)getDimension().getHeight()); + + if(fillColor != null){ + g.setColor(fillColor); + g.fill(thisEllipse); + } + + g.setColor(getLineColor()); + g.draw(thisEllipse); + } +} Index: image/src/org/netbeans/modules/image/VectorLine.java =================================================================== RCS file: image/src/org/netbeans/modules/image/VectorLine.java diff -N image/src/org/netbeans/modules/image/VectorLine.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/VectorLine.java 5 Jul 2005 11:25:10 -0000 @@ -0,0 +1,27 @@ +package org.netbeans.modules.image; + +import java.awt.Graphics2D; +import java.awt.BasicStroke; +import java.awt.geom.Line2D; +import java.awt.Color; + +/** Implimentation of the Line tool. + * + * @author Timothy Boyce + */ +class VectorLine extends VectorTool{ + + /** Use the superclass constructor */ + public VectorLine(int xVal, int yVal, Color c, int w){ + super(xVal, yVal, c, w); + } + + /** Draw a line between the start and end points, + to the specified graphics object */ + public void writeToGraphic(Graphics2D g){ + g.setStroke(new BasicStroke(getLineWidth())); + g.setPaintMode(); + g.setColor(getLineColor()); + g.draw(new Line2D.Float(getStart(), getEnd())); + } +} Index: image/src/org/netbeans/modules/image/VectorPolygon.java =================================================================== RCS file: image/src/org/netbeans/modules/image/VectorPolygon.java diff -N image/src/org/netbeans/modules/image/VectorPolygon.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/VectorPolygon.java 5 Jul 2005 11:25:11 -0000 @@ -0,0 +1,133 @@ +package org.netbeans.modules.image; + +import java.awt.Graphics2D; +import java.awt.BasicStroke; +import java.awt.Point; +import java.awt.Color; +import java.awt.geom.GeneralPath; +import java.util.Vector; + +/** + * Implimentation of the Polygon Edit Tool + * + * @author Timothy Boyce + */ +class VectorPolygon implements EditTool{ + + /** The start point of the polygon */ + protected Point startPoint; + + /** The end point of the polygon */ + protected Point lastPoint; + + /** Vector containing the last 3 polygon points */ + protected Vector polygonSegPoints = new Vector(){ + public void addElement(Object obj){ + if(this.size() >= 3) + this.removeElementAt(0); + super.addElement(obj); + } + }; + + /** General path used for drawing polygon segments */ + protected GeneralPath polygonSegPath; + + /** The line color */ + protected Color lineColor; + + /** The width of the line */ + protected float lineWidth; + + /** The status of the tool, true = complete, false = incomplete */ + protected boolean toolStatus = false; + + /** The type of the polgon, points only, or freehand and points */ + protected boolean polyType; + + /** Static polygon type varibles used in the constructor */ + public static final boolean FREEHAND_POLY = true; + public static final boolean POINT_POLY = false; + + /** Constructor, set the start point of the polygon, and other various + variables. */ + public VectorPolygon(int xVal, int yVal, Color c, int w, boolean f){ + startPoint = new Point(xVal, yVal); + polygonSegPoints.addElement(startPoint); + lastPoint = new Point(-1, -1); + lineColor = c; + lineWidth = (float)w; + polyType = false; + } + + public boolean getToolStatus(){ + return toolStatus; + } + + public boolean getMemoryless(){ + return true; + } + + /** When the image display editor invokes the setDragPoint + command, only set a new polygone point if the user has selected a + freehand polygon type */ + public void setDragPoint(int xVal, int yVal){ + if(polyType == VectorPolygon.FREEHAND_POLY){ + polygonSegPoints.addElement(new Point(xVal, yVal)); + lastPoint.setLocation(xVal, yVal); + } + } + + public void setClickPoint(int xVal, int yVal){ + lastPoint.setLocation(xVal, yVal); + polygonSegPoints.addElement(new Point(xVal, yVal)); + } + + public void setReleasePoint(int xVal, int yVal){ + /** Finish the polygon if the user clicks in the same spot twice */ + if((xVal == lastPoint.x) && (yVal == lastPoint.y)){ + toolStatus = true; + } + + lastPoint.setLocation(xVal, yVal); + polygonSegPoints.addElement(new Point(xVal, yVal)); + } + + + /** Write the last 2 polgon segments to the graphics context: + Since this is a non-memoryless tool, all preceding points will + still be held in the buffer. Only the last 2 segments need to + be drawn in order to get the new line, and the proper segment + joining at the newly created corner. */ + public void writeToGraphic(Graphics2D g){ + Point p1, p2, p3; + + g.setStroke(new BasicStroke(lineWidth, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)); + g.setPaintMode(); + g.setColor(lineColor); + + polygonSegPath = new GeneralPath(); + + p1 = (Point)polygonSegPoints.firstElement(); + polygonSegPath.moveTo(p1.x, p1.y); + + if(polygonSegPoints.size() == 3) + p2 = (Point)polygonSegPoints.get(1); + else + p2 = (Point)polygonSegPoints.lastElement(); + + polygonSegPath.lineTo(p2.x, p2.y); + + if(polygonSegPoints.size() == 2) + p3 = (Point)polygonSegPoints.firstElement(); + else + p3 = (Point)polygonSegPoints.lastElement(); + + polygonSegPath.lineTo(p3.x, p3.y); + + if(getToolStatus()){ + polygonSegPath.lineTo(startPoint.x, startPoint.y); + } + + g.draw(polygonSegPath); + } +} Index: image/src/org/netbeans/modules/image/VectorRectangle.java =================================================================== RCS file: image/src/org/netbeans/modules/image/VectorRectangle.java diff -N image/src/org/netbeans/modules/image/VectorRectangle.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/VectorRectangle.java 5 Jul 2005 11:25:12 -0000 @@ -0,0 +1,86 @@ +package org.netbeans.modules.image; + +import java.awt.Graphics2D; +import java.awt.Shape; +import java.awt.Rectangle; +import java.awt.BasicStroke; +import java.awt.Color; +import java.awt.GradientPaint; + +import java.awt.geom.RoundRectangle2D; + +/** + * VectorRectangle + * + * @author Timothy Boyce + */ +class VectorRectangle extends VectorTool{ + private Color fillColor; + private float roundingFactor; + + public VectorRectangle(int xVal, int yVal, Color c, int w){ + super(xVal, yVal, c, w); + + /* Set the fill colour to null, + and corner rounding to 0 */ + fillColor = null; + roundingFactor = 0; + } + + public VectorRectangle(int xVal, int yVal, Color c, int w, float r){ + super(xVal, yVal, c, w); + + /* Set the fill to null */ + fillColor = null; + + /* Set CornerRounding */ + roundingFactor = r; + } + + public VectorRectangle(int xVal, int yVal, Color line, Color fill, int w){ + super(xVal, yVal, line, w); + + /* Set the fill colour to null */ + fillColor = fill; + roundingFactor = 0; + } + + public VectorRectangle(int xVal, int yVal, Color line, Color fill, int w, float r){ + super(xVal, yVal, line, w); + + /* Set the fill colour to null */ + fillColor = fill; + roundingFactor = r; + } + + /* Returns null if there is no fill, the + color if the tool is complete, or the XOR + mode color if the tool is not yet complete */ + protected Color getFillColor(){ + return fillColor; + } + + public void writeToGraphic(Graphics2D g){ + g.setStroke(new BasicStroke(getLineWidth(), BasicStroke.CAP_SQUARE, BasicStroke.JOIN_MITER)); + g.setPaintMode(); + + Shape thisRectangle; + + if(roundingFactor == 0) + thisRectangle = new Rectangle(getTopLeft(), getDimension()); + else + thisRectangle = new RoundRectangle2D.Float((float)getTopLeft().getX(), (float)getTopLeft().getY(), (float)getDimension().getWidth(), (float)getDimension().getHeight(), roundingFactor, roundingFactor); + + /* Fill it if the user chose a filled variation */ + if(fillColor != null){ + g.setColor(getFillColor()); + g.fill(thisRectangle); + } + + /* Paint the line */ + g.setColor(getLineColor()); + g.draw(thisRectangle); + + } + +} Index: image/src/org/netbeans/modules/image/VectorTool.java =================================================================== RCS file: image/src/org/netbeans/modules/image/VectorTool.java diff -N image/src/org/netbeans/modules/image/VectorTool.java --- /dev/null 1 Jan 1970 00:00:00 -0000 +++ image/src/org/netbeans/modules/image/VectorTool.java 5 Jul 2005 11:25:15 -0000 @@ -0,0 +1,124 @@ +package org.netbeans.modules.image; + +import java.awt.Color; +import java.awt.Graphics2D; +import java.awt.Dimension; +import java.awt.Point; +import java.awt.Rectangle; + +/** + * VectorTool + * + * @author Timothy Boyce + */ +abstract class VectorTool implements EditTool{ + protected Point startPoint; + protected Point endPoint; + private Color lineColor; + private float lineWidth; + private Rectangle BoundingRectangle; + private Rectangle OldBoundingRectangle; + + protected boolean toolStatus = false; + + public VectorTool(int xVal, int yVal, Color c, int w){ + /* Set the start points */ + startPoint = new Point(xVal, yVal); + + /* Default the end points to the start points */ + endPoint = new Point(xVal, yVal); + + /* Set the Line Colour */ + lineColor = c; + + /* Sets the Line Width */ + lineWidth = (float)w; + } + + /* Default Action to be performed on a drag */ + public void setDragPoint(int xVal, int yVal){ + endPoint.setLocation(xVal, yVal); + } + + /* Default action taken on a release */ + public void setReleasePoint(int xVal, int yVal){ + endPoint.setLocation(xVal, yVal); + + /* Most Edit tools are complete when the user releases + the mouse */ + toolStatus = true; + } + + /* Default action taken on a Click */ + public void setClickPoint(int xVal, int yVal){ + } + + /* Return the tool status */ + public boolean getToolStatus(){ + return toolStatus; + } + + /* Return the shape height */ + private int getHeight(){ + return Math.abs((int)startPoint.getY() - (int)endPoint.getY()); + } + + /* Return the shape width */ + private int getWidth(){ + return Math.abs((int)startPoint.getX() - (int)endPoint.getX()); + } + + /* Retern the top-left point */ + protected Point getTopLeft(){ + double left = (startPoint.getX() < endPoint.getX()) ? startPoint.getX() : endPoint.getX(); + double top = (startPoint.getY() < endPoint.getY()) ? startPoint.getY() : endPoint.getY(); + + return new Point((int)left, (int)top); + } + + /* Return the bottom-right point */ + protected Point getBottomRight(){ + double right = (startPoint.getX() > endPoint.getX()) ? startPoint.getX() : endPoint.getX(); + double bottom = (startPoint.getY() > endPoint.getY()) ? startPoint.getY() : endPoint.getY(); + + return new Point((int)right, (int)bottom); + } + + /* Return the start point object */ + protected Point getStart(){ + return startPoint; + } + + /*Return the end point object */ + protected Point getEnd(){ + return endPoint; + } + + /* Return the width and height as a dimension object */ + protected Dimension getDimension(){ + return new Dimension(getWidth(), getHeight()); + } + + /* Returns a rectangle that bounds this object */ + public Rectangle getBounds(){ + return new Rectangle(getTopLeft(), getDimension()); + } + + /* Returns the line colour if the tool + is complete, otherwise it returns the colour + black to be used in XOR mode */ + protected Color getLineColor(){ + return lineColor; + } + + protected float getLineWidth(){ + return lineWidth; + } + + public boolean getMemoryless(){ + return false; + }; + + /* Writes the current tool to the graphis object */ + public abstract void writeToGraphic(Graphics2D g); +}