Drawing transculent rectangle - java

I was a problem with drawing rectangle using mouse. I have solve my problem and I get results what I want. But I have a small problem. If I want to start draw rectangle when I click mouse button, text in my button change. This is small difference but I don't want see this. Here is code:
package draw;
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
import javax.swing.event.*;
public class Selection extends JPanel
implements ChangeListener {
/**
*
*/
private static final long serialVersionUID = 1L;
private static final int WIDE = 640;
private static final int HIGH = 640;
private List<Node> nodes = new ArrayList<Node>();
private Point mousePt = new Point(WIDE / 2, HIGH / 2);
private Rectangle mouseRect = new Rectangle();
private boolean selecting = false;
public static void main(String[] args) throws Exception {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("GraphPanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Selection gp = new Selection();
gp.add(new JButton("Button"));
f.add(new JScrollPane(gp), BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});
}
Selection() {
this.setPreferredSize(new Dimension(WIDE, HIGH));
this.addMouseListener(new MouseHandler());
this.addMouseMotionListener(new MouseMotionHandler());
}
#Override
public void paintComponent(Graphics g) {
g.setColor(new Color(0x00f0f0f0));
g.fillRect(0, 0, getWidth(), getHeight());
for (Node n : nodes) {
n.draw(g);
}
if (selecting) {
g.setColor(Color.BLACK
);
((Graphics2D) g).setComposite(AlphaComposite.getInstance(rule, alpha));
g.fillRect(mouseRect.x, mouseRect.y,
mouseRect.width, mouseRect.height);
g.drawRect(mouseRect.x, mouseRect.y,
mouseRect.width, mouseRect.height);
}
}
int rule = AlphaComposite.SRC_OVER;
float alpha = 0.9F;
private class MouseHandler extends MouseAdapter {
#Override
public void mouseReleased(MouseEvent e) {
selecting = false;
mouseRect.setBounds(0, 0, 0, 0);
if (e.isPopupTrigger()) {
}
e.getComponent().repaint();
}
#Override
public void mousePressed(MouseEvent e) {
mousePt = e.getPoint();
Node.selectNone(nodes);
selecting = true;
e.getComponent().repaint();
}
}
private class MouseMotionHandler extends MouseMotionAdapter {
Point delta = new Point();
#Override
public void mouseDragged(MouseEvent e) {
if (selecting) {
mouseRect.setBounds(
Math.min(mousePt.x, e.getX()),
Math.min(mousePt.y, e.getY()),
Math.abs(mousePt.x - e.getX()),
Math.abs(mousePt.y - e.getY()));
} else {
delta.setLocation(
e.getX() - mousePt.x,
e.getY() - mousePt.y);
mousePt = e.getPoint();
}
e.getComponent().repaint();
}
}
/** A Node represents a node in a graph. */
private static class Node {
private Color color;
private boolean selected = false;
private Rectangle b = new Rectangle();
/** Draw this node. */
public void draw(Graphics g) {
g.setColor(this.color);
if (selected) {
g.setColor(Color.darkGray);
g.drawRect(b.x, b.y, b.width, b.height);
}
}
/** Mark this node as slected. */
public void setSelected(boolean selected) {
this.selected = selected;
}
/** Select no nodes. */
public static void selectNone(List<Node> list) {
for (Node n : list) {
n.setSelected(false);
}
}
}
#Override
public void stateChanged(ChangeEvent arg0) {
// TODO Auto-generated method stub
}
}
I think that can be a problem with place where I implement my button. I use eclipse SDK.
Can you help me?

Change your main to this. The reason is that you are setting alpha to < 1 for the entire panel and so the button is getting lighter shade. Simply move the button out of the panel and you are set.
public static void main(String[] args) throws Exception {
EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame f = new JFrame("GraphPanel");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel(new BorderLayout());
JButton button = new JButton("Button");
panel.add(button, BorderLayout.PAGE_START);
Selection gp = new Selection();
panel.add(gp, BorderLayout.CENTER);
f.add(new JScrollPane(panel), BorderLayout.CENTER);
f.pack();
f.setVisible(true);
}
});
}

Related

Why does this program only display the last graphic?

