commit
4148c1788a
@ -0,0 +1,6 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<classpath> |
||||||
|
<classpathentry kind="src" path="src"/> |
||||||
|
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER"/> |
||||||
|
<classpathentry kind="output" path="bin"/> |
||||||
|
</classpath> |
@ -0,0 +1,13 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||||
|
<launchConfiguration type="org.eclipse.ant.AntBuilderLaunchConfigurationType"> |
||||||
|
<booleanAttribute key="org.eclipse.ant.ui.ATTR_TARGETS_UPDATED" value="true"/> |
||||||
|
<booleanAttribute key="org.eclipse.ant.ui.DEFAULT_VM_INSTALL" value="false"/> |
||||||
|
<booleanAttribute key="org.eclipse.debug.ui.ATTR_LAUNCH_IN_BACKGROUND" value="false"/> |
||||||
|
<stringAttribute key="org.eclipse.jdt.launching.CLASSPATH_PROVIDER" value="org.eclipse.ant.ui.AntClasspathProvider"/> |
||||||
|
<booleanAttribute key="org.eclipse.jdt.launching.DEFAULT_CLASSPATH" value="true"/> |
||||||
|
<stringAttribute key="org.eclipse.jdt.launching.PROJECT_ATTR" value="HelloWorld"/> |
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_LOCATION" value="${workspace_loc:/HelloWorld/projectBuilder.xml}"/> |
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_RUN_BUILD_KINDS" value="full,incremental,"/> |
||||||
|
<booleanAttribute key="org.eclipse.ui.externaltools.ATTR_TRIGGERS_CONFIGURED" value="true"/> |
||||||
|
<stringAttribute key="org.eclipse.ui.externaltools.ATTR_WORKING_DIRECTORY" value="${workspace_loc:/HelloWorld}"/> |
||||||
|
</launchConfiguration> |
@ -0,0 +1,27 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8"?> |
||||||
|
<projectDescription> |
||||||
|
<name>BandoriTracker</name> |
||||||
|
<comment></comment> |
||||||
|
<projects> |
||||||
|
</projects> |
||||||
|
<buildSpec> |
||||||
|
<buildCommand> |
||||||
|
<name>org.eclipse.jdt.core.javabuilder</name> |
||||||
|
<arguments> |
||||||
|
</arguments> |
||||||
|
</buildCommand> |
||||||
|
<buildCommand> |
||||||
|
<name>org.eclipse.ui.externaltools.ExternalToolBuilder</name> |
||||||
|
<triggers>full,incremental,</triggers> |
||||||
|
<arguments> |
||||||
|
<dictionary> |
||||||
|
<key>LaunchConfigHandle</key> |
||||||
|
<value><project>/.externalToolBuilders/New_Builder (4).launch</value> |
||||||
|
</dictionary> |
||||||
|
</arguments> |
||||||
|
</buildCommand> |
||||||
|
</buildSpec> |
||||||
|
<natures> |
||||||
|
<nature>org.eclipse.jdt.core.javanature</nature> |
||||||
|
</natures> |
||||||
|
</projectDescription> |
@ -0,0 +1,11 @@ |
|||||||
|
eclipse.preferences.version=1 |
||||||
|
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=enabled |
||||||
|
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.8 |
||||||
|
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve |
||||||
|
org.eclipse.jdt.core.compiler.compliance=1.8 |
||||||
|
org.eclipse.jdt.core.compiler.debug.lineNumber=generate |
||||||
|
org.eclipse.jdt.core.compiler.debug.localVariable=generate |
||||||
|
org.eclipse.jdt.core.compiler.debug.sourceFile=generate |
||||||
|
org.eclipse.jdt.core.compiler.problem.assertIdentifier=error |
||||||
|
org.eclipse.jdt.core.compiler.problem.enumIdentifier=error |
||||||
|
org.eclipse.jdt.core.compiler.source=1.8 |
Binary file not shown.
@ -0,0 +1 @@ |
|||||||
|
/sig/ |
@ -0,0 +1,18 @@ |
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?> |
||||||
|
<project default="create_run_jar" name="Create Runnable Jar for Project BandoriTracker"> |
||||||
|
<!--this file was created by Eclipse Runnable JAR Export Wizard--> |
||||||
|
<!--ANT 1.7 is required --> |
||||||
|
<!--define folder properties--> |
||||||
|
<property name="dir.buildfile" value="."/> |
||||||
|
<property name="dir.workspace" value="${dir.buildfile}/.."/> |
||||||
|
<property name="dir.jarfile" value="${dir.buildfile}"/> |
||||||
|
<target name="create_run_jar"> |
||||||
|
<jar destfile="${dir.jarfile}/BandoriTracker.jar" filesetmanifest="mergewithoutmain"> |
||||||
|
<manifest> |
||||||
|
<attribute name="Main-Class" value="sig.tracker.BandoriTracker"/> |
||||||
|
<attribute name="Class-Path" value="."/> |
||||||
|
</manifest> |
||||||
|
<fileset dir="${dir.jarfile}/bin"/> |
||||||
|
</jar> |
||||||
|
</target> |
||||||
|
</project> |
@ -0,0 +1,326 @@ |
|||||||
|
package sig.tracker; |
||||||
|
|
||||||
|
import java.awt.AWTException; |
||||||
|
import java.awt.Color; |
||||||
|
import java.awt.Cursor; |
||||||
|
import java.awt.Dimension; |
||||||
|
import java.awt.Graphics; |
||||||
|
import java.awt.Graphics2D; |
||||||
|
import java.awt.Image; |
||||||
|
import java.awt.Point; |
||||||
|
import java.awt.Rectangle; |
||||||
|
import java.awt.Robot; |
||||||
|
import java.awt.Toolkit; |
||||||
|
import java.awt.event.ActionEvent; |
||||||
|
import java.awt.event.ActionListener; |
||||||
|
import java.awt.event.MouseEvent; |
||||||
|
import java.awt.event.MouseListener; |
||||||
|
import java.awt.image.BufferedImage; |
||||||
|
import java.io.File; |
||||||
|
import java.io.IOException; |
||||||
|
import java.util.ArrayList; |
||||||
|
import java.util.Arrays; |
||||||
|
import java.util.List; |
||||||
|
|
||||||
|
import javax.imageio.ImageIO; |
||||||
|
import javax.swing.JFileChooser; |
||||||
|
import javax.swing.JFrame; |
||||||
|
import javax.swing.JOptionPane; |
||||||
|
import javax.swing.JPanel; |
||||||
|
import javax.swing.SwingUtilities; |
||||||
|
import javax.swing.Timer; |
||||||
|
|
||||||
|
public class BandoriTracker { |
||||||
|
public static BufferedImage capture; |
||||||
|
public static BufferedImage footprint_img; |
||||||
|
public static Robot robot = null; |
||||||
|
static UpdateEvent runEvent = new UpdateEvent(); |
||||||
|
static Timer programClock = new Timer(16,runEvent); |
||||||
|
public static DrawPanel panel; |
||||||
|
public static final ModeType MODE = ModeType.FOOTPRINT; |
||||||
|
public static ModeType FOOTPRINT_MODE = ModeType.FOOTPRINT_ORIGIN1; |
||||||
|
public static Point origin1,origin2; |
||||||
|
public static Character character; |
||||||
|
public static DChar displayedFootprint; |
||||||
|
public static List<DChar> footprint_database = new ArrayList<DChar>(); |
||||||
|
public static void main(String[] args) { |
||||||
|
try { |
||||||
|
robot = new Robot(); |
||||||
|
} catch (AWTException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
capture = robot.createScreenCapture(new Rectangle(0,0,(int)Toolkit.getDefaultToolkit().getScreenSize().getWidth(),(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight())); |
||||||
|
|
||||||
|
JFrame f = new JFrame(); |
||||||
|
panel = new DrawPanel(); |
||||||
|
f.add(panel); |
||||||
|
f.pack(); |
||||||
|
f.setSize(500, 500); |
||||||
|
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); |
||||||
|
SwingUtilities.invokeLater(new Runnable() { |
||||||
|
@Override |
||||||
|
public void run() { |
||||||
|
f.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
}); |
||||||
|
programClock.start(); |
||||||
|
|
||||||
|
switch (MODE) { |
||||||
|
case FOOTPRINT:{ |
||||||
|
JFileChooser browse = new JFileChooser(); |
||||||
|
browse.setDialogTitle("Select Footprint File"); |
||||||
|
if (browse.showOpenDialog(null) == JFileChooser.APPROVE_OPTION) { |
||||||
|
String fileloc = browse.getSelectedFile().getAbsolutePath(); |
||||||
|
try { |
||||||
|
footprint_img = ImageIO.read(new File(fileloc)); |
||||||
|
JOptionPane.showMessageDialog(null, "Click on origin location."); |
||||||
|
FOOTPRINT_MODE = ModeType.FOOTPRINT_ORIGIN1; |
||||||
|
ChangeCursor(Cursor.CROSSHAIR_CURSOR); |
||||||
|
} catch (IOException e) { |
||||||
|
e.printStackTrace(); |
||||||
|
} |
||||||
|
} |
||||||
|
}break; |
||||||
|
default:{ |
||||||
|
|
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
public static void ChangeCursor(int cursor) { |
||||||
|
BandoriTracker.panel.setCursor(Cursor.getPredefinedCursor(cursor)); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class DrawPanel extends JPanel implements MouseListener{ |
||||||
|
|
||||||
|
DrawPanel() { |
||||||
|
addMouseListener(this); |
||||||
|
} |
||||||
|
|
||||||
|
public Dimension getPreferredSize() { |
||||||
|
return new Dimension(1280,480); |
||||||
|
} |
||||||
|
|
||||||
|
public void paintComponent(Graphics g) { |
||||||
|
switch (BandoriTracker.MODE) { |
||||||
|
case FOOTPRINT:{ |
||||||
|
if (DisplaySampledFootprint()) { |
||||||
|
g.clearRect(0, 0, getWidth(), getHeight()); |
||||||
|
BandoriTracker.displayedFootprint.draw(14,new Point(0,0),g); |
||||||
|
BandoriTracker.displayedFootprint.draw(BandoriTracker.displayedFootprint.initial_size,new Point(32,0),g); |
||||||
|
BandoriTracker.displayedFootprint.draw(32,new Point(64,0),g); |
||||||
|
} else |
||||||
|
if (BandoriTracker.footprint_img!=null) { |
||||||
|
g.drawImage(BandoriTracker.footprint_img, 0,0, null); |
||||||
|
} |
||||||
|
}break; |
||||||
|
default:{ |
||||||
|
if (BandoriTracker.capture!=null) { |
||||||
|
g.drawImage(BandoriTracker.capture, 0, 0, BandoriTracker.capture.getWidth()/2, BandoriTracker.capture.getHeight()/2, null); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseClicked(MouseEvent e) { |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mousePressed(MouseEvent e) { |
||||||
|
if (GettingFirstClick()) { |
||||||
|
BandoriTracker.origin1 = e.getPoint(); |
||||||
|
BandoriTracker.FOOTPRINT_MODE = ModeType.FOOTPRINT_ORIGIN2; |
||||||
|
JOptionPane.showMessageDialog(null, "Click on ending location."); |
||||||
|
} else |
||||||
|
if (GettingSecondClick()) { |
||||||
|
BandoriTracker.origin2 = e.getPoint(); |
||||||
|
BandoriTracker.FOOTPRINT_MODE = ModeType.FOOTPRINT_CHARACTER; |
||||||
|
BandoriTracker.ChangeCursor(Cursor.DEFAULT_CURSOR); |
||||||
|
String input = JOptionPane.showInputDialog("What character is this representing?"); |
||||||
|
BandoriTracker.character = input.charAt(0); |
||||||
|
|
||||||
|
DChar footprint = new DChar(BandoriTracker.footprint_img,BandoriTracker.character,BandoriTracker.origin1,BandoriTracker.origin2); |
||||||
|
BandoriTracker.footprint_database.add(BandoriTracker.displayedFootprint = footprint); |
||||||
|
BandoriTracker.FOOTPRINT_MODE = ModeType.FOOTPRINT_PRINT; |
||||||
|
} |
||||||
|
|
||||||
|
//System.out.println("Clicked: "+e.getX()+","+e.getY());
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseReleased(MouseEvent e) { |
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseEntered(MouseEvent e) { |
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public void mouseExited(MouseEvent e) { |
||||||
|
// TODO Auto-generated method stub
|
||||||
|
|
||||||
|
} |
||||||
|
|
||||||
|
boolean GettingFirstClick() { |
||||||
|
return BandoriTracker.MODE == ModeType.FOOTPRINT && BandoriTracker.FOOTPRINT_MODE == ModeType.FOOTPRINT_ORIGIN1; |
||||||
|
} |
||||||
|
boolean GettingSecondClick() { |
||||||
|
return BandoriTracker.MODE == ModeType.FOOTPRINT && BandoriTracker.FOOTPRINT_MODE == ModeType.FOOTPRINT_ORIGIN2; |
||||||
|
} |
||||||
|
boolean DisplaySampledFootprint() { |
||||||
|
return BandoriTracker.MODE == ModeType.FOOTPRINT && BandoriTracker.FOOTPRINT_MODE == ModeType.FOOTPRINT_PRINT; |
||||||
|
} |
||||||
|
} |
||||||
|
class UpdateEvent implements ActionListener { |
||||||
|
@Override |
||||||
|
public void actionPerformed(ActionEvent e) { |
||||||
|
BandoriTracker.capture = BandoriTracker.robot.createScreenCapture(new Rectangle(9+66,30+10,(int)Toolkit.getDefaultToolkit().getScreenSize().getWidth()-18-66*2,(int)Toolkit.getDefaultToolkit().getScreenSize().getHeight()-62-10*2)); |
||||||
|
BandoriTracker.panel.repaint(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class DChar { |
||||||
|
Character character; |
||||||
|
Point[] points; |
||||||
|
Integer initial_size; |
||||||
|
|
||||||
|
DChar(Image ref_img, Character c, Point origin1, Point origin2){ |
||||||
|
Color back_col; |
||||||
|
this.character=c; |
||||||
|
BufferedImage img = toBufferedImage(ref_img); |
||||||
|
int width = origin2.x-origin1.x; |
||||||
|
int[] pixels = img.getRGB(origin1.x, origin1.y, width, origin2.y-origin1.y, null, 0, width); |
||||||
|
System.out.println(Arrays.toString(pixels)); |
||||||
|
//First trim the image.
|
||||||
|
int top_height = -1; |
||||||
|
int bottom_height = -1; |
||||||
|
for (int j=0;j<pixels.length/width;j++) { |
||||||
|
for (int i=0;i<width;i++) { |
||||||
|
if (ColorMeetsThreshold(pixels[i+j*width],25)) { |
||||||
|
top_height=j; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (top_height!=-1) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
for (int j=pixels.length/width-1;j>=0;j--) { |
||||||
|
for (int i=width-1;i>=0;i--) { |
||||||
|
if (ColorMeetsThreshold(pixels[i+j*width],25)) { |
||||||
|
//Found bottom-most pixel.
|
||||||
|
bottom_height=j+1; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (bottom_height!=-1) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
int left_width = -1; |
||||||
|
int right_width = -1; |
||||||
|
for (int i=0;i<width;i++) { |
||||||
|
for (int j=0;j<pixels.length/width;j++) { |
||||||
|
if (ColorMeetsThreshold(pixels[i+j*width],25)) { |
||||||
|
left_width=i; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (left_width!=-1) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
for (int i=width-1;i>=0;i--) { |
||||||
|
for (int j=pixels.length/width-1;j>=0;j--) { |
||||||
|
if (ColorMeetsThreshold(pixels[i+j*width],25)) { |
||||||
|
right_width=i; |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
if (right_width!=-1) { |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
//System.out.println("TOP:"+top_height+",BOTTOM:"+bottom_height+",LEFT:"+left_width+",RIGHT:"+right_width+". Size: "+pixels.length);
|
||||||
|
pixels = Arrays.copyOfRange(pixels, top_height*width, bottom_height*width); |
||||||
|
int goodpixels = 0; |
||||||
|
for (int i=0;i<pixels.length;i++) { |
||||||
|
if (i%width<left_width || i%width>right_width) { |
||||||
|
pixels[i]=Integer.MAX_VALUE; |
||||||
|
} else { |
||||||
|
goodpixels++; |
||||||
|
} |
||||||
|
} |
||||||
|
int[] trim_pixels = new int[goodpixels]; |
||||||
|
int goodpixelslot = 0; |
||||||
|
for (int i=0;i<pixels.length;i++) { |
||||||
|
if (pixels[i]!=Integer.MAX_VALUE) { |
||||||
|
trim_pixels[goodpixelslot++]=pixels[i]; |
||||||
|
} |
||||||
|
} |
||||||
|
width = right_width-left_width+1; |
||||||
|
int height = initial_size = bottom_height-top_height; |
||||||
|
List<Point> pointlist = new ArrayList<Point>(); |
||||||
|
for (int j=0;j<height;j++) { |
||||||
|
for (int i=0;i<width;i++) { |
||||||
|
if (ColorMeetsThreshold(trim_pixels[i+j*width],25)) { |
||||||
|
pointlist.add(new Point(i,j)); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
System.out.println(pointlist.toString()); |
||||||
|
//System.out.println("Character height: "+height);
|
||||||
|
points = pointlist.toArray(new Point[pointlist.size()]); |
||||||
|
System.out.println(Arrays.toString(points)); |
||||||
|
} |
||||||
|
|
||||||
|
private boolean ColorMeetsThreshold(int color, int threshold) { |
||||||
|
Color col = new Color(color); |
||||||
|
return col.getRed()+col.getGreen()+col.getBlue()<=(255-threshold)*3; |
||||||
|
} |
||||||
|
|
||||||
|
public void draw(int text_size, Point offset, Graphics g) { |
||||||
|
for (int i=0;i<points.length;i++) { |
||||||
|
g.drawOval(offset.x+(int)(points[i].x*((double)text_size/initial_size)), offset.y+(int)(points[i].y*((double)text_size/initial_size)), 1, 1); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void draw(Graphics g) { |
||||||
|
draw(initial_size,new Point(0,0),g); |
||||||
|
} |
||||||
|
|
||||||
|
public static BufferedImage toBufferedImage(Image img) |
||||||
|
{ |
||||||
|
if (img instanceof BufferedImage) |
||||||
|
{ |
||||||
|
return (BufferedImage) img; |
||||||
|
} |
||||||
|
|
||||||
|
// Create a buffered image with transparency
|
||||||
|
BufferedImage bimage = new BufferedImage(img.getWidth(null), img.getHeight(null), BufferedImage.TYPE_INT_ARGB); |
||||||
|
|
||||||
|
// Draw the image on to the buffered image
|
||||||
|
Graphics2D bGr = bimage.createGraphics(); |
||||||
|
bGr.drawImage(img, 0, 0, null); |
||||||
|
bGr.dispose(); |
||||||
|
|
||||||
|
// Return the buffered image
|
||||||
|
return bimage; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
enum ModeType { |
||||||
|
NORMAL, |
||||||
|
FOOTPRINT, |
||||||
|
FOOTPRINT_ORIGIN1, |
||||||
|
FOOTPRINT_ORIGIN2, |
||||||
|
FOOTPRINT_CHARACTER, |
||||||
|
FOOTPRINT_PRINT |
||||||
|
|
||||||
|
} |
@ -0,0 +1,203 @@ |
|||||||
|
package sig.tracker; |
||||||
|
|
||||||
|
import java.util.*; |
||||||
|
import java.awt.*; |
||||||
|
import java.awt.event.*; |
||||||
|
import javax.swing.*; |
||||||
|
import javax.swing.event.*; |
||||||
|
|
||||||
|
/** |
||||||
|
* Note: Normally the ButtonPanel and DrawingArea would not be static classes. |
||||||
|
* This was done for the convenience of posting the code in one class and to |
||||||
|
* highlight the differences between the two approaches. All the differences |
||||||
|
* are found in the DrawingArea class. |
||||||
|
*/ |
||||||
|
public class DrawOnComponent |
||||||
|
{ |
||||||
|
public static void main(String[] args) |
||||||
|
{ |
||||||
|
SwingUtilities.invokeLater(new Runnable() { |
||||||
|
public void run() { |
||||||
|
createAndShowGUI(); |
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
private static void createAndShowGUI() |
||||||
|
{ |
||||||
|
DrawingArea drawingArea = new DrawingArea(); |
||||||
|
ButtonPanel buttonPanel = new ButtonPanel( drawingArea ); |
||||||
|
|
||||||
|
JFrame.setDefaultLookAndFeelDecorated(true); |
||||||
|
JFrame frame = new JFrame("Draw On Component"); |
||||||
|
frame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); |
||||||
|
frame.getContentPane().add(drawingArea); |
||||||
|
frame.getContentPane().add(buttonPanel, BorderLayout.SOUTH); |
||||||
|
frame.setSize(400, 400); |
||||||
|
frame.setLocationRelativeTo( null ); |
||||||
|
frame.setVisible(true); |
||||||
|
} |
||||||
|
|
||||||
|
static class ButtonPanel extends JPanel implements ActionListener |
||||||
|
{ |
||||||
|
private DrawingArea drawingArea; |
||||||
|
|
||||||
|
public ButtonPanel(DrawingArea drawingArea) |
||||||
|
{ |
||||||
|
this.drawingArea = drawingArea; |
||||||
|
|
||||||
|
add( createButton(" ", Color.BLACK) ); |
||||||
|
add( createButton(" ", Color.RED) ); |
||||||
|
add( createButton(" ", Color.GREEN) ); |
||||||
|
add( createButton(" ", Color.BLUE) ); |
||||||
|
add( createButton(" ", Color.ORANGE) ); |
||||||
|
add( createButton(" ", Color.YELLOW) ); |
||||||
|
add( createButton("Clear Drawing", null) ); |
||||||
|
} |
||||||
|
|
||||||
|
private JButton createButton(String text, Color background) |
||||||
|
{ |
||||||
|
JButton button = new JButton( text ); |
||||||
|
button.setBackground( background ); |
||||||
|
button.addActionListener( this ); |
||||||
|
|
||||||
|
return button; |
||||||
|
} |
||||||
|
|
||||||
|
public void actionPerformed(ActionEvent e) |
||||||
|
{ |
||||||
|
JButton button = (JButton)e.getSource(); |
||||||
|
|
||||||
|
if ("Clear Drawing".equals(e.getActionCommand())) |
||||||
|
drawingArea.clear(); |
||||||
|
else |
||||||
|
drawingArea.setForeground( button.getBackground() ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
static class DrawingArea extends JPanel |
||||||
|
{ |
||||||
|
private final static int AREA_SIZE = 400; |
||||||
|
private ArrayList<ColoredRectangle> coloredRectangles = new ArrayList<ColoredRectangle>(); |
||||||
|
private Rectangle shape; |
||||||
|
|
||||||
|
public DrawingArea() |
||||||
|
{ |
||||||
|
setBackground(Color.WHITE); |
||||||
|
|
||||||
|
MyMouseListener ml = new MyMouseListener(); |
||||||
|
addMouseListener(ml); |
||||||
|
addMouseMotionListener(ml); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
public Dimension getPreferredSize() |
||||||
|
{ |
||||||
|
return isPreferredSizeSet() ? |
||||||
|
super.getPreferredSize() : new Dimension(AREA_SIZE, AREA_SIZE); |
||||||
|
} |
||||||
|
|
||||||
|
@Override |
||||||
|
protected void paintComponent(Graphics g) |
||||||
|
{ |
||||||
|
super.paintComponent(g); |
||||||
|
|
||||||
|
// Custom code to paint all the Rectangles from the List
|
||||||
|
|
||||||
|
Color foreground = g.getColor(); |
||||||
|
|
||||||
|
g.setColor( Color.BLACK ); |
||||||
|
g.drawString("Add a rectangle by doing mouse press, drag and release!", 40, 15); |
||||||
|
|
||||||
|
for (DrawingArea.ColoredRectangle cr : coloredRectangles) |
||||||
|
{ |
||||||
|
g.setColor( cr.getForeground() ); |
||||||
|
Rectangle r = cr.getRectangle(); |
||||||
|
g.drawRect(r.x, r.y, r.width, r.height); |
||||||
|
} |
||||||
|
|
||||||
|
// Paint the Rectangle as the mouse is being dragged
|
||||||
|
|
||||||
|
if (shape != null) |
||||||
|
{ |
||||||
|
Graphics2D g2d = (Graphics2D)g; |
||||||
|
g2d.setColor( foreground ); |
||||||
|
g2d.draw( shape ); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
public void addRectangle(Rectangle rectangle, Color color) |
||||||
|
{ |
||||||
|
// Add the Rectangle to the List so it can be repainted
|
||||||
|
|
||||||
|
ColoredRectangle cr = new ColoredRectangle(color, rectangle); |
||||||
|
coloredRectangles.add( cr ); |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
public void clear() |
||||||
|
{ |
||||||
|
coloredRectangles.clear(); |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
class MyMouseListener extends MouseInputAdapter |
||||||
|
{ |
||||||
|
private Point startPoint; |
||||||
|
|
||||||
|
public void mousePressed(MouseEvent e) |
||||||
|
{ |
||||||
|
startPoint = e.getPoint(); |
||||||
|
shape = new Rectangle(); |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseDragged(MouseEvent e) |
||||||
|
{ |
||||||
|
int x = Math.min(startPoint.x, e.getX()); |
||||||
|
int y = Math.min(startPoint.y, e.getY()); |
||||||
|
int width = Math.abs(startPoint.x - e.getX()); |
||||||
|
int height = Math.abs(startPoint.y - e.getY()); |
||||||
|
|
||||||
|
shape.setBounds(x, y, width, height); |
||||||
|
repaint(); |
||||||
|
} |
||||||
|
|
||||||
|
public void mouseReleased(MouseEvent e) |
||||||
|
{ |
||||||
|
if (shape.width != 0 || shape.height != 0) |
||||||
|
{ |
||||||
|
addRectangle(shape, e.getComponent().getForeground()); |
||||||
|
} |
||||||
|
|
||||||
|
shape = null; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
class ColoredRectangle |
||||||
|
{ |
||||||
|
private Color foreground; |
||||||
|
private Rectangle rectangle; |
||||||
|
|
||||||
|
public ColoredRectangle(Color foreground, Rectangle rectangle) |
||||||
|
{ |
||||||
|
this.foreground = foreground; |
||||||
|
this.rectangle = rectangle; |
||||||
|
} |
||||||
|
|
||||||
|
public Color getForeground() |
||||||
|
{ |
||||||
|
return foreground; |
||||||
|
} |
||||||
|
|
||||||
|
public void setForeground(Color foreground) |
||||||
|
{ |
||||||
|
this.foreground = foreground; |
||||||
|
} |
||||||
|
|
||||||
|
public Rectangle getRectangle() |
||||||
|
{ |
||||||
|
return rectangle; |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue