I made a paint application. And need your help to solve a problem. As you can see this code draws the shapes again and again when paint event is called. When there is many shapes, the preview rectangle feature becomes slow and doesn't work smoothly. Is there any way to draw shapes only when mouse pressing and releasing? When I tried shapes began to disappear while mouse dragging and appears when mouse Released.
Here is Essential code:
private class drawer extends JComponent{
ArrayList<Shape> shapes = new ArrayList<Shape>();
ArrayList<Color> fillcolo = new ArrayList<Color>();
ArrayList<Color> strokecolo = new ArrayList<Color>();
Point drawst, drawend;
public drawer(){
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
drawst = new Point(e.getX(), e.getY());
drawend = drawst;
if(currentaction == 0){
ArrayList<Shape> availables = new ArrayList<Shape>();
for(Shape s : shapes){
if(s.contains(drawst)){
availables.add(s);
}
}
if(!availables.isEmpty()){
int tmpindex = shapes.indexOf(availables.get(availables.size() -1));
shapes.remove(tmpindex);
fillcolo.remove(tmpindex);
strokecolo.remove(tmpindex);
}
}
flowthrough = true;
repaint();
}
public void mouseReleased(MouseEvent e){
switch (currentaction){
case 0:
break;
case 1:
break;
case 4:
Shape shape01 = drawellipse(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape01);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
case 3:
Shape shape = drawrect(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
}
drawst = null; drawend = null;
flowthrough = true;
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
drawend = new Point(e.getX(), e.getY());
repaint();
}
}
);
}
public void paint(Graphics g){
Graphics2D graph = (Graphics2D)g;
graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
graph.setStroke(new BasicStroke(2));
if(flowthrough){
Iterator<Color> strokecounter = strokecolo.iterator();
Iterator<Color> fillcounter = fillcolo.iterator();
for(Shape s : shapes){
graph.setPaint(strokecounter.next());
graph.draw(s);
graph.setPaint(fillcounter.next());
graph.fill(s);
}
}
if(drawst != null && drawend != null){
switch (currentaction){
case 4:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape bshape = drawellipse(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(bshape);
break;
case 3:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape ashape = drawrect(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(ashape);
break;
}
}
}
private Rectangle2D.Float drawrect(int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x1-x2);
int height = Math.abs(y1-y2);
return new Rectangle2D.Float(x,y,width,height);
}
private Ellipse2D.Float drawellipse(int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int width = Math.abs(x1 - x2);
int height = Math.abs(y1 - y2);
return new Ellipse2D.Float(x,y,width,height);
}
}
Here is full code(I minimized it a bit):
public class Basics extends JFrame {
JButton brushbut, shapebut, linebut, strokecolbut, fillcolbut;
int currentaction = 1;
int strokesize = 2;
boolean flowthrough = false;
Color strokecol = Color.black, fillcol = Color.darkGray;
public Basics(){
this.setBounds(new Rectangle(50,50,1000,600));
this.setTitle("Dandle");
JPanel buttonpanel = new JPanel();
Box thebox = Box.createHorizontalBox();
brushbut = makebutton("/home/kamal/Pictures/brushicon(sized).png", 4);
shapebut = makebutton("/home/kamal/Pictures/shapeicon(sized).png", 3);
linebut = makebutton("/home/kamal/Pictures/vector-path-lineicon(sized).png",0);
strokecolbut = makebutton("/home/kamal/Pictures/strokecolor(sized).png", true);
fillcolbut = makebutton("/home/kamal/Pictures/fill-coloricon(sized).png", false);
thebox.add(brushbut);
........
buttonpanel.add(thebox);
this.add(buttonpanel, BorderLayout.SOUTH);
this.add(new drawer(), BorderLayout.CENTER);
}
private JButton makebutton(String icon, final int num){
JButton thebut = new JButton();
........
thebut.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
currentaction = num;
}
});
return thebut;
}
private JButton makebutton(String icon, final boolean stroke){
JButton thebut = new JButton();
thebut.setIcon(new ImageIcon(icon));
thebut.setSize(50,50);
thebut.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e){
if(stroke) strokecol = JColorChooser.showDialog(null, "Pick a stroke", strokecol);
..........
}
});
return thebut;
}
public static void main(String[] args){
new Basics().setVisible(true);
}
private class drawer extends JComponent{
ArrayList<Shape> shapes = new ArrayList<Shape>();
ArrayList<Color> fillcolo = new ArrayList<Color>();
ArrayList<Color> strokecolo = new ArrayList<Color>();
Point drawst, drawend;
public drawer(){
this.addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
drawst = new Point(e.getX(), e.getY());
drawend = drawst;
if(currentaction == 0){
ArrayList<Shape> availables = new ArrayList<Shape>();
for(Shape s : shapes){
if(s.contains(drawst)){
availables.add(s);
}
}
if(!availables.isEmpty()){
int tmpindex = shapes.indexOf(availables.get(availables.size() -1));
shapes.remove(tmpindex);
fillcolo.remove(tmpindex);
strokecolo.remove(tmpindex);
}
}
flowthrough = true;
repaint();
}
public void mouseReleased(MouseEvent e){
switch (currentaction){
case 0:
break;
case 1:
break;
case 4:
Shape shape01 = drawellipse(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape01);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
case 3:
Shape shape = drawrect(drawst.x,drawst.y,e.getX(),e.getY());
shapes.add(shape);
fillcolo.add(fillcol);
strokecolo.add(strokecol);
break;
}
drawst = null; drawend = null;
flowthrough = true;
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
drawend = new Point(e.getX(), e.getY());
repaint();
}
}
);
}
public void paint(Graphics g){
Graphics2D graph = (Graphics2D)g;
graph.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f));
graph.setStroke(new BasicStroke(2));
if(flowthrough){
Iterator<Color> strokecounter = strokecolo.iterator();
Iterator<Color> fillcounter = fillcolo.iterator();
for(Shape s : shapes){
graph.setPaint(strokecounter.next());
graph.draw(s);
graph.setPaint(fillcounter.next());
graph.fill(s);
}
}
if(drawst != null && drawend != null){
switch (currentaction){
case 4:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape bshape = drawellipse(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(bshape);
break;
case 3:
graph.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.40f));
graph.setPaint(Color.LIGHT_GRAY);
Shape ashape = drawrect(drawst.x, drawst.y, drawend.x, drawend.y);
graph.draw(ashape);
break;
}
}
}
private Rectangle2D.Float drawrect(int x1, int y1, int x2, int y2){
..........
return new Rectangle2D.Float(x,y,width,height);
}
private Ellipse2D.Float drawellipse(int x1, int y1, int x2, int y2){
..........
return new Ellipse2D.Float(x,y,width,height);
}
}
}
Related
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.util.List;
import java.util.ArrayList;
class DrawningBoard extends Canvas implements MouseMotionListener{
private List<Point> points = new ArrayList<>();
private List<List<Point>> curves = new ArrayList<>();
private boolean isRectangle = false;
private int xr, yr, widthr, heightr;
public void setIsRectangle(boolean trueOrFalse){
isRectangle = trueOrFalse;
}
public boolean getIsRectangle(){
return isRectangle;
}
public DrawningBoard(){
setBackground(Color.MAGENTA);
addMouseMotionListener(this);
addMouseListener(new MouseAdapter(){
public void mouseReleased(MouseEvent e){
curves.add(points);
points = new ArrayList<>();
}
public void mousePressed(MouseEvent e){
points.add(new Point(e.getX(), e.getY()));
}
});
}
public void paint(Graphics g){
g.setColor(Color.CYAN);
if(isRectangle){
g.drawRect(xr, yr, widthr, heightr);
}
for(List<Point> curve : curves){
for(int i = 0; i < curve.size() - 1; i++){
g.drawLine((int)curve.get(i).getX(), (int)curve.get(i).getY(), (int)curve.get(i + 1).getX(), (int)curve.get(i + 1).getY());
}
}
}
public void mouseDragged(MouseEvent e){
Graphics g = getGraphics();
g.setColor(Color.CYAN);
int xx = e.getX();
int yy = e.getY();
int x = (int)points.get(points.size() - 1).getX();
int y = (int)points.get(points.size() - 1).getY();
int dx = xx-x;
int dy = yy-y;
if(isRectangle){
if(dx >= 0 && dy >= 0){
xr = x;
yr = y;
widthr = dx;
heightr = dy;
} else if(dx < 0 && dy < 0){
xr = xx;
yr = yy;
widthr = -dx;
heightr = -dy;
} else if(dx >= 0 && dy < 0){
xr = x;
yr = yy;
widthr = dx;
heightr = -dy;
} else if(dx < 0 && dy >= 0){
xr = xx;
yr = y;
widthr = -dx;
heightr = dy;
}
repaint();
}
else {
g.drawLine(xx, yy, (int)points.get(points.size() - 1).getX(), (int)points.get(points.size() - 1).getY());
points.add(new Point(xx, yy));
}
}
public void mouseMoved(MouseEvent e) { }
}
class GUI extends JFrame implements ActionListener{
private JPanel[] panel;
private JButton[] button;
private DrawningBoard board;
public GUI(String title){
super(title);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setSize(416, 400);
board = new DrawningBoard();
board.setBounds(0,0, 400, 400);
panel = new JPanel[3];
panel[0] = new JPanel();
panel[1] = new JPanel();
panel[2] = new JPanel();
panel[0].setLayout(null);
panel[1].setLayout(null);
panel[2].setLayout(null);
panel[0].setBounds(0, 0, 400, 20);
panel[1].setBounds(0, 20, 400, 400);
panel[2].add(panel[0]);
panel[2].add(panel[1]);
panel[0].setBackground(Color.red);
button = new JButton[5];
button[0] = new JButton("Rectangle");
button[1] = new JButton("b1");
button[2] = new JButton("b2");
button[3] = new JButton("b3");
button[4] = new JButton("b4");
button[0].addActionListener(this);
button[3].addActionListener(this);
button[0].setBounds(0, 0, 100, 20);
button[1].setBounds(100, 0, 100, 20);
button[2].setBounds(200, 0, 100, 20);
button[3].setBounds(300, 0, 100, 20);
button[4].setBounds(0, 0, 100, 20);
panel[0].add(button[0]);
panel[0].add(button[1]);
panel[0].add(button[2]);
panel[0].add(button[3]);
panel[0].add(button[4]);
panel[1].add(board);
add(panel[2]);
show();
}
public void actionPerformed(ActionEvent e){
String command = e.getActionCommand();
if(command.equals("Rectangle"))
board.setIsRectangle(!board.getIsRectangle());
}
}
public class Paint{
public static void main(String []str){
new GUI("Paint");
}
}
I want to create a Paint application. If I draw multiple curves on the board and then I want to draw a rectangle (using drawRect(x, y, width, height)), those curves are repainted and results some flushing as result of use repaint() method. How can I avoid that flushing?
I tried to use update() method, but many rectangles are drawn when mouse dragging.
Swing is double buffered by default.
public void paint(Graphics g){
Don't override paint(). You have done this incorrectly and have lost the benefit of double buffering.
Instead, custom painting should be done by overriding the paintComponent(...) method. Read the section from the Swing tutorial on Custom Painting for more information and working examples.
You can also check out the DrawOnComponent example from Custom Painting Approaches for a more complete example that does what you want.
I am new to Java, as for my class's final project, I am developing a paint application that enables users to draw rich curved lines and common geometric shapes like rectangle and oval, also users can undo their shape drawing.
My app worked well on shape drawing. When I want to draw shapes, the shapes I want to draw are stored in the LinkedList which will be called to draw shapes on the screen When I applied this LinkedList concept to draw curved lines on the screen. I modified shape drawing code to draw curved lines. I ran to a problem; The result I got was little dots on the screen. If I tried to copy similar code that draws shapes for drawing curved lines, I would get straight lines instead of the curved lines.
I think this problem is related to MouseListener interfaces. I need some suggestions on how can I modify my MouseListener methods so that I can draw the curved lines on the screen properly.
Changes to my source code are welcome:
import java.util.*;
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class PaintAppPlusSecondDraft extends JApplet implements ActionListener {
private static final long serialVersionUID = 1L;
private JMenuBar menuBar = new JMenuBar();
private JMenu mainMenu = new JMenu("Main menu");
private JMenuItem howToUse = new JMenuItem("How to use?");
private JMenuItem toDefaultMode = new JMenuItem("Return to default mode");
private JMenu boardSettings = new JMenu("Paint board settings");
private JMenuItem clearBoard = new JMenuItem("Clear screen");
private JMenuItem toDefaultBoard = new JMenuItem("Set to default paint board");
private JMenuItem bCustom = new JMenuItem("Set background colour");
private JMenu brushSettings = new JMenu("Paintbrush settings");
private JMenuItem eraser = new JMenuItem("Eraser");
private JMenuItem toDefaultBrush = new JMenuItem("Set to default paintbrush");
private JMenu setBrushSize = new JMenu("Set paintbrush size");
private JMenuItem Two = new JMenuItem("2 pixels");
private JMenuItem Four = new JMenuItem("4 pixels");
private JMenuItem Six = new JMenuItem("6 pixels");
private JMenuItem Eight = new JMenuItem("8 pixels");
private JMenuItem Ten = new JMenuItem("10 pixels");
private JMenu setBrushType = new JMenu("Set paintbrush type");
private JMenuItem defaultType1 = new JMenuItem("Default");
private JMenuItem defaultType2 = new JMenuItem("Default (light stroke)");
private JMenuItem Custom = new JMenuItem("Set paintbrush colour");
private JMenu drawShapes = new JMenu("Draw shapes");
private JMenuItem undoShape = new JMenuItem("Undo shape drawing");
private JMenuItem StraightLine = new JMenuItem("Straight line");
private JMenuItem Rectangle = new JMenuItem("Rectangle");
private JMenuItem Oval = new JMenuItem("Oval");
private JMenuItem filledRectangle = new JMenuItem("Filled rectangle");
private JMenuItem filledOval = new JMenuItem("Filled oval");
private int prevBrushSize = PaintBoard.brushSize;
private int prevBrushType = PaintBoard.brushType;
private Color prevBrushColour = PaintBoard.currentColour; /* For better user experience */
public void init() {
Frame frame = (Frame) getParent().getParent();
frame.setTitle("JAVA Paint plus");
frame.setResizable(false);
this.setSize(600, 400);
this.setContentPane(new PaintBoard());
mainMenu.add(howToUse);
mainMenu.add(toDefaultMode);
mainMenu.add(about);
boardSettings.add(clearBoard);
boardSettings.add(toDefaultBoard);
boardSettings.add(bCustom);
brushSettings.add(eraser);
brushSettings.add(toDefaultBrush);
setBrushSize.add(Two);
setBrushSize.add(Four);
setBrushSize.add(Six);
setBrushSize.add(Eight);
setBrushSize.add(Ten);
brushSettings.add(setBrushSize);
setBrushType.add(defaultType1);
setBrushType.add(defaultType2);
setBrushType.add(waterColourBrush);
setBrushType.add(triangleType);
setBrushType.add(squareType);
setBrushType.add(hexagonType);
setBrushType.add(starType);
setBrushType.add(heartType);
brushSettings.add(setBrushType);
brushSettings.add(Custom);
drawShapes.add(undoShape);
drawShapes.add(StraightLine);
drawShapes.add(Rectangle);
drawShapes.add(Oval);
drawShapes.add(filledRectangle);
drawShapes.add(filledOval);
menuBar.add(mainMenu);
menuBar.add(boardSettings);
menuBar.add(brushSettings);
menuBar.add(drawShapes);
howToUse.addActionListener(this);
toDefaultMode.addActionListener(this);
clearBoard.addActionListener(this);
toDefaultBoard.addActionListener(this);
bCustom.addActionListener(this);
eraser.addActionListener(this);
toDefaultBrush.addActionListener(this);
Two.addActionListener(this);
Four.addActionListener(this);
Six.addActionListener(this);
Eight.addActionListener(this);
Ten.addActionListener(this);
defaultType1.addActionListener(this);
defaultType2.addActionListener(this);
Custom.addActionListener(this);
undoShape.addActionListener(this);
StraightLine.addActionListener(this);
Rectangle.addActionListener(this);
Oval.addActionListener(this);
filledRectangle.addActionListener(this);
filledOval.addActionListener(this);
this.setJMenuBar(menuBar);
this.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == howToUse) {
JOptionPane.showMessageDialog(null, "Press your mouse on the board and drag to draw!", "How to use?", JOptionPane.INFORMATION_MESSAGE);
}
if (e.getSource() == toDefaultMode) {
PaintBoard.canvasColour = Color.WHITE;
PaintBoard.brushSize = prevBrushSize = 6;
PaintBoard.brushType = prevBrushType = 1;
PaintBoard.currentColour = prevBrushColour = Color.BLACK;
PaintBoard.shapes.makeEmpty();
repaint();
}
if (e.getSource() == clearBoard) {
PaintBoard.shapes.makeEmpty();
repaint();
}
if (e.getSource() == toDefaultBoard) {
PaintBoard.canvasColour = Color.WHITE;
repaint();
}
if (e.getSource() == bCustom) {
try {
Color customColour = JColorChooser.showDialog(null, "Select colour:", PaintBoard.canvasColour);
PaintBoard.canvasColour = customColour;
PaintBoard.shapes.makeEmpty();
repaint();
} catch (NullPointerException ex) {
}
}
if (e.getSource() == eraser) {
prevBrushSize = PaintBoard.brushSize;
prevBrushType = PaintBoard.brushType;
prevBrushColour = PaintBoard.currentColour;
PaintBoard.brushSize = 44;
PaintBoard.brushType = 1;
PaintBoard.currentColour = PaintBoard.canvasColour;
}
if (e.getSource() == toDefaultBrush) {
PaintBoard.brushSize = prevBrushSize = 6;
PaintBoard.brushType = prevBrushType = 1;
PaintBoard.currentColour = prevBrushColour = Color.BLACK;
}
if (e.getSource() == Two) {
PaintBoard.brushSize = prevBrushSize = 2;
PaintBoard.brushType = prevBrushType;
PaintBoard.currentColour = prevBrushColour;
}
if (e.getSource() == Four) {
PaintBoard.brushSize = prevBrushSize = 4;
PaintBoard.brushType = prevBrushType;
PaintBoard.currentColour = prevBrushColour;
}
if (e.getSource() == Six) {
PaintBoard.brushSize = prevBrushSize = 6;
PaintBoard.brushType = prevBrushType;
PaintBoard.currentColour = prevBrushColour;
}
if (e.getSource() == Eight) {
PaintBoard.brushSize = prevBrushSize = 8;
PaintBoard.brushType = prevBrushType;
PaintBoard.currentColour = prevBrushColour;
}
if (e.getSource() == Ten) {
PaintBoard.brushSize = prevBrushSize = 10;
PaintBoard.brushType = prevBrushType;
PaintBoard.currentColour = prevBrushColour;
}
if (e.getSource() == defaultType1) {
PaintBoard.brushSize = prevBrushSize;
PaintBoard.brushType = prevBrushType = 1;
PaintBoard.currentColour = prevBrushColour;
}
if (e.getSource() == defaultType2) {
PaintBoard.brushSize = prevBrushSize;
PaintBoard.brushType = prevBrushType = 2;
PaintBoard.currentColour = prevBrushColour;
}
if (e.getSource() == Custom) {
try {
Color customColour = JColorChooser.showDialog(null, "Select colour:", PaintBoard.currentColour);
PaintBoard.brushSize = prevBrushSize;
PaintBoard.brushType = prevBrushType;
PaintBoard.currentColour = prevBrushColour = customColour;
} catch (NullPointerException ex) {
}
}
if (e.getSource() == undoShape) {
try {
PaintBoard.shapes.removeFront();
repaint();
} catch (NullPointerException ex) {
}
}
if (e.getSource() == StraightLine) {
PaintBoard.brushSize = prevBrushSize;
PaintBoard.currentColour = prevBrushColour;
PaintBoard.shapeType = 1;
}
if (e.getSource() == Rectangle) {
PaintBoard.currentColour = prevBrushColour;
PaintBoard.shapeType = 2;
PaintBoard.filled = false;
}
if (e.getSource() == Oval) {
PaintBoard.currentColour = prevBrushColour;
PaintBoard.shapeType = 3;
PaintBoard.filled = false;
}
if (e.getSource() == filledRectangle) {
PaintBoard.currentColour = prevBrushColour;
PaintBoard.shapeType = 2;
PaintBoard.filled = true;
}
if (e.getSource() == filledOval) {
PaintBoard.currentColour = prevBrushColour;
PaintBoard.shapeType = 3;
PaintBoard.filled = true;
}
}
abstract static class brushLine {
private int brushSize;
private int brushType;
private Color brushColour;
public brushLine() {
brushSize = 6;
brushType = 1;
brushColour = Color.BLACK;
}
public brushLine(int brushSize, int brushType, Color brushColour) {
this.brushSize = brushSize;
this.brushType = brushType;
this.brushColour = brushColour;
}
public void setBrushSize(int brushSize) {
this.brushSize = brushSize;
}
public void setBrushType(int brushType) {
this.brushType = brushType;
}
public void setBrushColour(Color brushColour) {
this.brushColour = brushColour;
}
public int getBrushSize() {
return brushSize;
}
public int getBrushType() {
return brushType;
}
public Color getBrushColour() {
return brushColour;
}
abstract void show(Graphics window);
}
static class paintBrushLine extends brushLine {
private int x1, y1, x2, y2;
public paintBrushLine() {
super();
x1 = 0;
y1 = 0;
x2 = 0;
y2 = 0;
}
public paintBrushLine(int brushSize, int brushType, Color brushColour, int x1, int y1, int x2, int y2) {
super(brushSize, brushType, brushColour);
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
public void setX1(int x1) {
this.x1 = x1;
}
public void setY1(int y1) {
this.y1 = y1;
}
public void setX2(int x2) {
this.x2 = x2;
}
public void setY2(int y2) {
this.y2 = y2;
}
public int getX1() {
return x1;
}
public int getY1() {
return y1;
}
public int getX2() {
return x2;
}
public int getY2() {
return y2;
}
public void show(Graphics window) {
window.setColor(getBrushColour());
switch (getBrushType()) {
case 1://Default brush
((Graphics2D) window).setStroke(new BasicStroke(getBrushSize(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
window.drawLine(getX1(), getY1(), getX2(), getY2());
break;
case 2://Default brush (light stroke) --> Makes empty squares with few randomly positioned pixels
int[] pixelPos = new int[2];
for (int i = 0; i < ((getBrushSize()*getBrushSize()) / 10); i++) {
pixelPos[0] = new Random().nextInt(getBrushSize());
pixelPos[1] = new Random().nextInt(getBrushSize());
window.drawRect(getX1() + pixelPos[0], getY1() + pixelPos[1], 1, 1);
}
break;
}
}
}
abstract static class Shape {
private int x1, y1, x2, y2;
private int thickness;
private Color shapeColour;
public Shape() {
x1 = 0;
y1 = 0;
x2 = 0;
y2 = 0;
shapeColour = Color.BLACK;
}
public Shape(int x1, int y1, int x2, int y2, int thickness, Color shapeColour)
{
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
this.thickness = thickness;
this.shapeColour = shapeColour;
}
public void setX1(int x1) {
this.x1 = x1;
}
public void setY1(int y1) {
this.y1 = y1;
}
public void setX2(int x2) {
this.x2 = x2;
}
public void setY2(int y2) {
this.y2 = y2;
}
public void setThickness(int thickness) {
this.thickness = thickness;
}
public void setShapeColour(Color shapeColour) {
this.shapeColour = shapeColour;
}
public int getX1() {
return x1;
}
public int getY1() {
return y1;
}
public int getX2() {
return x2;
}
public int getY2() {
return y2;
}
public int getThickness() {
return thickness;
}
public Color getShapeColour() {
return shapeColour;
}
abstract void sketch(Graphics window);
}
abstract static class boundedShape extends Shape {
private int shapeType;
private boolean filled;
public boundedShape() {
super();
filled = false;
}
public boundedShape(int x1, int y1, int x2, int y2, int thickness, Color shapeColour, int shapeType, boolean filled) {
super(x1, y1, x2, y2, thickness, shapeColour);
this.shapeType = shapeType;
this.filled = filled;
}
public void setShapeType(int shapeType) {
this.shapeType = shapeType;
}
public void setFilled(boolean filled) {
this.filled = filled;
}
public int getUpperLeftX() {
return Math.min(getX1(), getX2());
}
public int getUpperLeftY() {
return Math.min(getY1(), getY2());
}
public int getWidth() {
return Math.abs(getX1() - getX2());
}
public int getHeight() {
return Math.abs(getY1() - getY2());
}
public int getShapeType() {
return shapeType;
}
public boolean getFilled() {
return filled;
}
abstract public void sketch(Graphics window);
}
static class geometricShape extends boundedShape {
public geometricShape() {
super();
}
public geometricShape(int x1, int y1, int x2, int y2, int thickness, Color shapeColour, int shapeType, boolean filled) {
super(x1, y1, x2, y2, thickness, shapeColour, shapeType, filled);
}
public void sketch(Graphics window) {
window.setColor(getShapeColour());
switch(getShapeType()) {
case 1://Straight line
((Graphics2D) window).setStroke(new BasicStroke(getThickness(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
window.drawLine(getX1(), getY1(), getX2(), getY2());
break;
case 2://Rectangle
if (getFilled())
window.fillRect(getUpperLeftX(), getUpperLeftY(), getWidth(), getHeight());
else {
((Graphics2D) window).setStroke(new BasicStroke(getThickness(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
window.drawRect(getUpperLeftX(), getUpperLeftY(), getWidth(), getHeight());
}
break;
case 3://Oval
if (getFilled())
window.fillOval(getUpperLeftX(), getUpperLeftY(), getWidth(), getHeight());
else {
((Graphics2D) window).setStroke(new BasicStroke(getThickness(), BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND));
window.drawOval(getUpperLeftX(), getUpperLeftY(), getWidth(), getHeight());
}
break;
}
}
}
static class PaintBoard extends JPanel implements MouseMotionListener, MouseListener {
private static final long serialVersionUID = 1L;
private boolean painting;
private int prevX, prevY;
private static Color canvasColour = Color.WHITE;
private static int brushSize = 6;
private static int brushType = 1;
private static Color currentColour = Color.BLACK;
private static LinkedList<brushLine> brushLines = new LinkedList<>();
private brushLine currentBrushLine;
private static LinkedList<Shape> shapes = new LinkedList<>();
private static int shapeType = 0;
private Shape currentShape = null;
private static boolean filled;
private JLabel mouseCoordinates = new JLabel("X: 0 pixels Y: 0 pixels");
public PaintBoard() {
setSize(getWidth(), getHeight());
setLayout(new BorderLayout());
add(mouseCoordinates, BorderLayout.SOUTH);
addMouseMotionListener(this);
addMouseListener(this);
}
#Override
public void paintComponent(Graphics board) {
super.paintComponent(board);
board.setColor(canvasColour);
board.fillRect(0, 0, getWidth(), getHeight());
ArrayList<brushLine> linesToDraw = brushLines.getArray();
for (int i = linesToDraw.size() - 1; i >= 0; i--)
linesToDraw.get(i).show(board);
if (currentBrushLine != null)
currentBrushLine.show(board);
ArrayList<Shape> shapesToDraw = shapes.getArray();
for (int j = shapesToDraw.size() - 1; j >= 0; j--)
shapesToDraw.get(j).sketch(board);
if (currentShape != null)
currentShape.sketch(board);
}
public void mouseDragged(MouseEvent e) {
mouseCoordinates.setText(String.format("X: %d pixels Y: %d pixels", e.getX(), e.getY()));
if (shapeType > 0) {
currentShape.setX2(e.getX());
currentShape.setY2(e.getY());
repaint();
} else {
if (!painting)
return;
((paintBrushLine) currentBrushLine).setX1(prevX);
((paintBrushLine) currentBrushLine).setY1(prevY);
((paintBrushLine) currentBrushLine).setX2(e.getX());
((paintBrushLine) currentBrushLine).setY2(e.getY());
repaint();
prevX = e.getX();
prevY = e.getY();
}
}
public void mouseMoved(MouseEvent e) {
mouseCoordinates.setText(String.format("X: %d pixels Y: %d pixels", e.getX(), e.getY()));
}
public void mouseClicked(MouseEvent e) {
}
public void mouseEntered(MouseEvent e) {
}
public void mouseExited(MouseEvent e) {
}
public void mousePressed(MouseEvent e) {
switch (shapeType) {
case 0://Curved line
if (painting)
return;
prevX = e.getX();
prevY = e.getY();
currentBrushLine = new paintBrushLine(brushSize, brushType, currentColour, prevX, prevY, prevX, prevY);
painting = true;
break;
default://Other shapes
currentShape = new geometricShape(e.getX(), e.getY(), e.getX(), e.getY(), brushSize, currentColour, shapeType, filled);
painting = false;
break;
}
}
public void mouseReleased(MouseEvent e) {
if (shapeType > 0) {
currentShape.setX2(e.getX());
currentShape.setY2(e.getY());
shapes.addFront(currentShape);
currentShape = null;
shapeType = 0;
repaint();
} else {
if (!painting)
return;
((paintBrushLine) currentBrushLine).setX2(e.getX());
((paintBrushLine) currentBrushLine).setY2(e.getY());
brushLines.addFront(currentBrushLine);
currentBrushLine = null;
painting = false;
repaint();
}
}
}
}
LinkedList class:
import java.util.ArrayList;
class LinkedList<T> {
private int numberOfNodes = 0;
private ListNode<T> front = null;
// Returns true if the linked list has no nodes, or false otherwise.
public boolean isEmpty() {
return (front == null);
}
// Deletes all of the nodes in the linked list.
// Note: ListNode objects will be automatically garbage collected by JVM.
public void makeEmpty() {
front = null;
numberOfNodes = 0;
}
// Returns the number of nodes in the linked list
public int size() {
return numberOfNodes;
}
// Adds a node to the front of the linked list.
public void addFront( T element ) {
front = new ListNode<T>( element, front );
numberOfNodes++;
}
// Returns a reference to the data in the first node, or null if the list is empty.
public T peek() {
if (isEmpty())
return null;
return front.getData();
}
// Removes a node from the front of the linked list (if there is one).
// Returns a reference to the data in the first node, or null if the list is empty.
#SuppressWarnings("unchecked")
public T removeFront() {
T tempData;
if (isEmpty())
return null;
tempData = front.getData();
front = front.getNext();
numberOfNodes--;
return tempData;
}
#SuppressWarnings("unchecked")
public void removeEnd(T element) {
ListNode<T> node=front;
while(node.getNext() != null)
{
node = node.getNext();
}
node.setNext(new ListNode<T>((T)element, null));
}
// Return array filled with T objects
#SuppressWarnings("unchecked")
public ArrayList<T> getArray() {
ArrayList<T> shapeArray=new ArrayList<T>();
ListNode<T> node=front;
while (node!=null)
{
shapeArray.add(node.getData());
node = node.getNext();
}
return shapeArray;
}
}
ListNode class:
public class ListNode<T> {
private T data;
private ListNode next;
// Constructor: No reference to next node provided so make it null
public ListNode( T nodeData ) {
this( nodeData, null);
}
// Constructor: Set data and reference to next node.
public ListNode( T nodeData, ListNode nodeNext ) {
data = nodeData;
next = nodeNext;
}
// Accessor: Return the data for current ListNode object
public T getData() {
return data;
}
// Accessor: Return reference to next ListNode object
public ListNode getNext() {
return next;
}
// Mutator: Set new data for current ListNode object
public void setData( T newData ) {
data = newData;
}
// Mutator: Set new reference to the next node object
public void setNext( ListNode newNext ) {
next = newNext;
}
}
Both your shapes and your lines only store a start and end point.
abstract static class Shape {
private int x1, y1, x2, y2;
private int thickness;
private Color shapeColour;
So how does your paint method know what to do? How can it draw a curve when it only ever knows two points?
What you need to do:
Once you have the shape completed you need to do some math to work out the radius and coordinates of each arc based on the coordinates of the previous and next segment, and then in your paint method you can draw lots and lots of small lines so that it appears a nice smooth arc.
Also, add some debugging code to find out what values your paint method is using, you may find that the reason you only see dots or small lines is because the values for each shape/line is not being stored correctly.
I need to delete shapes individually or all of them!
please help I've tried deleting all contents from my arrayList "Figuras"
and removeAll from panel
public class PaintRodo extends JFrame {
JButton linea, circulo, rectangulo, trazo, llenar,borrar;
static int seleccion = 1;
Color trazoC = Color.BLACK;
Color llenarC = Color.lightGray;
JMenuBar barra;
public static void main(String[] args) {
new PaintRodo();
}
public PaintRodo() {
this.setSize(1000,700);
this.setTitle("Paint");
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel();
panel.setBackground(Color.BLACK);
Box miBox = Box.createHorizontalBox();
linea= AgregarIcono("./src/linea.png",2);
circulo= AgregarIcono("./src/circ.png",3);
rectangulo= AgregarIcono("./src/rect.png",4);
trazo = AgregarIconoColor("./src/trazo.png",5,true);
llenar = AgregarIconoColor("./src/llenar.png",6,false);
borrar = AgregarIcono("./src/borrador.png",7);
miBox.add(linea);
miBox.add(circulo);
miBox.add(rectangulo);
miBox.add(llenar);
miBox.add(trazo);
miBox.add(borrar);
panel.add(miBox);
this.add(panel,BorderLayout.NORTH);
this.add(new Lienzo(),BorderLayout.CENTER);
this.setVisible(true);
}
public JButton AgregarIcono (String icono, final int accion){
JButton boton = new JButton();
Icon iconos = new ImageIcon (icono);
boton.setIcon(iconos);
boton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
seleccion =accion;
}
});
return boton;
}
public JButton AgregarIconoColor (String icono, final int accion,final boolean grosor ){
JButton boton = new JButton();
Icon iconos = new ImageIcon (icono);
boton.setIcon(iconos);
boton.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e){
if(grosor){
trazoC = JColorChooser.showDialog(null,"Elige el Contorno",Color.BLACK);
}
else{
llenarC = JColorChooser.showDialog(null,"Elige el Relleno",Color.BLACK);
}
}
});
return boton;
}
public class Lienzo extends JComponent{
ArrayList<Shape> figuras = new ArrayList<Shape>();
ArrayList<Color> arrLleno = new ArrayList<Color>();
ArrayList<Color> arrTrazo = new ArrayList<Color>();
Point inicio,fin;
public Lienzo(){
this.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e){
if (seleccion!=1){
inicio = new Point (e.getX(),e.getY());
fin=inicio;
repaint();
}
}
public void mouseReleased(MouseEvent e){
if (seleccion!=1){
Shape SAVEfig=null;
if (seleccion==2){
SAVEfig = crearLinea(inicio.x,inicio.y,e.getX(),e.getY());
}
else if (seleccion==3){
SAVEfig = crearCirculo(inicio.x,inicio.y,e.getX(),e.getY());
}
figuras.add(SAVEfig);
arrLleno.add(llenarC);
arrTrazo.add(trazoC);
repaint();
}
}
});//mouselistener
this.addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
fin= new Point (e.getX(),e.getY());
repaint();
}
});//MotionListener
}//constructor lienzo
public void paint (Graphics g){
Graphics2D graFig = (Graphics2D)g;
graFig.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
graFig.setStroke (new BasicStroke(2));
Iterator<Color>contadorTrazo= arrTrazo.iterator();
Iterator<Color>contadorLleno= arrLleno.iterator();
graFig.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,1.0f));
this.setBackground(Color.LIGHT_GRAY);
for (Shape i: figuras){
graFig.setPaint(contadorTrazo.next());
graFig.draw(i);
graFig.setPaint(contadorLleno.next());
graFig.fill(i);
}
if (inicio!=null&&fin!=null){
graFig.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER,0.40f));
graFig.setPaint(Color.LIGHT_GRAY);
Shape SAVEfig=null;
if (seleccion==2){
SAVEfig=crearLinea(inicio.x,inicio.y,fin.x,fin.y);
}
else if (seleccion==3){
SAVEfig=crearCirculo(inicio.x,inicio.y,fin.x,fin.y);
}
graFig.draw(SAVEfig);
}
}
private Rectangle2D.Float crearRectangulo(int x1, int y1,int x2 , int y2){
int x =Math.min(x1, x2);
int y = Math.min(y1, y2);
int ancho = Math.abs(x1-x2);
int alto = Math.abs(y1-y2);
return new Rectangle2D.Float(x,y,ancho,alto);
}
private Line2D.Float crearLinea(int x1, int y1, int x2, int y2){
return new Line2D.Float(x1, y1, x2, y2);
}
private Ellipse2D.Float crearCirculo( int x1, int y1, int x2, int y2){
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int ancho = Math.abs(x1 - x2);
int alto = Math.abs(y1 - y2);
return new Ellipse2D.Float(x, y, ancho, alto);
}
}//classLienzo
}//MainClass Paint rodo
I need to delete shapes individually or all of them!
Please help; I've tried deleting all contents from my arrayList "Figuras"
and (removeAll) from panel
How to create a component that can be dragged and resized in Java Swing?
Like "Text Tools" text box feature in MS Paint, highlighted by red border in image.
I only want drag and resize feature, not text formatting.
How can I implement this component using Java Swing?
In my quest to solve this problem, I found Piccolo2d ZUI library.
That's exactly, what I was looking for! However, it might not be best approach just to implement a "Draggable & Resizable Text Box", but I got it working in under an hour using Piccolo2d. So, I am posting the code here, if someone can find it useful.
Here is the screenshot of sample application!
I tried to make the code as describable as possible, so it's a bit long.
You'll require piccolo2d-core-XXX.jar & piccolo2d-extras-XXX.jar to run this code, that can be downloaded from Maven Central Repository. I used version 3.0 & didn't tested with any other version!
Custom Component Class
class PBox extends PNode {
private PCanvas canvas;
private Rectangle2D rectangle;
private Cursor moveCursor;
public PBox(PCanvas canvas) {
this(0, 0, 50, 50, canvas);
}
public PBox(double x, double y, double width, double height, PCanvas canvas) {
this.canvas = canvas;
rectangle = new Rectangle2D.Double();
moveCursor = Cursor.getPredefinedCursor(Cursor.MOVE_CURSOR);
addAnchors(x, y, width, height);
setBounds(x, y, width, height);
setInputEventListener();
}
private void addAnchors(double x, double y, double width, double height) {
addChild(new Anchor(SwingConstants.NORTH));
addChild(new Anchor(SwingConstants.NORTH_EAST));
addChild(new Anchor(SwingConstants.EAST));
addChild(new Anchor(SwingConstants.SOUTH_EAST));
addChild(new Anchor(SwingConstants.SOUTH));
addChild(new Anchor(SwingConstants.SOUTH_WEST));
addChild(new Anchor(SwingConstants.WEST));
addChild(new Anchor(SwingConstants.NORTH_WEST));
}
private void setInputEventListener() {
addInputEventListener(new PBasicInputEventHandler() {
#Override
public void mouseEntered(PInputEvent event) {
canvas.setCursor(moveCursor);
}
#Override
public void mouseExited(PInputEvent event) {
canvas.setCursor(Cursor.getDefaultCursor());
}
#Override
public void mouseDragged(PInputEvent event) {
PDimension delta = event.getDeltaRelativeTo(PBox.this);
translate(delta.width, delta.height);
event.setHandled(true);
}
});
}
#Override
protected void layoutChildren() {
Iterator iterator = getChildrenIterator();
int position = SwingConstants.NORTH;
while (iterator.hasNext()) {
PNode anchor = (PNode) iterator.next();
anchor.setBounds(getAnchorBounds(position));
++position;
}
}
private Rectangle2D getAnchorBounds(int position) {
double x = 0, y = 0;
Rectangle2D b = getBounds();
switch (position) {
case SwingConstants.NORTH:
x = b.getX()+b.getWidth()/2;
y = b.getY();
break;
case SwingConstants.NORTH_EAST:
x = b.getX()+b.getWidth();
y = b.getY();
break;
case SwingConstants.EAST:
x = b.getX()+b.getWidth();
y = b.getY()+b.getHeight()/2;
break;
case SwingConstants.SOUTH_EAST:
x = b.getX()+b.getWidth();
y = b.getY()+b.getHeight();
break;
case SwingConstants.SOUTH:
x = b.getX()+b.getWidth()/2;
y = b.getY()+b.getHeight();
break;
case SwingConstants.SOUTH_WEST:
x = b.getX();
y = b.getY()+b.getHeight();
break;
case SwingConstants.WEST:
x = b.getX();
y = b.getY()+b.getHeight()/2;
break;
case SwingConstants.NORTH_WEST:
x = b.getX();
y = b.getY();
break;
}
return new Rectangle2D.Double(x-2, y-2, 4, 4);
}
#Override
public boolean setBounds(double x, double y, double width, double height) {
if (super.setBounds(x, y, width, height)) {
rectangle.setFrame(x, y, width, height);
return true;
}
return false;
}
#Override
public boolean intersects(Rectangle2D localBounds) {
return rectangle.intersects(localBounds);
}
#Override
protected void paint(PPaintContext paintContext) {
Graphics2D g2 = paintContext.getGraphics();
g2.setPaint(Color.BLACK);
g2.setStroke(new BasicStroke(1.0f,
BasicStroke.CAP_BUTT,
BasicStroke.JOIN_MITER,
1.0f, new float[]{4.0f}, 0));
g2.draw(rectangle);
}
class Anchor extends PNode {
private Rectangle2D point;
private Cursor resizeCursor;
Anchor(int position) {
point = new Rectangle2D.Double();
setCursor(position);
setInputEventListener(position);
}
private void setCursor(int position) {
switch (position) {
case SwingConstants.NORTH:
resizeCursor = Cursor.getPredefinedCursor(Cursor.N_RESIZE_CURSOR);
break;
case SwingConstants.NORTH_EAST:
resizeCursor = Cursor.getPredefinedCursor(Cursor.NE_RESIZE_CURSOR);
break;
case SwingConstants.EAST:
resizeCursor = Cursor.getPredefinedCursor(Cursor.E_RESIZE_CURSOR);
break;
case SwingConstants.SOUTH_EAST:
resizeCursor = Cursor.getPredefinedCursor(Cursor.SE_RESIZE_CURSOR);
break;
case SwingConstants.SOUTH:
resizeCursor = Cursor.getPredefinedCursor(Cursor.S_RESIZE_CURSOR);
break;
case SwingConstants.SOUTH_WEST:
resizeCursor = Cursor.getPredefinedCursor(Cursor.SW_RESIZE_CURSOR);
break;
case SwingConstants.WEST:
resizeCursor = Cursor.getPredefinedCursor(Cursor.W_RESIZE_CURSOR);
break;
case SwingConstants.NORTH_WEST:
resizeCursor = Cursor.getPredefinedCursor(Cursor.NW_RESIZE_CURSOR);
break;
default:
resizeCursor = Cursor.getDefaultCursor();
}
}
private void setInputEventListener(final int position) {
addInputEventListener(new PBasicInputEventHandler() {
#Override
public void mouseEntered(PInputEvent event) {
canvas.setCursor(resizeCursor);
event.setHandled(true);
}
#Override
public void mouseExited(PInputEvent event) {
canvas.setCursor(Cursor.getDefaultCursor());
event.setHandled(true);
}
#Override
public void mouseDragged(PInputEvent event) {
PDimension delta = event.getDeltaRelativeTo(Anchor.this);
PNode parent = getParent();
if (position == SwingConstants.EAST
|| position == SwingConstants.NORTH_EAST
|| position == SwingConstants.SOUTH_EAST) {
parent.setWidth(parent.getWidth() + delta.width);
} else if (position == SwingConstants.WEST
|| position == SwingConstants.NORTH_WEST
|| position == SwingConstants.SOUTH_WEST) {
parent.setX(parent.getX() + delta.width);
parent.setWidth(parent.getWidth() - delta.width);
}
if (position == SwingConstants.SOUTH
|| position == SwingConstants.SOUTH_EAST
|| position == SwingConstants.SOUTH_WEST) {
parent.setHeight(parent.getHeight() + delta.height);
} else if (position == SwingConstants.NORTH
|| position == SwingConstants.NORTH_EAST
|| position == SwingConstants.NORTH_WEST) {
parent.setY(parent.getY() + delta.height);
parent.setHeight(parent.getHeight() - delta.height);
}
event.setHandled(true);
}
});
}
#Override
public boolean setBounds(double x, double y, double width, double height) {
if (super.setBounds(x, y, width, height)) {
point.setFrame(x, y, width, height);
return true;
}
return false;
}
#Override
public boolean intersects(Rectangle2D localBounds) {
return point.intersects(localBounds);
}
#Override
protected void paint(PPaintContext paintContext) {
Graphics2D g2 = paintContext.getGraphics();
g2.setColor(Color.WHITE);
g2.fill(point);
g2.setStroke(new BasicStroke(1.0f));
g2.setColor(Color.BLACK);
g2.draw(point);
}
}
}
And, the main class
public class Piccolo2DExample extends PFrame {
#Override
public void initialize() {
PCanvas canvas = getCanvas();
PNode text = new PText("Draggable & Resizable Box using Piccolo2d");
text.scale(2.0);
canvas.getCamera().addChild(text);
PLayer layer = canvas.getLayer();
PNode aLayerNode = new PText("A_Layer_Node");
aLayerNode.setOffset(10, 50);
layer.addChild(aLayerNode);
// Adding the component to layer
layer.addChild(new PBox(50, 100, 250, 50, canvas));
}
public static void main(String[] args) {
PFrame frame = new Piccolo2DExample();
frame.setSize(800, 640);
}
}
I'm kinda new to java and have been trying to make a simple paint program, I have gotten everything to work except the color of the paint brush. Rigth now I set the color to blue but I want to make the color of the paint brush the same color as the color selected by the color slider.
Here's the code I got so far
import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.event.*;
public class Paint extends JFrame implements ChangeListener{
PaintPanel color;
PaintPanel2 paint;
JSlider red;
JSlider green;
JSlider blue;
public Paint(){
super("Paint");
setSize(300,290);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setVisible(true);
color = new PaintPanel();
paint = new PaintPanel2();
red = new JSlider(0,255,255);
green = new JSlider(0,255,0);
blue = new JSlider(0,255,0);
red.setMajorTickSpacing(50);
red.setMinorTickSpacing(10);
red.setPaintTicks(true);
red.setPaintLabels(true);
red.addChangeListener(this);
green.setMajorTickSpacing(50);
green.setMinorTickSpacing(10);
green.setPaintTicks(true);
green.setPaintLabels(true);
green.addChangeListener(this);
blue.setMajorTickSpacing(50);
blue.setMinorTickSpacing(10);
blue.setPaintTicks(true);
blue.setPaintLabels(true);
blue.addChangeListener(this);
JLabel redLabel = new JLabel("Red: ");
JLabel greenLabel = new JLabel("Green: ");
JLabel blueLabel = new JLabel("Blue: ");
GridLayout grid = new GridLayout(5,1);
FlowLayout flow = new FlowLayout(FlowLayout.RIGHT);
setLayout(grid);
JPanel redPanel = new JPanel();
redPanel.setLayout(flow);
redPanel.add(redLabel);
redPanel.add(red);
add(redPanel);
JPanel greenPanel = new JPanel();
greenPanel.setLayout(flow);
greenPanel.add(greenLabel);
greenPanel.add(green);
add(greenPanel);
JPanel bluePanel = new JPanel();
bluePanel.setLayout(flow);
bluePanel.add(blueLabel);
bluePanel.add(blue);
add(bluePanel);
add(color);
add(paint);
setVisible(true);
}
public void stateChanged(ChangeEvent e){
JSlider source = (JSlider) e.getSource();
if(source.getValueIsAdjusting() != true){
Color mainColor = new Color(red.getValue(),
green.getValue(),
blue.getValue());
color.changeColor(mainColor);
color.repaint();
}
}
public static void main(String[] args){
Paint p = new Paint();
}
}
class PaintPanel extends JPanel{
Color background;
public PaintPanel(){
background = Color.red;
}
public void paintComponent(Graphics comp){
Graphics2D comp2D = (Graphics2D) comp;
comp2D.setColor(background);
comp2D.fillRect(0,0,getSize().width,getSize().height);
}
void changeColor(Color newBackground){
background = newBackground;
}
}
class PaintPanel2 extends JPanel{
Image image;
Graphics2D comp2D;
int currentX, currentY, oldX, oldY;
PaintPanel color;
public PaintPanel2(){
color = new PaintPanel();
addMouseListener(new MouseAdapter(){
public void mousePressed(MouseEvent e){
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter(){
public void mouseDragged(MouseEvent e){
currentX = e.getX();
currentY = e.getY();
if(comp2D != null)
comp2D.drawLine(oldX, oldY, currentX, currentY);
repaint();
oldX = currentX;
oldY = currentY;
}
});
}
public void paintComponent(Graphics comp){
if(image == null){
image = createImage(getSize().width, getSize().height);
comp2D = (Graphics2D)image.getGraphics();
comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
comp2D.setPaint(Color.white);
comp2D.fillRect(0, 0, getSize().width, getSize().height);
comp2D.setPaint(Color.blue);
repaint();
}
comp.drawImage(image, 0, 0, null);
}
}
The problem was that you weren't setting the chosen color in PaintPanel2. I changed the stateChanged method and the PaintPanel2 as follows, and now it works as I assume you intended:
public void stateChanged(ChangeEvent e) {
JSlider source = (JSlider) e.getSource();
if (source.getValueIsAdjusting() != true) {
Color mainColor = new Color(red.getValue(),
green.getValue(),
blue.getValue());
color.changeColor(mainColor);
paint.setPaintColor(mainColor);
color.repaint();
}
}
class PaintPanel2 extends JPanel {
Image image;
Graphics2D comp2D;
int currentX, currentY, oldX, oldY;
public PaintPanel2() {
addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
oldX = e.getX();
oldY = e.getY();
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
currentX = e.getX();
currentY = e.getY();
if (comp2D != null) {
comp2D.drawLine(oldX, oldY, currentX, currentY);
}
repaint();
oldX = currentX;
oldY = currentY;
}
});
}
public void paintComponent(Graphics comp) {
if (image == null) {
image = createImage(getSize().width, getSize().height);
comp2D = (Graphics2D) image.getGraphics();
comp2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
comp2D.setPaint(Color.white);
comp2D.fillRect(0, 0, getSize().width, getSize().height);
comp2D.setPaint(Color.blue);
repaint();
}
comp.drawImage(image, 0, 0, null);
}
public void setPaintColor(Color color) {
comp2D.setColor(color);
}
}