Im using JPanel and JFrame to create a program that can draw lines and circles. The problem is that my program only redraws the last object added.
I have tried moving around the repaint. For some reason, when I directly draw shapes onto the graphic in paintComponent(), they show up and refresh each frame. However, I have methods inside of paintComponent that pass the graphic variable to elsewhere methods that draw to the graphic object, these are the shapes that do not show up.
Painter Class
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Painter implements ActionListener, MouseListener, MouseMotionListener {
/**
*
*/
Color temp = Color.RED;
// 0 = line, 1 = circle
int object = 0;
PaintingPanel canvas;
Point startPoint = new Point();
Point endPoint = new Point();
Painter() {
//buttons
JButton circleBut = new JButton();
JButton lineBut = new JButton();
//frame
//close operation
//resizes
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(500, 500);
//holder holds the information
JPanel holder = new JPanel();
JPanel leftPanel = new JPanel();
holder.setLayout(new BorderLayout());
leftPanel.setLayout(new GridLayout(3, 1)); // 3 by 1 grid
JPanel northPanel = new JPanel();
northPanel.setLayout(new GridLayout(1, 2)); // 3 by 1 grid
frame.add(holder);
// circle and line buttons
circleBut.setText("Circle");
lineBut.setText("Line");
northPanel.add(circleBut);
northPanel.add(lineBut);
circleBut.setActionCommand("1");
lineBut.setActionCommand("0");
//
holder.add(northPanel, BorderLayout.NORTH);
// red
JButton redPaint = new JButton();
redPaint.setBackground(Color.RED);
redPaint.setOpaque(true);
redPaint.setBorderPainted(false);
leftPanel.add(redPaint);
redPaint.setActionCommand("red");
// green
JButton greenPaint = new JButton();
greenPaint.setBackground(Color.GREEN);
greenPaint.setOpaque(true);
greenPaint.setBorderPainted(false);
leftPanel.add(greenPaint);
greenPaint.setActionCommand("green");
// blue
JButton bluePaint = new JButton();
bluePaint.setBackground(Color.BLUE);
bluePaint.setOpaque(true);
bluePaint.setBorderPainted(false);
leftPanel.add(bluePaint);
bluePaint.setActionCommand("blue");
holder.add(leftPanel, BorderLayout.WEST);
// still need to add painting panel to the CENTER panel
canvas = new PaintingPanel();
holder.add(canvas, BorderLayout.CENTER);
circleBut.addActionListener(this);
lineBut.addActionListener(this);
redPaint.addActionListener(this);
greenPaint.addActionListener(this);
bluePaint.addActionListener(this);
canvas.addMouseListener(this);
//holder.addMouseMotionListener(this);
// still need to add chat panel to the SOUTH panel
frame.setContentPane(holder);
frame.setVisible(true);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getActionCommand().equals("red")) {
temp = Color.RED;
System.out.println("received r");
} else if (e.getActionCommand().equals("green")) {
temp = Color.GREEN;
System.out.println("received g");
} else if (e.getActionCommand().equals("blue")) {
temp = Color.BLUE;
System.out.println("received b");
} else if (e.getActionCommand().equals("0")) {
object = 0;
System.out.println("received 0");
} else if (e.getActionCommand().equals("1")) {
object = 1;
System.out.println("received 1");
}
}
#Override
public void mouseDragged(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
}
#Override
public void mousePressed(MouseEvent e) {
startPoint.setLocation(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
// and this one
endPoint.setLocation(e.getPoint());
if (object == 0) {
canvas.addPrimitive(new Line(startPoint, endPoint, temp));
}
if (object == 1){
canvas.addPrimitive(new Circle(startPoint, endPoint, temp));
}
canvas.repaint();
}
#Override
public void mouseEntered(MouseEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent e) {
// TODO Auto-generated method stub
}
public static void main(String[] args) {
Painter game1 = new Painter();
}
}
PaintingPrimitives:
`
import java.awt.Graphics;
import java.awt.Color;
public abstract class PaintingPrimitive{
Color color;
PaintingPrimitive(Color color) {
this.color = color;
}
// This is an example of the Template Design Pattern
// this is all invariant code
public final void draw(Graphics g) {
g.setColor(color);
drawGeometry(g);
}
public void setColor(Color color) {
this.color = color;
}
protected abstract void drawGeometry(Graphics g);
}
Line Class:
import java.awt.Graphics;
import java.awt.Point;
import java.awt.Color;
public class Line extends PaintingPrimitive{
Point startPoint = new Point();
Point endPoint = new Point();
public Line(Point start, Point end, Color c) {
super(c);
this.startPoint = start;
this.endPoint = end;
}
public void drawGeometry(Graphics g) {
System.out.println("graw geo called");
g.drawLine(startPoint.x, startPoint.y, endPoint.x, endPoint.y);
}
#Override
public String toString() {
return "Line";
}
}
Painting Panel:
import java.util.ArrayList;
import javax.swing.JPanel;
import java.awt.Graphics;
import java.awt.Color;
public class PaintingPanel extends JPanel {
ArrayList<PaintingPrimitive> primitives = new ArrayList<PaintingPrimitive>();
PaintingPanel() {
setBackground(Color.WHITE);
}
public void addPrimitive(PaintingPrimitive obj) {
primitives.add(obj);
this.repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
// i'm confident that this is not painting to the right graphics
for (PaintingPrimitive shape : primitives) {
//g.dispose();
//this line works. this line is drawn each time its updated.
g.drawLine(0,0,100,100);
shape.draw(g);
}
}
}
`
Okay, that was weird, until it wasn't. Your problem basic centers around...
public void mousePressed(MouseEvent e) {
startPoint.setLocation(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
// and this one
endPoint.setLocation(e.getPoint());
if (object == 0) {
canvas.addPrimitive(new Line(startPoint, endPoint, temp));
}
You create a single instance of startPoint and endPoint and simply update the location of each Point. You then pass these to each primitive you create. This means that each primitive is using the SAME instance of startPoint and endPoint. So, each time you call setLocation ALL the primitives are been updated.
Instead, do something more like...
#Override
public void mousePressed(MouseEvent e) {
startPoint = new Point(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
// and this one
endPoint = new Point(e.getPoint());
And because I'm paranoid and don't trust any one, I'd probably also do...
public class Line extends PaintingPrimitive {
Point startPoint = new Point();
Point endPoint = new Point();
public Line(Point start, Point end, Color c) {
super(c);
this.startPoint = new Point(start);
this.endPoint = new Point(end);
}
Just to be sure

How do I properly implement a mouselistener to my Jcomponent?

I have a project where I need to create a GUI in Java that creates a circle on mouse-click and and continues to make trailing circles as the mouse is dragged through the frame. I've been given reference to multiple threads on here but none have seemed to help me do what I need to do. So far I've got a static circle added to my JFrame, but I want to make the multiple circles show on a JPanel in that frame. I'm stuck after trying many different angles. As of now I just need to be able to click once and create a circle.
public class Theremin extends JFrame implements ActionListener, MouseListener{
private JPanel windowArea;
private int x, y;
private static final long serialVersionUID = 1L;
public Theremin() {
}
public static void main(String[] args) {
Theremin Frame = new Theremin();
Frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
panel.setLayout(null);
Frame.add(panel);
Frame.pack();
Frame.setLocationRelativeTo(null);
Frame.setVisible(true);
}
private static class MyPanel extends JPanel {
public void paint(Graphics g) {
Graphics2D gObj = (Graphics2D)g;
Shape disk = new Ellipse2D.Double(10, 10, 100, 100);
gObj.setColor(new Color(255, 0, 0, 120));
gObj.fill(disk);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 600);
}
}
#Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
// TODO Auto-generated method stub
}
#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
}
}
Here's a GUI that I put together.
Each mouse click creates a circle.
When I create a Swing GUI, or any Java application, I use the model / view / controller (MVC) pattern. This pattern allows me to separate my concerns and focus on one part of the application at a time.
For a Swing GUI, the MVC pattern means:
The view reads from the model.
The view does not update the model.
The controller updates the model and repaints / revalidates the view.
The model consists of two classes, Circles and Circle. The Circle class defines a circle with a Point center, int radius, and a Color color. Because Circle is a class, I can define as many instances (circles) as I want.
The Circles class holds a List of Circle instances.
The view consists of a JFrame and a drawing JPanel. The paintComponent method of the drawing JPanel paints circles. Period. We create the circles in the controller class.
The controller class CirclesListener creates the circles and repaints the drawing JPanel. All of the circles are redrawn each and every time the drawing JPanel is repainted.
An instance of the JFrame class and the application model class is passed to the controller CirclesListener class. This allows the class to create a new circle and repaint the drawing JPanel.
Here's the complete runnable code.
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.RenderingHints;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class MouseClickCircleGUI implements Runnable {
public static void main(String[] args) {
SwingUtilities.invokeLater(new MouseClickCircleGUI());
}
private Circles circles;
private DrawingPanel drawingPanel;
public MouseClickCircleGUI() {
this.circles = new Circles();
}
#Override
public void run() {
JFrame frame = new JFrame("Circles");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
drawingPanel = new DrawingPanel(this, circles);
frame.add(drawingPanel, BorderLayout.CENTER);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public void repaint() {
drawingPanel.repaint();
}
public class DrawingPanel extends JPanel {
private static final long serialVersionUID = 1L;
private final Circles circles;
public DrawingPanel(MouseClickCircleGUI frame, Circles circles) {
this.circles = circles;
setBackground(Color.WHITE);
setPreferredSize(new Dimension(500, 500));
addMouseListener(new CirclesListener(frame, circles));
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setStroke(new BasicStroke(3f));
for (Circle circle : circles.getCircles()) {
Point p = circle.getCenter();
int radius = circle.getRadius();
g2.setColor(circle.getColor());
g2.drawOval(p.x - radius, p.y - radius,
2 * radius, 2 * radius);
}
}
}
public class CirclesListener extends MouseAdapter {
private final Circles circles;
private final MouseClickCircleGUI frame;
public CirclesListener(MouseClickCircleGUI frame, Circles circles) {
this.frame = frame;
this.circles = circles;
}
#Override
public void mouseReleased(MouseEvent event) {
circles.addCircle(new Circle(event.getPoint(), 30, Color.BLACK));
frame.repaint();
}
}
public class Circles {
private final List<Circle> circles;
public Circles() {
this.circles = new ArrayList<>();
}
public void addCircle(Circle circle) {
this.circles.add(circle);
}
public List<Circle> getCircles() {
return circles;
}
}
public class Circle {
private final int radius;
private final Color color;
private final Point center;
public Circle(Point center, int radius, Color color) {
this.center = center;
this.radius = radius;
this.color = color;
}
public int getRadius() {
return radius;
}
public Point getCenter() {
return center;
}
public Color getColor() {
return color;
}
}
}
The idea here is to:
capture point
add it to list
repaint component
Here is how I have done it, this is a sample code.
package com.company;
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.Ellipse2D;
import java.util.ArrayList;
import java.util.List;
public class Main {
public static void main(String[] args) {
Theremin frame = new Theremin();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
MyPanel panel = new MyPanel();
panel.initListeners();
panel.setLayout(null);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
frame.addWindowListener(new WindowListener() {
#Override
public void windowOpened(WindowEvent e) {
}
#Override
public void windowClosing(WindowEvent e) {
panel.releaseListener();
}
#Override
public void windowClosed(WindowEvent e) {
}
#Override
public void windowIconified(WindowEvent e) {
}
#Override
public void windowDeiconified(WindowEvent e) {
}
#Override
public void windowActivated(WindowEvent e) {
}
#Override
public void windowDeactivated(WindowEvent e) {
}
});
}
}
class MyPanel extends JPanel implements MouseListener, MouseMotionListener {
private Graphics graphics;
private List<CircleData> shapeList = new ArrayList<>();
private Graphics2D gObj;
public MyPanel() {
}
#Override
public void paint(Graphics g) {
this.graphics = g;
gObj = (Graphics2D) g;
System.out.println("called paint with times: " + times++);
for (CircleData circleData : shapeList) {
Rectangle rectangle = circleData.rectangle;
Color color = circleData.color;
Shape disk = new Ellipse2D.Double(rectangle.x, rectangle.y, rectangle.width, rectangle.height);
gObj.setColor(color);
gObj.fill(disk);
}
}
Color randomColor() {
int red = (int) (Math.random() * 256);
int green = (int) (Math.random() * 256);
int blue = (int) (Math.random() * 256);
return new Color(red, green, blue);
}
static int times = 0;
#Override
public Dimension getPreferredSize() {
return new Dimension(700, 600);
}
public void initListeners() {
System.out.println("added default listeners");
addMouseListener(this);
addMouseMotionListener(this);
}
public void releaseListener() {
System.out.println("removed default listeners");
removeMouseListener(this);
removeMouseMotionListener(this);
}
#Override
public void mouseClicked(MouseEvent e) {
float x = e.getX();
float y = e.getY();
String cordinates = String.format("(%f, %f)", x, y);
System.out.println("Mouse Clicked # " + cordinates);
shapeList.add(new CircleData(new Rectangle((int) x, (int) y, 50, 50), randomColor()));
repaint();
}
#Override
public void mousePressed(MouseEvent e) {
}
#Override
public void mouseReleased(MouseEvent e) {
}
#Override
public void mouseEntered(MouseEvent e) {
}
#Override
public void mouseExited(MouseEvent e) {
}
#Override
public void mouseDragged(MouseEvent e) {
float x = e.getX();
float y = e.getY();
String cordinates = String.format("(%f, %f)", x, y);
System.out.println("Mouse Dragged # " + cordinates);
System.out.println("Mouse Dragged # " + shapeList.size());
shapeList.add(new CircleData(new Rectangle((int) x, (int) y, 50, 50), randomColor()));
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
}
class CircleData {
Rectangle rectangle;
Color color;
public CircleData(Rectangle rectangle, Color color) {
this.rectangle = rectangle;
this.color = color;
}
}
class Theremin extends JFrame {
private static final long serialVersionUID = 1L;
public Theremin() {
}
}

How to let user draw inside a canvas and save image afterwards?

I am trying to implement a free hand drawing Java applet which allows user to draw something in canvas (canvas is not the priority, it could be anything else as long I can save the image after (need to save it, because I have to display it later in a different place after pressing a button, any other solutions are welcome)). I found a code, which allows me to draw, but now I am having a trouble with drawing inside the canvas... And I have already spent few days with no results on that. Here is the code I have by now and a description below it:
import java.awt.*;
import java.awt.event.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.event.MouseMotionListener;
import javax.swing.*;
import java.applet.*;
public class paintMozApplet extends Applet implements ActionListener
{
int xPressed,yPressed;
int xReleased,yReleased;
int xDragged,yDragged;
private GridLayout gL;
private JPanel buttons;
private JPanel panel;
private Button clear, createMoz;
private Label result_here;
private javax.swing.JPanel drawing;
private JPanel moz;
private Canvas canvas;
private draw draw;
public paintMozApplet()
{
draw = new draw();
gL = new GridLayout(1, 0);
buttons = new JPanel();
drawing = new JPanel();
moz = new JPanel();
canvas = new Canvas();
clear = new Button("clear");
createMoz = new Button("Create Moz");
buttons.add(clear);
buttons.add(createMoz);
result_here = new Label("Result here!");
moz.add(result_here);
drawing.add(canvas);
clear.addActionListener(this);
//canvas.add(draw);
//canvas.addMouseMotionListener(this);
canvas.setPreferredSize(new Dimension(200, 200));
canvas.setBackground(Color.green);
add(drawing);
add(buttons);
add(moz);
add(draw);
setPreferredSize(new Dimension(1000, 1000));
setSize(1000, 1000);
setLayout(gL);
}
public void actionPerformed(ActionEvent e)
{
if(e.getSource()==clear)
{
//setOpaque(false);
repaint();
}
}
}
class draw extends JFrame implements MouseListener, MouseMotionListener, ActionListener {
int xPressed,yPressed;
int xReleased,yReleased;
int xDragged,yDragged;
private JButton clear;
public draw()
{
setPreferredSize(new Dimension(1200, 500));
setBounds(0, 0, 480, 500);
clear=new JButton("CLEAR");
add(clear);
clear.setBounds(540, 5, 100, 25);
clear.addActionListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
protected void paintComponent(Graphics g)
{
g.drawLine(xPressed,yPressed,xDragged,yDragged);
xPressed=xDragged;
yPressed=yDragged;
}
#Override
public void mouseDragged(MouseEvent arg0) {
Graphics g = getGraphics();
g.drawLine(xPressed, yPressed, arg0.getX(), arg0.getY());
xDragged = arg0.getX();
yDragged = arg0.getY();
repaint();
}
#Override
public void mouseMoved(MouseEvent arg0) {
}
#Override
public void mouseClicked(MouseEvent arg0) {
}
#Override
public void mouseEntered(MouseEvent arg0) {
}
#Override
public void mouseExited(MouseEvent arg0) {
}
#Override
public void mousePressed(MouseEvent arg0) {
xPressed = arg0.getX();
yPressed = arg0.getY();
}
#Override
public void mouseReleased(MouseEvent arg0) {
}
#Override
public void actionPerformed(ActionEvent e) {
}
}
So my idea is to create two classes where one is used to draw and other to create place where to draw and everything else. I have tried lots of things and now I am here and cant figure out, how to cal the draw class on my canvas so it will draw only there. Before I had everything in one class and called mouse events on my canvas. Result was that it drawed only when I clicked on canvas, but the actual drawing went also out of canvas if I did not let go of my mouse and dragged it out of canvas. Also it did not draw in canvas, but on the background of applet, at least it looked like that.
I really hope I explained my self understanding and I am sure, that this can be solved easily since there are lots of solutions online but I can't seem to find one that would work as I intend.
I suggest starting with this approach based around a BufferedImage as the painting surface..
import java.awt.*;
import java.awt.RenderingHints.Key;
import java.awt.event.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.border.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;
public class BasicPaint {
/** Reference to the original image. */
private BufferedImage originalImage;
/** Image used to make changes. */
private BufferedImage canvasImage;
/** The main GUI that might be added to a frame or applet. */
private JPanel gui;
/** The color to use when calling clear, text or other
* drawing functionality. */
private Color color = Color.WHITE;
/** General user messages. */
private JLabel output = new JLabel("You DooDoodle!");
private BufferedImage colorSample = new BufferedImage(
16,16,BufferedImage.TYPE_INT_RGB);
private JLabel imageLabel;
private int activeTool;
public static final int SELECTION_TOOL = 0;
public static final int DRAW_TOOL = 1;
public static final int TEXT_TOOL = 2;
private Point selectionStart;
private Rectangle selection;
private boolean dirty = false;
private Stroke stroke = new BasicStroke(
3,BasicStroke.CAP_ROUND,BasicStroke.JOIN_ROUND,1.7f);
private RenderingHints renderingHints;
public JComponent getGui() {
if (gui==null) {
Map<Key, Object> hintsMap = new HashMap<RenderingHints.Key,Object>();
hintsMap.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
hintsMap.put(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
hintsMap.put(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
renderingHints = new RenderingHints(hintsMap);
setImage(new BufferedImage(320,240,BufferedImage.TYPE_INT_RGB));
gui = new JPanel(new BorderLayout(4,4));
gui.setBorder(new EmptyBorder(5,3,5,3));
JPanel imageView = new JPanel(new GridBagLayout());
imageView.setPreferredSize(new Dimension(480,320));
imageLabel = new JLabel(new ImageIcon(canvasImage));
JScrollPane imageScroll = new JScrollPane(imageView);
imageView.add(imageLabel);
imageLabel.addMouseMotionListener(new ImageMouseMotionListener());
imageLabel.addMouseListener(new ImageMouseListener());
gui.add(imageScroll,BorderLayout.CENTER);
JToolBar tb = new JToolBar();
tb.setFloatable(false);
JButton colorButton = new JButton("Color");
colorButton.setMnemonic('o');
colorButton.setToolTipText("Choose a Color");
ActionListener colorListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
Color c = JColorChooser.showDialog(
gui, "Choose a color", color);
if (c!=null) {
setColor(c);
}
}
};
colorButton.addActionListener(colorListener);
colorButton.setIcon(new ImageIcon(colorSample));
tb.add(colorButton);
setColor(color);
final SpinnerNumberModel strokeModel =
new SpinnerNumberModel(3,1,16,1);
JSpinner strokeSize = new JSpinner(strokeModel);
ChangeListener strokeListener = new ChangeListener() {
#Override
public void stateChanged(ChangeEvent arg0) {
Object o = strokeModel.getValue();
Integer i = (Integer)o;
stroke = new BasicStroke(
i.intValue(),
BasicStroke.CAP_ROUND,
BasicStroke.JOIN_ROUND,
1.7f);
}
};
strokeSize.addChangeListener(strokeListener);
strokeSize.setMaximumSize(strokeSize.getPreferredSize());
JLabel strokeLabel = new JLabel("Stroke");
strokeLabel.setLabelFor(strokeSize);
strokeLabel.setDisplayedMnemonic('t');
tb.add(strokeLabel);
tb.add(strokeSize);
tb.addSeparator();
ActionListener clearListener = new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
int result = JOptionPane.OK_OPTION;
if (dirty) {
result = JOptionPane.showConfirmDialog(
gui, "Erase the current painting?");
}
if (result==JOptionPane.OK_OPTION) {
clear(canvasImage);
}
}
};
JButton clearButton = new JButton("Clear");
tb.add(clearButton);
clearButton.addActionListener(clearListener);
gui.add(tb, BorderLayout.PAGE_START);
JToolBar tools = new JToolBar(JToolBar.VERTICAL);
tools.setFloatable(false);
JButton crop = new JButton("Crop");
final JRadioButton select = new JRadioButton("Select", true);
final JRadioButton draw = new JRadioButton("Draw");
final JRadioButton text = new JRadioButton("Text");
tools.add(crop);
tools.add(select);
tools.add(draw);
tools.add(text);
ButtonGroup bg = new ButtonGroup();
bg.add(select);
bg.add(text);
bg.add(draw);
ActionListener toolGroupListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
if (ae.getSource()==select) {
activeTool = SELECTION_TOOL;
} else if (ae.getSource()==draw) {
activeTool = DRAW_TOOL;
} else if (ae.getSource()==text) {
activeTool = TEXT_TOOL;
}
}
};
select.addActionListener(toolGroupListener);
draw.addActionListener(toolGroupListener);
text.addActionListener(toolGroupListener);
gui.add(tools, BorderLayout.LINE_END);
gui.add(output,BorderLayout.PAGE_END);
clear(colorSample);
clear(canvasImage);
}
return gui;
}
/** Clears the entire image area by painting it with the current color. */
public void clear(BufferedImage bi) {
Graphics2D g = bi.createGraphics();
g.setRenderingHints(renderingHints);
g.setColor(color);
g.fillRect(0, 0, bi.getWidth(), bi.getHeight());
g.dispose();
imageLabel.repaint();
}
public void setImage(BufferedImage image) {
this.originalImage = image;
int w = image.getWidth();
int h = image.getHeight();
canvasImage = new BufferedImage(w,h,BufferedImage.TYPE_INT_ARGB);
Graphics2D g = this.canvasImage.createGraphics();
g.setRenderingHints(renderingHints);
g.drawImage(image, 0, 0, gui);
g.dispose();
selection = new Rectangle(0,0,w,h);
if (this.imageLabel!=null) {
imageLabel.setIcon(new ImageIcon(canvasImage));
this.imageLabel.repaint();
}
if (gui!=null) {
gui.invalidate();
}
}
/** Set the current painting color and refresh any elements needed. */
public void setColor(Color color) {
this.color = color;
clear(colorSample);
}
private JMenu getFileMenu(boolean webstart){
JMenu file = new JMenu("File");
file.setMnemonic('f');
JMenuItem newImageItem = new JMenuItem("New");
newImageItem.setMnemonic('n');
ActionListener newImage = new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
BufferedImage bi = new BufferedImage(
360, 300, BufferedImage.TYPE_INT_ARGB);
clear(bi);
setImage(bi);
}
};
newImageItem.addActionListener(newImage);
file.add(newImageItem);
if (webstart) {
//TODO Add open/save functionality using JNLP API
} else {
//TODO Add save functionality using J2SE API
file.addSeparator();
ActionListener openListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
if (!dirty) {
JFileChooser ch = getFileChooser();
int result = ch.showOpenDialog(gui);
if (result==JFileChooser.APPROVE_OPTION ) {
try {
BufferedImage bi = ImageIO.read(
ch.getSelectedFile());
setImage(bi);
} catch (IOException e) {
showError(e);
e.printStackTrace();
}
}
} else {
// TODO
JOptionPane.showMessageDialog(
gui, "TODO - prompt save image..");
}
}
};
JMenuItem openItem = new JMenuItem("Open");
openItem.setMnemonic('o');
openItem.addActionListener(openListener);
file.add(openItem);
ActionListener saveListener = new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JFileChooser ch = getFileChooser();
int result = ch.showSaveDialog(gui);
if (result==JFileChooser.APPROVE_OPTION ) {
try {
File f = ch.getSelectedFile();
ImageIO.write(BasicPaint.this.canvasImage, "png", f);
BasicPaint.this.originalImage = BasicPaint.this.canvasImage;
dirty = false;
} catch (IOException ioe) {
showError(ioe);
ioe.printStackTrace();
}
}
}
};
JMenuItem saveItem = new JMenuItem("Save");
saveItem.addActionListener(saveListener);
saveItem.setMnemonic('s');
file.add(saveItem);
}
if (canExit()) {
ActionListener exit = new ActionListener() {
#Override
public void actionPerformed(ActionEvent arg0) {
// TODO Auto-generated method stub
System.exit(0);
}
};
JMenuItem exitItem = new JMenuItem("Exit");
exitItem.setMnemonic('x');
file.addSeparator();
exitItem.addActionListener(exit);
file.add(exitItem);
}
return file;
}
private void showError(Throwable t) {
JOptionPane.showMessageDialog(
gui,
t.getMessage(),
t.toString(),
JOptionPane.ERROR_MESSAGE);
}
JFileChooser chooser = null;
public JFileChooser getFileChooser() {
if (chooser==null) {
chooser = new JFileChooser();
FileFilter ff = new FileNameExtensionFilter("Image files", ImageIO.getReaderFileSuffixes());
chooser.setFileFilter(ff);
}
return chooser;
}
public boolean canExit() {
boolean canExit = false;
SecurityManager sm = System.getSecurityManager();
if (sm==null) {
canExit = true;
} else {
try {
sm.checkExit(0);
canExit = true;
} catch(Exception stayFalse) {
}
}
return canExit;
}
public JMenuBar getMenuBar(boolean webstart){
JMenuBar mb = new JMenuBar();
mb.add(this.getFileMenu(webstart));
return mb;
}
public static void main(String[] args) {
Runnable r = new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(
UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) {
// use default
}
BasicPaint bp = new BasicPaint();
JFrame f = new JFrame("DooDoodle!");
f.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
f.setLocationByPlatform(true);
f.setContentPane(bp.getGui());
f.setJMenuBar(bp.getMenuBar(false));
f.pack();
f.setMinimumSize(f.getSize());
f.setVisible(true);
}
};
SwingUtilities.invokeLater(r);
}
public void text(Point point) {
String text = JOptionPane.showInputDialog(gui, "Text to add", "Text");
if (text!=null) {
Graphics2D g = this.canvasImage.createGraphics();
g.setRenderingHints(renderingHints);
g.setColor(this.color);
g.setStroke(stroke);
int n = 0;
g.drawString(text,point.x,point.y);
g.dispose();
this.imageLabel.repaint();
}
}
public void draw(Point point) {
Graphics2D g = this.canvasImage.createGraphics();
g.setRenderingHints(renderingHints);
g.setColor(this.color);
g.setStroke(stroke);
int n = 0;
g.drawLine(point.x, point.y, point.x+n, point.y+n);
g.dispose();
this.imageLabel.repaint();
}
class ImageMouseListener extends MouseAdapter {
#Override
public void mousePressed(MouseEvent arg0) {
// TODO Auto-generated method stub
if (activeTool==BasicPaint.SELECTION_TOOL) {
selectionStart = arg0.getPoint();
} else if (activeTool==BasicPaint.DRAW_TOOL) {
// TODO
draw(arg0.getPoint());
} else if (activeTool==BasicPaint.TEXT_TOOL) {
// TODO
text(arg0.getPoint());
} else {
JOptionPane.showMessageDialog(
gui,
"Application error. :(",
"Error!",
JOptionPane.ERROR_MESSAGE);
}
}
#Override
public void mouseReleased(MouseEvent arg0) {
if (activeTool==BasicPaint.SELECTION_TOOL) {
selection = new Rectangle(
selectionStart.x,
selectionStart.y,
arg0.getPoint().x,
arg0.getPoint().y);
}
}
}
class ImageMouseMotionListener implements MouseMotionListener {
#Override
public void mouseDragged(MouseEvent arg0) {
reportPositionAndColor(arg0);
if (activeTool==BasicPaint.SELECTION_TOOL) {
selection = new Rectangle(
selectionStart.x,
selectionStart.y,
arg0.getPoint().x-selectionStart.x,
arg0.getPoint().y-selectionStart.y);
} else if (activeTool==BasicPaint.DRAW_TOOL) {
draw(arg0.getPoint());
}
}
#Override
public void mouseMoved(MouseEvent arg0) {
reportPositionAndColor(arg0);
}
}
private void reportPositionAndColor(MouseEvent me) {
String text = "";
if (activeTool==BasicPaint.SELECTION_TOOL) {
text += "Selection (X,Y:WxH): " +
(int)selection.getX() +
"," +
(int)selection.getY() +
":" +
(int)selection.getWidth() +
"x" +
(int)selection.getHeight();
} else {
text += "X,Y: " + (me.getPoint().x+1) + "," + (me.getPoint().y+1);
}
output.setText(text);
}
}
This source is very patchy.
It has many parts with // TODO
A dirty attribute is declared but never used in any meaningful way. ..
It is just something I hacked together today and thought should be shown before it hit the posting limit.
Oh, and don't go looking for any 'OO design' since I did not put any in. If there is any, it is only by accident. This code is intended to demonstrate what is possible and how to start doing it.

