Skip to content

Instantly share code, notes, and snippets.

@Hirunagrad
Created May 24, 2023 19:55
Show Gist options
  • Save Hirunagrad/db09ecbec0737a5936bb889b2eeb9f35 to your computer and use it in GitHub Desktop.
Save Hirunagrad/db09ecbec0737a5936bb889b2eeb9f35 to your computer and use it in GitHub Desktop.
package paint.canvas;
import paint.model.DrawType;
import paint.model.PaintInfo;
import javax.swing.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import java.io.Serializable;
import java.util.ArrayList;
public class GlassPanel extends JPanel implements MouseListener, MouseMotionListener, Serializable {
private final ArrayList<PaintInfo> drawHistory;
private final PaintInfo drawInfo;
private PaintCanvas canvas;
public GlassPanel(ArrayList<PaintInfo> drawHistory, PaintInfo drawInfo, PaintCanvas canvas) {
super();
this.setOpaque(false);
this.drawInfo = drawInfo;
this.drawHistory = drawHistory;
this.canvas = canvas;
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void setTargetCanvas(PaintCanvas canvas) {
this.canvas = canvas;
}
@Override
public void setVisible(boolean flag) {
super.setVisible(flag);
if (flag) this.getParent().setComponentZOrder(this, 0);
}
@Override
public void mouseClicked(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseMoved(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
drawInfo.clickState = true;
drawInfo.end = drawInfo.start = e.getPoint();
drawInfo.dragState = true;
}
@Override
public void mouseReleased(MouseEvent e) {
drawInfo.end = e.getPoint();
if (drawInfo.dragState) {
drawInfo.dragState = false;
if (drawInfo.type == DrawType.Pen || drawInfo.type == DrawType.Line) {
canvas.paintShape(canvas.getBufferGraphics());
} else {
if (drawInfo.start.x > drawInfo.end.x) {
int tmp = drawInfo.end.x;
drawInfo.end.x = drawInfo.start.x;
drawInfo.start.x = tmp;
}
if (drawInfo.start.y > drawInfo.end.y) {
int tmp = drawInfo.end.y;
drawInfo.end.y = drawInfo.start.y;
drawInfo.start.y = tmp;
}
PaintInfo tmp = new PaintInfo(drawInfo);
drawHistory.add(tmp);
ObjectiveShape Shape = new ObjectiveShape(tmp, canvas.getResizePanel());
Shape.setLocation(drawInfo.start.x - (int) (drawInfo.stroke.getLineWidth() + 0.5),
drawInfo.start.y - (int) (drawInfo.stroke.getLineWidth() + 0.5));
canvas.add(Shape);
canvas.setComponentZOrder(Shape, 0);
}
}
drawInfo.clickState = false;
}
@Override
public void mouseDragged(MouseEvent e) {
if (drawInfo.type == DrawType.Pen) {
drawInfo.start = drawInfo.end;
}
drawInfo.end = e.getPoint();
drawInfo.dragState = true;
canvas.repaint();
}
}
package paint.canvas;
import paint.canvas.resize.ResizePanel;
import paint.model.PaintInfo;
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.Serializable;
public class ObjectiveShape extends JComponent implements Serializable {
private final PaintInfo drawInfo;
private final ResizePanel resizePanel;
private Point anchorPoint;
private int strokeWidth = 0;
public ObjectiveShape(PaintInfo drawInfo, ResizePanel resizePanel) {
super();
this.resizePanel = resizePanel;
this.drawInfo = drawInfo;
this.addDragListeners();
this.setOpaque(false);
strokeWidth = (int) (drawInfo.stroke.getLineWidth() + 0.5);
this.setSize(drawInfo.end.x - drawInfo.start.x + 2 * strokeWidth,
drawInfo.end.y - drawInfo.start.y + 2 * strokeWidth);
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(drawInfo.color);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(drawInfo.stroke);
strokeWidth = (int) (drawInfo.stroke.getLineWidth() + 0.5);
switch (drawInfo.type) {
case Rect:
if (drawInfo.fill) {
if (drawInfo.color != drawInfo.innerColor) g.setColor(drawInfo.innerColor);
g.fillRect(strokeWidth, strokeWidth,
getWidth() - 2 * strokeWidth,
getHeight() - 2 * strokeWidth);
}
g.setColor(drawInfo.color);
g.drawRect(strokeWidth, strokeWidth,
getWidth() - 2 * strokeWidth,
getHeight() - 2 * strokeWidth);
break;
case Oval:
if (drawInfo.fill) {
if (drawInfo.color != drawInfo.innerColor) g.setColor(drawInfo.innerColor);
g.fillOval(strokeWidth, strokeWidth,
getWidth() - 2 * strokeWidth,
getHeight() - 2 * strokeWidth);
}
g.setColor(drawInfo.color);
g.drawOval(strokeWidth, strokeWidth,
getWidth() - 2 * strokeWidth,
getHeight() - 2 * strokeWidth);
break;
case RoundRect:
if (drawInfo.fill) {
if (drawInfo.color != drawInfo.innerColor) g.setColor(drawInfo.innerColor);
g.fillRoundRect(strokeWidth, strokeWidth,
getWidth() - 2 * strokeWidth,
getHeight() - 2 * strokeWidth, 50, 50);
}
g.setColor(drawInfo.color);
g.drawRoundRect(strokeWidth, strokeWidth,
getWidth() - 2 * strokeWidth,
getHeight() - 2 * strokeWidth, 50, 50);
break;
default:
System.exit(1);
break;
}
}
private void addDragListeners() {
final ObjectiveShape handle = this;
addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
resizePanel.setTarget(handle);
resizePanel.setVisible(true);
resizePanel.setPreferredSize(new Dimension(getWidth(), getHeight()));
resizePanel.setLocation(handle.getLocation());
anchorPoint = e.getPoint();
setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
getParent().setComponentZOrder(handle, 0);
}
@Override
public void mouseReleased(MouseEvent e) {
setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
}
});
addMouseMotionListener(new MouseAdapter() {
@Override
public void mouseDragged(MouseEvent e) {
resizePanel.setLocation(handle.getLocation().x - 7, handle.getLocation().y - 7);
int anchorX = anchorPoint.x;
int anchorY = anchorPoint.y;
Point parentOnScreen = getParent().getLocationOnScreen();
Point mouseOnScreen = e.getLocationOnScreen();
Point position = new Point(mouseOnScreen.x - parentOnScreen.x
- anchorX, mouseOnScreen.y - parentOnScreen.y - anchorY);
setLocation(position);
drawInfo.start = position;
drawInfo.end.x = position.x + getWidth();
drawInfo.end.y = position.y + getHeight();
}
});
}
public PaintInfo getDrawInfo() {
return drawInfo;
}
}
package paint.canvas;
import paint.canvas.resize.ResizePanel;
import paint.model.DrawType;
import paint.model.PaintInfo;
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.Serializable;
public class PaintCanvas extends JPanel implements Serializable {
private final ResizePanel resizePanel;
private final PaintInfo drawInfo;
private BufferedImage bufferImage = null;
private Graphics2D bufferGraphics = null;
private int prevWidth = 400;
private int prevHeight = 400;
public PaintCanvas(PaintInfo drawInfo, ResizePanel resizePanel) {
super();
//this.setPreferredSize(new Dimension(prevWidth, prevHeight));
this.setSize(prevWidth, prevHeight);
this.drawInfo = drawInfo;
this.setLayout(null);
this.resizePanel = resizePanel;
this.setOpaque(false);
this.setBackground(Color.WHITE);
}
public Graphics2D getBufferGraphics() {
return this.bufferGraphics;
}
public ResizePanel getResizePanel() {
return this.resizePanel;
}
@Override
public boolean isOptimizedDrawingEnabled() {
return false;
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawRect(10, 10, 50, 50);
Graphics2D g2 = (Graphics2D) g;
int width = this.getWidth();
int height = this.getHeight();
if (width != prevWidth || height != prevHeight) {
BufferedImage tmp = bufferImage;
bufferImage = (BufferedImage) this.createImage(width, height);
bufferGraphics = (Graphics2D) bufferImage.getGraphics();
bufferGraphics.drawImage(tmp, null, 0, 0);
tmp = null;
prevWidth = width;
prevHeight = height;
}
g2.drawImage(bufferImage, null, 0, 0);
if (drawInfo.clickState) {
if (drawInfo.type == DrawType.Pen) paintShape(bufferGraphics);
else if (drawInfo.dragState) paintShape(g);
}
}
public void paintShape(Graphics g) {
g.setColor(drawInfo.color);
Graphics2D g2 = (Graphics2D) g;
g2.setStroke(drawInfo.stroke);
int startX = Math.min(drawInfo.start.x, drawInfo.end.x);
int startY = Math.min(drawInfo.start.y, drawInfo.end.y);
int width = Math.abs(drawInfo.end.x - drawInfo.start.x);
int height = Math.abs(drawInfo.end.y - drawInfo.start.y);
switch (drawInfo.type) {
case Rect:
if (drawInfo.fill) {
if (drawInfo.color != drawInfo.innerColor) g.setColor(drawInfo.innerColor);
g.fillRect(startX, startY, width, height);
}
g.setColor(drawInfo.color);
g.drawRect(startX, startY, width, height);
break;
case Oval:
if (drawInfo.fill) {
if (drawInfo.color != drawInfo.innerColor) g.setColor(drawInfo.innerColor);
g.fillOval(startX, startY, width, height);
}
g.setColor(drawInfo.color);
g.drawOval(startX, startY, width, height);
break;
case RoundRect:
if (drawInfo.fill) {
if (drawInfo.color != drawInfo.innerColor) g.setColor(drawInfo.innerColor);
g.fillRoundRect(startX, startY,
width,
height, 10, 10);
}
g.setColor(drawInfo.color);
g.drawRoundRect(startX, startY,
width,
height, 50, 50);
break;
case Pen:
case Line:
g.drawLine(drawInfo.start.x, drawInfo.start.y, drawInfo.end.x, drawInfo.end.y);
break;
default:
System.exit(1);
break;
}
}
}
package paint.canvas;
import paint.canvas.resize.ResizePanel;
import paint.model.PaintInfo;
import javax.swing.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.Serializable;
import java.util.ArrayList;
public class PaintFrame extends JInternalFrame implements Serializable {
private final ResizePanel resizePanel;
private final PaintCanvas canvas;
private final PaintInfo drawInfo;
private final GlassPanel glass;
private final JPanel overlay;
private final ArrayList<PaintInfo> drawHistory;
private final ArrayList<PaintCanvas> layout = new ArrayList<PaintCanvas>();
public PaintFrame(ArrayList<PaintInfo> drawHistory, PaintInfo drawInfo, int width, int height) {
super("New Image", true, true, true, true);
this.drawHistory = drawHistory;
overlay = new JPanel() {
public boolean isOptimizedDrawingEnabled() {
return false;
}
};
overlay.setOpaque(false);
overlay.setLayout(new OverlayLayout(overlay));
//overlay.setPreferredSize(new Dimension(width, height));
//this.getContentPane().setLayout(null);
//this.add(overlay, BorderLayout.CENTER);
this.setContentPane(overlay);
//this.getContentPane().setLayout(null);
//layer = this.getLayeredPane();
//layer.setOpaque(false);
this.drawInfo = drawInfo;
resizePanel = new ResizePanel();
canvas = new PaintCanvas(drawInfo, resizePanel);
glass = new GlassPanel(drawHistory, drawInfo, canvas);
resizePanel.setVisible(false);
this.addMouseListener(new MouseAdapter() {
@Override
public void mousePressed(MouseEvent e) {
if (resizePanel.isVisible()) {
resizePanel.setVisible(false);
}
}
});
layout.add(canvas);
this.add(canvas);
canvas.setSize(width, height);
JButton btn = new JButton("a");
btn.setBounds(10, 10, 60, 60);
canvas.add(btn);
this.setGlassPane(glass);
this.setVisible(true);
this.getContentPane().setComponentZOrder(resizePanel, 0);
}
public void disableResizePane() {
resizePanel.setVisible(false);
}
public ArrayList<PaintCanvas> getLayoutList() {
return layout;
}
public void setTargetCanvas(int index) {
glass.setTargetCanvas(layout.get(index));
this.getContentPane().setComponentZOrder(layout.get(index), 1);
}
public void addLayout() {
PaintCanvas newCanvas = new PaintCanvas(drawInfo, resizePanel);
layout.add(newCanvas);
JButton btn = new JButton("b");
btn.setBounds(30, 30, 60, 60);
newCanvas.add(btn);
this.add(newCanvas);
newCanvas.setVisible(true);
//newCanvas.setSize(400, 400);
}
public void repaintAll() {
for (PaintInfo aDrawHistory : this.drawHistory) {
ObjectiveShape Shape = new ObjectiveShape(aDrawHistory, resizePanel);
Shape.setLocation(aDrawHistory.start.x - (int) (aDrawHistory.stroke.getLineWidth() + 0.5),
aDrawHistory.start.y - (int) (aDrawHistory.stroke.getLineWidth() + 0.5));
canvas.add(Shape);
canvas.setComponentZOrder(Shape, 0);
}
}
}
package paint.canvas.resize;
import java.awt.Graphics;
import java.awt.Rectangle;
import javax.swing.JComponent;
import paint.canvas.ObjectiveShape;
public class ResizePanel extends JComponent {
private ResizeButton NW = new ResizeNW(), NE = new ResizeNE(), N = new ResizeN(),
SW = new ResizeSW(), SE = new ResizeSE(), S = new ResizeS(), W = new ResizeW(), E = new ResizeE();
private ObjectiveShape Shape;
public ResizePanel() {
this.setLayout(null);
this.setOpaque(false);
this.add(SE);
this.add(E);
this.add(S);
this.add(NW);
this.add(NE);
this.add(N);
this.add(SW);
this.add(W);
}
public void setTarget(ObjectiveShape target) {
Shape = target;
SE.setTarget(target);
E.setTarget(target);
S.setTarget(target);
NW.setTarget(target);
NE.setTarget(target);
N.setTarget(target);
SW.setTarget(target);
W.setTarget(target);
this.repaint();
}
@Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Rectangle tmpShape = Shape.getBounds();
tmpShape.width += NW.getWidth() - 2;
tmpShape.height += NW.getHeight() - 2;
tmpShape.x -= NW.getWidth()/2 - 1;
tmpShape.y -= NW.getHeight()/2 - 1;
this.setBounds(tmpShape);
NW.setLocation(0, 0);
W.setLocation(0, getHeight()/2 - W.getHeight()/2);
SW.setLocation(0, getHeight() - SW.getHeight());
N.setLocation(getWidth()/2 - N.getWidth()/2, 0);
S.setLocation(getWidth()/2 - S.getWidth()/2,
getHeight() - S.getHeight());
NE.setLocation(getWidth() - NE.getWidth(), 0);
E.setLocation(getWidth() - E.getWidth(),
getHeight()/2 - E.getHeight()/2);
SE.setLocation(getWidth() - SE.getWidth(),
getHeight() - SE.getHeight());
}
}
@Hirunagrad
Copy link
Author

  1. GlassPanel- Jayath
  2. ObjctiveShape - Zuvi
  3. PaintCanvas -Avishka
  4. PainFrame - Hela
  5. ResizePanel - Prineth

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment