I need to some help about drawing shapes with java graphics...,I'm trying to create paint application and when I using mousedragged its drawing multiple shapes (from small to large);like this : https://i.sstatic.net/0oQmv.png
Anyone can solve this issue ? THANKS FOR ALL..
This is DrawingArea class :
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.awt.image.RenderedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JColorChooser;
import javax.swing.JComponent;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JSlider;
import say.swing.JFontChooser;
public class DrawingArea extends JComponent implements MouseListener,MouseMotionListener {
/**
*
*/
Shapers shape;//IMPORTED FROM SHAPERS CLASS TO USE THE ENUMS.
private Font myFont;
private Image image;
private Graphics2D g2;
private static final long serialVersionUID = 1L;
private Color currentColor, initialColor = Color.BLACK;
private int oldX, oldY, lastX, lastY, draggedX, draggedY, width, height, x, y, thickness = 3;
public DrawingArea() { //ADDING LISTENERS FOR JCOMPONENTS.
setDoubleBuffered(false);
addMouseMotionListener(this);
addMouseListener(this);
}
//PENCIL OR ERASER STROKE SETTED BY JSLIDER
public void setStroke(JSlider slider) {thickness = slider.getValue();}
//FOR CHOOSING COLOR FROM COLOR CHOOSER
public void ChooseColor() { currentColor = JColorChooser.showDialog(this, "Choose Your Color", initialColor);}
//CHOOSING FONT FROM FONTCHOOSER (EXTERNAL LIBRARY).
public void ChooseFont() {
JFontChooser chooseFont = new JFontChooser();
int results = chooseFont.showDialog(this);
if (results == JFontChooser.OK_OPTION) {
myFont = chooseFont.getSelectedFont();
}
}
@Override//GETTING FIRST (STARTING) COORDINATE WHEN THE MOUSE PRESSED
public void mousePressed(MouseEvent e) {
oldX = e.getX();
oldY = e.getY();
repaint();
if(shape == Shapers.TEXT){ //DRAWING TEXT (FONT,SIZE AND COLOR ENABLED).
String str = JOptionPane.showInputDialog("Write Your Text Here : ");
g2.setFont(myFont);
g2.setColor(currentColor);
g2.drawString(str, oldX, oldY);
}
}
@Override//GETTING RELEASED COORDINATE TO DRAW LINE.
public void mouseReleased(MouseEvent e) {
lastX = e.getX();
lastY = e.getY();
}
//GETTING COORDINATE TO DRAW FILLEDRECT,FILLEDOVAL,OVAL,RECT.
public void mouseDragged(MouseEvent e) {
draggedX = e.getX();
draggedY = e.getY();
repaint();
width = Math.abs(oldX - draggedX);
height = Math.abs(oldY - draggedY);
x = Math.min(draggedX, oldX);
y = Math.min(draggedY, oldY);
}
public void mouseMoved(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
//CLEAR THE ALL SHAPES DRAWED ON DRAW AREA.
public void clear() {
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, (int) this.getWidth() + 55, (int) this.getHeight() + 55);
super.repaint();
}
//FIRST DRAWING WHITE IMAGE TO ABLE SAVE DRAWED SHAPES ON DRAWING AREA.
//AFTER THAT DRAWING WHEN FIRE BUTTONS ACTIONLISTENER (FROM CODER_PAINT CLASS) SELECTING SHAPES WITH IF & ELSE.
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null) {
image = createImage((int) this.getWidth(), (int) this.getHeight());
g2 = (Graphics2D) image.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
g.drawImage(image, 0, 0, this);
g2.setColor(initialColor);
if(shape == Shapers.PENCIL){
g2.setColor(currentColor);
g2.fillOval(draggedX, draggedY, thickness, thickness);
repaint();
}
else if(shape == Shapers.OVAL){
g2.setColor(currentColor);
g2.drawOval(oldX, oldY, draggedX, draggedX);
repaint();
}
else if(shape == Shapers.FILLEDOVAL){
g2.setColor(currentColor);
g2.fillOval(oldX, oldY, draggedX, draggedY);
repaint();
}
else if(shape == Shapers.RECT){
g2.setColor(currentColor);
g2.drawRect(x, y, width, height);
repaint();
}
else if(shape == Shapers.FILLEDRECT){
g2.setColor(currentColor);
g2.fillRect(x, y, width, height);
repaint();
}
else if(shape == Shapers.LINE){
g2.setColor(currentColor);
g2.drawLine(oldX, oldY, lastX, lastY);
oldX = lastX;//SETTING FIRST COORDINATE TO LAST COORDINATE BECAUSE ABLE TO CONTINUE DRAWING LINE.
oldY = lastY;
repaint();
}
else if(shape == Shapers.ERASER){
g2.setColor(Color.WHITE);
g2.fillRect(draggedX, draggedY, thickness, thickness);
repaint();
}
else{
}
}
//AFTER DRAWING IF THE USER WANTED SAVE THE DRAWED WE CAN USE THIS METHOD.
public void SaveImage() {
try {
String fileName = JOptionPane.showInputDialog(null, "Please enter file name...");
String fileType = JOptionPane.showInputDialog(null, "Please enter file type...");
if (fileName != null && fileType != null && fileName.length() > 0 && fileType.length() > 0) {
ImageIO.write((RenderedImage) image, fileType.toUpperCase(),//WRITING NEW FILE DATAS GETTED FROM DRAW AREA IMAGE.
new File("/Users/MacbookPro/Desktop/" + fileName + "." + fileType.toUpperCase()));
JOptionPane.showMessageDialog(null, "Your image saved.");
} else {
JOptionPane.showMessageDialog(null, "Please try re saving and dont't forget filling the blanks!");
return;
}
} catch (IOException e2) {System.out.println("CanNot save the image!");}
}
//CHANGING CHOOSED COLOR PANEL TO USER CAN KNOW WHICH COLOR CHOOSED NOW
public void changeColor(JPanel panel) {panel.setBackground(currentColor);}
//THIS METHOD USING TO IMPORT IMAGE FROM COMPUTER.
public void PrintImage(Image img) {
g2.drawImage(img, 0, 0, this.getWidth(), this.getHeight(), this);
super.paint(g2);
repaint();
}
//CALLING UPDATE METHOD FOR WHAT I'M ALSO DON'T KNOW :)
public void update(Graphics g) {super.repaint();}
}
Finally after a lot struggle I solved it :) and there is some example code :
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image != null) {
g2D = (Graphics2D) image.getGraphics();
g2D.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(image, 0, 0, AREA_WIDTH, AREA_HEIGHT, null);
}
//SETTING STROKE FOR SHAPES
BasicStroke basicStroke = new BasicStroke(thickness);
Graphics2D g2d = (Graphics2D) g;
g2d.setStroke(basicStroke);
g2d.setPaint(currentColor);
if(g2d != null) {
// ENUMROPE = IS ENUM CLASS USED LIKE BRIDGE BETWEEN MAIN CLASS AND DRAWING AREA
if (figures == EnumRope.RECT && rectangle != null) {
g2d.draw(rectangle);
}else if(figures == EnumRope.FILLEDRECT && rectangle != null){
g2d.fill(rectangle);
}else if (figures == EnumRope.OVAL && ellipse2d != null) {
g2d.draw(ellipse2d);
}else if (figures == EnumRope.FILLEDOVAL && ellipse2d != null){
g2d.fill(ellipse2d);
}else if (figures == EnumRope.LINE && line2d != null) {
g2d.draw(line2d);
}else if(figures == EnumRope.PENCIL && ErasRect != null){
g2d.fill(ErasRect);
}else if(figures == EnumRope.ERASER && ErasRect != null){
g2d.fill(ErasRect);
}
}
}
public void clear()
{ //INVOKING CLEARAREA METHOD
clearArea();
repaint();
}
public void clearArea() {
//THERE CREATED NEW IMAGE TO CLEAN DRAW AREA & ERASE ALL DRAWN SHAPES
image = new BufferedImage(AREA_WIDTH, AREA_HEIGHT, BufferedImage.TYPE_INT_ARGB);
}
public void addRectangle(Rectangle rectangle, Color color, int tickness)
{
// DRAW THE RECTANGLE ONTO THE BUFFEREDIMAGE
BasicStroke basicStroke = new BasicStroke(tickness);
Graphics2D g2d = (Graphics2D)image.getGraphics();
g2d.setStroke(basicStroke);
g2d.setColor( currentColor );
if(figures==EnumRope.FILLEDRECT){
g2d.fill( rectangle );
}else {
g2d.draw( rectangle );
}
repaint();
}
public void addEllipse(Ellipse2D.Float ellipse2D, Color color, int tickness)
{
// DRAW THE OVAL(circle) ONTO THE BUFFEREDIMAGE
BasicStroke basicStroke = new BasicStroke(tickness);
Graphics2D g2d = (Graphics2D)image.getGraphics();
g2d.setStroke(basicStroke);
g2d.setColor( currentColor );
if(figures == EnumRope.FILLEDOVAL) {
g2d.fill( ellipse2D );
}else {
g2d.draw( ellipse2D );
}
repaint();
}
public void addLine(Line2D.Float line2D, Color color, int tickness)
{
// DRAW THE LINE ONTO THE BUFFEREDIMAGE
BasicStroke basicStroke = new BasicStroke(tickness);
Graphics2D g2d = (Graphics2D)image.getGraphics();
g2d.setStroke(basicStroke);
g2d.setColor( currentColor );
g2d.draw( line2D );
repaint();
}
public void addEraser(Rectangle2D.Float erasRect, Color color, int tickness)
{
// DRAW THE ERASER(WHITE,CONSTANT RECTANGLE) ONTO THE BUFFEREDIMAGE
BasicStroke basicStroke = new BasicStroke(tickness);
Graphics2D g2d = (Graphics2D)image.getGraphics();
g2d.setStroke(basicStroke);
g2d.setColor(Color.WHITE);
g2d.fill(erasRect);
repaint();
}
public void addPencil(Rectangle2D.Float erasRect, Color color, int tickness)
{
// DRAW THE PENCIL(COLORED,CONSTANT RECTANGLE) ONTO THE BUFFEREDIMAGE
BasicStroke basicStroke = new BasicStroke(tickness);
Graphics2D g2d = (Graphics2D)image.getGraphics();
g2d.setStroke(basicStroke);
g2d.setColor(currentColor);
g2d.fill(erasRect);
repaint();
}
//NEW INNER CLASS FOR MOUSEADAPTER
class MyMouseListener extends MouseInputAdapter{
private Point startpoint;
@Override
public void mousePressed(MouseEvent e)
{
startpoint = e.getPoint();
rectangle = new Rectangle();
oldX = e.getX();
oldY = e.getY();
repaint();
if(figures == EnumRope.TEXT){
text = JOptionPane.showInputDialog("Write Your Text Here : ");
g2D.setFont(myFont);
g2D.setColor(currentColor);
g2D.drawString(text, oldX, oldY);
repaint();
}
}
@Override
public void mouseDragged(MouseEvent e) {
currentX = e.getX();
currentY = e.getY();
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());
rectangle.setBounds(x, y, width, height);
repaint();
ellipse2d = new Ellipse2D.Float(x, y, width, height);
repaint();
line2d = new Line2D.Float(oldX, oldY, currentX, currentY);
repaint();
ErasRect = new Rectangle2D.Float(currentX, currentY, thickness, thickness);
repaint();
// WE NEED ADD THIS TWO SHAPE HERE BECAUSE SHAPE DARWING WITH MOUSEDRAG !
if (figures == EnumRope.ERASER) {
addEraser(ErasRect, Color.WHITE, thickness);
ErasRect = null;
}else if (figures == EnumRope.PENCIL) {
addPencil(ErasRect, currentColor, thickness);
ErasRect = null;
}
}
// GETTING RELEASED COORDINATE TO DRAW SHAPES BECAUSE SOME SHAPES GETTED
//COORDINATES FROM MOUSEDRAGGED, IF YOU ADD THE SHAPE TO IMAGE IN MOUSEDRAGGED
//SHAPE WILL BE NESTED( more nested shapes from small to big). SO ADD ALL
//COORDINATES WHEN MOUSE RELEASED.
@Override
public void mouseReleased(MouseEvent e) {
if (figures == EnumRope.OVAL) {
addEllipse(ellipse2d, currentColor, thickness);
ellipse2d = null;
} else if (figures == EnumRope.FILLEDOVAL) {
addEllipse(ellipse2d, currentColor, thickness);
ellipse2d = null;
} else if (figures == EnumRope.RECT) {
addRectangle(rectangle, currentColor, thickness);
rectangle = null;
} else if (figures == EnumRope.FILLEDRECT) {
addRectangle(rectangle, currentColor, thickness);
rectangle = null;
} else if (figures == EnumRope.LINE) {
addLine(line2d, currentColor, thickness);
line2d = null;
}
}
}
I hope to this answer benefit to others.