Java repaint() not working

I am making a simple program to paint a graph and some points in it. The points should be made with methods while changing coordinates of the g.fillOval but actually its painting only the last point.
Here is the code:
import javax.swing.*;
import java.awt.*;
public class PointGraphWriter extends JPanel
{
JFrame korniza = new JFrame();
private int x;
private int y;
private int length;
private String OX;
private String OY;
private String emri;
private int y_height;
private int x_num;
public PointGraphWriter()
{
int width= 500;
korniza.setSize(width,width);
korniza.setVisible(true);
korniza.setTitle(emri);
korniza.getContentPane().add(this);
}
public void paintComponent(Graphics g)
{
g.drawLine(x,y,x+length,y);
g.drawLine(x,y,x,y-length);
g.drawString(OX,x+length, y+15);
g.drawString(OY,x-15,y-length);
g.drawString("0", x -15,y);
g.drawString("0", x,y+15);
g.fillOval(x_num,y-y_height-2, 4 ,4);
}
public void setTitle(String name)
{
emri= name;
this.repaint();
}
public void setAxes(int x_pos, int y_pos, int axis_length, String x_label, String y_label)
{
x= x_pos;
y=y_pos;
length= axis_length;
OX = x_label;
OY = y_label;
}
public void setPoint1(int height)
{
y_height=height;
x_num = x-2;
this.repaint();
}
public void setPoint2(int height)
{
y_height=height;
x_num = x + length/5-2;
this.repaint();
}
}
and here is the main method:
public class TestPlot
{
public static void main(String[] a)
{
PointGraphWriter e = new PointGraphWriter();
e.setTitle("Graph of y = x*x");
e.setAxes(50, 110, 90, "5", "30");
int scale_factor = 3;
e.setPoint1(0 * scale_factor);
e.setPoint2(1 * scale_factor);
}
}
Please have a look at this example. Something in lines of this, you might have to incorporate in your example, to make it work. Simply use a Collection to store what you have previously painted, and when the new thingy comes along, simply add that thingy to the list, and repaint the whole Collection again. As shown below :
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
public class RectangleExample {
private DrawingBoard customPanel;
private JButton button;
private Random random;
private java.util.List<Rectangle2D.Double> rectangles;
private ActionListener buttonActions =
new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
Rectangle2D.Double rectangle = new Rectangle2D.Double(
(double) random.nextInt(100), (double) random.nextInt(100),
(double) random.nextInt(100), (double) random.nextInt(100));
rectangles.add(rectangle);
customPanel.setValues(rectangles);
}
};
public RectangleExample() {
rectangles = new ArrayList<Rectangle2D.Double>();
random = new Random();
}
private void displayGUI() {
JFrame frame = new JFrame("Rectangle Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel();
contentPane.setLayout(new BorderLayout(5, 5));
customPanel = new DrawingBoard();
contentPane.add(customPanel, BorderLayout.CENTER);
button = new JButton("Create Rectangle");
button.addActionListener(buttonActions);
contentPane.add(button, BorderLayout.PAGE_END);
frame.setContentPane(contentPane);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
Runnable runnable = new Runnable() {
#Override
public void run() {
new RectangleExample().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class DrawingBoard extends JPanel {
private java.util.List<Rectangle2D.Double> rectangles =
new ArrayList<Rectangle2D.Double>();
public DrawingBoard() {
setOpaque(true);
setBackground(Color.WHITE);
}
public void setValues(java.util.List<Rectangle2D.Double> rectangles) {
this.rectangles = rectangles;
repaint();
}
#Override
public Dimension getPreferredSize() {
return (new Dimension(300, 300));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Rectangle2D.Double rectangle : rectangles) {
g.drawRect((int)rectangle.getX(), (int)rectangle.getY(),
(int)rectangle.getWidth(), (int)rectangle.getHeight());
}
System.out.println("WORKING");
}
}
See Custom Painting Approaches for examples of the two common ways to do painting:
Keep a List of the objects to be painted
Paint onto a BufferedImage
The approach you choose will depend on your exact requirement.

How do I clear my Jpanel but keep the grid lines?

I'm drawing lines on a JPanel using a paint component and graphics 2D, but the background of the JPanel is set to a grid which is drawn when the user enters some dimensions. How do I clear the lines drawn on the JPanel when a button is clicked but regenerate a fresh panel again with the grid lines drawn? With the action event method for the clear button, I've tried using repaint(), removeAll() and creating a new instance of the JPanel but none of that seems to work.
Here is the code for the class with the main Panel and button functions:
package floorplan;
/**
*
* #author xodkx
*/
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class FloorPlan extends JFrame
{
private JPanel backPanel = new JPanel();
private JPanel toolsPanel = new JPanel();
private JFrame chooseFurniture;
private JFrame chooseFixture;
private JFrame chooseFramework;
private JButton furnitureButton = new JButton();
private JButton fixturesButton = new JButton();
private JButton frameworkButton = new JButton();
private JButton deleteButton = new JButton();
private JButton saveButton = new JButton();
private JButton clearButton = new JButton();
private JButton closeButton = new JButton();
private JRadioButton wall = new JRadioButton("Wall");
private JRadioButton door = new JRadioButton("Door");
private JRadioButton window = new JRadioButton("Window");
Floor floor = new Floor();
public FloorPlan()
{
super("Floor Plan Generator");
createWindow();
buttonFunctions();
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
setVisible(true);
}
private void createWindow()
{
backPanel.setLayout(new BorderLayout());
backPanel.setBorder(BorderFactory.createEmptyBorder(200, 200, 200, 200));
GridLayout panelLayout = new GridLayout();
frameworkButton.setText("Framework");
fixturesButton.setText("Fixtures");
furnitureButton.setText("Furniture");
deleteButton.setText("Delete");
saveButton.setText("Save");
clearButton.setText("Clear");
add(backPanel, BorderLayout.CENTER);
backPanel.add(toolsPanel, BorderLayout.NORTH);
backPanel.add(floor, BorderLayout.CENTER);
backPanel.setBorder(BorderFactory.createEmptyBorder(20, 20, 20, 20));
toolsPanel.add(frameworkButton);
toolsPanel.add(fixturesButton);
toolsPanel.add(furnitureButton);
toolsPanel.add(deleteButton);
toolsPanel.add(saveButton);
toolsPanel.add(clearButton);
add(backPanel);
}
private void buttonFunctions()
{
frameworkButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
chooseFramework = new JFrame("Pick A Framework");
chooseFramework.setSize(250,250);
chooseFramework.setLayout(new GridLayout(4,1));
chooseFramework.add(wall);
chooseFramework.add(door);
chooseFramework.add(window);
chooseFramework.add(closeButton);
closeButton.setText("Close");
wall.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
floor.setFramework(Framework.WALL);
}});
door.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
floor.setColor(Color.RED);
floor.setFramework(Framework.DOOR);
}});
window.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
floor.setColor(Color.BLUE);
floor.setFramework(Framework.WALL);
}});
closeButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
chooseFramework.setVisible(false);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
chooseFramework.setVisible(true);
}
});
furnitureButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
chooseFurniture = new JFrame("Pick Furniture to add");
chooseFurniture.setSize(250,250);
chooseFurniture.setLayout(new GridLayout(4,1));
chooseFurniture.add(closeButton);
closeButton.setText("Close");
closeButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
chooseFurniture.setVisible(false);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
chooseFurniture.setVisible(true);
}
});
fixturesButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
chooseFixture = new JFrame("Pick Furniture to add");
chooseFixture.setSize(250,250);
chooseFixture.setLayout(new GridLayout(4,1));
chooseFixture.add(closeButton);
closeButton.setText("Close");
closeButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(ActionEvent e)
{
chooseFixture.setVisible(false);
}
});
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack();
chooseFixture.setVisible(true);
}
});
**clearButton.addActionListener(new ActionListener()
{
#Override
public void actionPerformed(final ActionEvent e)
{
**//THIS IS WHERE I WANT TO CLEAR THE JPANEL WHEN THIS BUTTON IS CLICKED**
}
});**
}
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
FloorPlan floorPlan = new FloorPlan();
}
});
}
}
Here is the class that does all the graphics stuff and draws onto the JPanel
package floorplan;
/**
*
* #author xodkx
*/
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.awt.event.MouseListener;
public class Floor extends JPanel implements MouseListener, MouseMotionListener
{
private static final int WIDTH = Integer.parseInt(JOptionPane.showInputDialog("Please
enter the width of your room"));
private static final int LENGTH = Integer.parseInt(JOptionPane.showInputDialog("Please
enter the width of your room"));
private static final Color BACKGROUND = Color.WHITE;
private static final Color INITIAL_COLOUR = Color.BLACK;
private static final Framework INITIAL_FRAMEWORK = Framework.WALL;
private MouseState state = MouseState.IDLE;
private Framework frameworkType = INITIAL_FRAMEWORK;
private Color colour = INITIAL_COLOUR;
private Point start = null;
private Point end = null;
private Point startpt = null;
private Point endpt = null;
private BufferedImage bufImage = null;
public Floor()
{
setPreferredSize(new Dimension(LENGTH,WIDTH));
setBackground(Color.white);
setBorder(BorderFactory.createLineBorder (Color.black, 5));
this.addMouseListener(this);
this.addMouseMotionListener(this);
}
public void setColor(Color color)
{
colour = color;
}
public void setFramework(Framework framework)
{
frameworkType = framework;
}
#Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
if(bufImage == null)
{
int h = this.getHeight();
int w = this.getWidth();
bufImage = (BufferedImage)this.createImage(h,w);
Graphics2D gc = bufImage.createGraphics();
gc.setColor(BACKGROUND);
gc.fillRect(0, 0, w, h);
}
g2.drawImage(bufImage,null,0,0);
drawGrid(g2);
if(state == MouseState.DRAGGING)
{
createComponent(g2);
}
}
public void drawGrid(Graphics g2)
{
int gridDivisions = 20;
int divisionSize = WIDTH/gridDivisions;
int grid = WIDTH*LENGTH;
g2.setColor(Color.lightGray);
for(int i=1; i<grid; i++)
{
int x = i * divisionSize;
g2.drawLine(x,0,x,getSize().height);
}
for(int i=1; i<grid; i++)
{
int y = i*divisionSize;
g2.drawLine(0,y,getSize().width,y);
}
}
public void createComponent(Graphics2D g2)
{
g2.setColor(colour);
switch (frameworkType)
{
case WALL:
g2.setStroke(new BasicStroke(5));
g2.drawLine(start.x, start.y, end.x,end.y);
break;
case DOOR:
g2.setStroke(new BasicStroke(5));
g2.drawLine(start.x, start.y, end.x,end.y);
break;
case WINDOW:
g2.setStroke(new BasicStroke(5));
g2.drawLine(start.x, start.y, end.x,end.y);
break;
default:
g2.drawString("test", 10, 20);
break;
}
}
#Override
public void mousePressed(MouseEvent e)
{
state = MouseState.DRAGGING;
start = e.getPoint();
end = start;
}
#Override
public void mouseDragged(MouseEvent e)
{
state = MouseState.DRAGGING;
end = e.getPoint();
this.repaint();
}
#Override
public void mouseReleased(MouseEvent e)
{
end = e.getPoint();
if(state == MouseState.DRAGGING)
{
state = MouseState.IDLE;
createComponent(bufImage.createGraphics());
this.repaint();
}
}
#Override
public void mouseClicked(MouseEvent e)
{
}
#Override
public void mouseEntered(MouseEvent e)
{
}
#Override
public void mouseExited(MouseEvent e)
{
}
#Override
public void mouseMoved(MouseEvent e)
{
}
}
It is not clear exactly how do you want to incorporate the logic of displaying the grid. Here is an example how to toggle it just to give you the idea. In Floor class add boolean flag that controls whether the grid is displayed or not. Then in Floor.paintComponent() draw grid based on the value of this boolean flag. Changing the flag's value should trigger a repaint. Then, change the value of this flag from FloorPlan class, in response to an action or some other program logic. Here is a simple implementation that toggles grid when clear button is clicked :
Floor class:
private boolean displayGrid = true;
public boolean isDisplayGrid() {
return displayGrid;
}
public void setDisplayGrid(boolean displayGrid) {
this.displayGrid = displayGrid;
repaint();
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
...
if (displayGrid)
drawGrid(g2);
}
FloorPlan class:
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
floor.setDisplayGrid(!floor.isDisplayGrid());
}
});
EDIT:
Seems that I totally misinterpreted your question. If I understand correctly you want to clear the drawings upon a button click. Looks like all the drawings are done on the bufImage in the Floor class. Simply reset this image, ie:
Floor class:
public void clear() {
bufImage.flush();
bufImage = null;
repaint();
}
FloorPlan class:
clearButton.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
floor.clear();
}
});
You could use a for loop with panel.remove the buttons (instead of panel.add)

Categories

Resources