java: how to implement drawing freehand using a inner class
Hi I am attempting a paint application and trying to figure how an inner class can get access to the main graphic2D function to implement a freehand draw choice? or am I barking up the wrong tree?
import javax.swing.*; // For JPanel, etc.
import java.awt.*; // For Graphics, etc.
import java.awt.geom.*; // For Ellipse2D, etc.
import java.awt.event.*;
import java.util.ArrayList;
import java.awt.Shape;
import java.awt.Graphics2D;
import java.lang.Math;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
public class DrawingPanel extends JPanel
{
private double x1=0;
private double x2=0;
private double y1=0;
private double y2=0;
private double x3=0;
private double x4=0;
private double y3=0;
private double y4=0;
private double tx=0;
private double ty=0;
private double tz=0;
double width = Math.abs(x1 -x2);
double height = Math.abs(y1-y2);
private Point start, end;
private ArrayList<Shape> myArr = new ArrayList<Shape>();
private ArrayList<Shape> myArr2 = new ArrayList<Shape>();
ButtonPanel buttonPress;
protected void paintComponent(Graphics g) {
super.paintComponent(g);// let panel draw itself
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(Color.blue);
g2d.setStroke(new BasicStroke(4));
for (Shape i : myArr)
{
g2d.draw(i);
}
for(int j = 0;j<myArr2.size();j++)
{
//g2d.setColor(shapeTransColor.get(i));// get the colour from the colour array
g2d.fill(myArr2.get(j));// fill the shape from the shape array
}
}
//inner class
class Listener1 extends MouseAdapter
{
public void mousePressed(MouseEvent e)
{
x1=e.getX();
y1=e.getY();
System.out.println("Mouse Pressed");
if (buttonPress.buttonType.equals("Clear"))
{
System.out.println("ArrayList Size :"+myArr.size());
System.out.println("ArrayList2 Size :"+myArr2.size());
myArr.clear();
myArr2.clear(); // clears all elements from arraylists
System.out.println("ArrayList Size :"+myArr.size());
System.out.println("ArrayList2 Size :"+myArr2.size());
repaint();
}
}
public void mouseReleased(MouseEvent e)
{
x2=e.getX();
y2=e.getY();
Shape shape = null;
if (buttonPress.buttonType.equals("Rectangle"))
{
// Rectangles cannot have a zero width 开发者_如何学Cor height
if (x1 != x2 || y1 != y2)
{
double width = Math.abs(x1 - x2);
double height = Math.abs(y1 - y2);
Rectangle2D.Double rect = new Rectangle2D.Double(Math.min(x1,x2),Math.min(y1,y2), width, height);
myArr.add(rect);
repaint();
}
}
if (buttonPress.buttonType.equals("Eclipse"))
{
double width = Math.abs(x1 - x2);
double height = Math.abs(y1 - y2);
Ellipse2D.Double elli = new Ellipse2D.Double(Math.min(x1,x2),Math.min(y1,y2), width, height);
myArr.add(elli);
repaint();
}
if (buttonPress.buttonType.equals("Lines"))
{
Line2D.Double nuLine = new Line2D.Double(x1, y1, x2, y2);
myArr.add(nuLine);
repaint();
}
if (buttonPress.buttonType.equals("Triangle"))
{/*
*
*
*
repaint(); */
}
if (buttonPress.buttonType.equals("FillRectangle"))
{
if (x1 != x2 || y1 != y2)
{
double width = Math.abs(x1 - x2);
double height = Math.abs(y1 - y2);
Rectangle2D.Double fillRect = new Rectangle2D.Double(Math.min(x1,x2),Math.min(y1,y2), width, height);
myArr2.add(fillRect);
repaint();
}
}
if (buttonPress.buttonType.equals("FillEclipse"))
{
double width = Math.abs(x1 - x2);
double height = Math.abs(y1 - y2);
Ellipse2D.Double fillElli = new Ellipse2D.Double(Math.min(x1,x2),Math.min(y1,y2), width, height);
myArr2.add(fillElli);
repaint();
}
if (buttonPress.buttonType.equals("Freehand"))
{
System.out.println("test free");
//*
//*
//*
repaint();
//myArr2.add(nuLine2);
}
if (shape != null)
{
myArr.add(shape);
myArr2.add(shape);
}
repaint();
}
}
//end of inner class
public DrawingPanel(ButtonPanel reference)
{
buttonPress = reference;
setBorder(BorderFactory.createLineBorder(Color.LIGHT_GRAY,2));
addMouseListener(new Listener1());
repaint();
}
}
I've used two solutions to this problem:
- One solution is to have the outer class hold as a class field a BufferedImage object and display it in its paintComponent method, and then the inner class can extract a Graphics or Graphcis2D object from the BufferedImage, draw to it, dispose the Graphics object, and call repaint on the outer class.
- Another option is to draw in the outer class's paintComponent method using class ArrayLists of Point (or other Shape) objects that are filled from within the inner class. In the latter situation the inner class has nothing to do with a Graphics object but rather fills the outer's array lists and calls repaint.
You can put:
private Graphics2D g2d;
As a class member of the panel and after the first time paintComponent is called it will have the main graphics object accessible to inner classes.
精彩评论