How to pass Graphics objects between classes and methods to draw lines - java

I am making a gui program with the mouseListener and mouseMotionListener. I have the following Line class
public class Line {
private int x1, x2, y1, y2;
private Color color;
public Line(int x1, int x2, int y1, int y2, Color color)
{
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.color = color;
}
public void draw(Graphics page)
{
page.drawLine(x1, y1, x2, y2);
page.setColor(color);
}
}
here is my mouseReleased where i get the final points of the desired line.
public void mouseReleased (MouseEvent event)
{ // ending points
moving = false;
Point p2 = event.getPoint();
x2 = p2.x;
y2 = p2.y;
line = new Line(x1,x2,y1,y2,currentColor);
lineList.add(line);
canvas.paintComponent(??????????);
Here is the canvas method that should draw all of these lines in the array list "lineList". to the canvas
private class CanvasPanel extends JPanel
{
//this method draws all shapes specified by a user
public void paintComponent(Graphics page)
{
super.paintComponent(page);
setBackground(Color.WHITE);
for(int i = 0; i <lineList.size()-1;i++)
{
line.draw(page);
}
However I do not know how to pass the graphics object to the canvas class in order to actually draw my lines on the JPanel. Assuming i have all other info correct(initial line points, JPanel set correctly, and buttons set up) how do i pass these to actually make it draw the lines to the canvas. Thank you!

No, you don't want to pass a Graphics object anywhere, and in fact you don't paint from within the MouseListener or MouseMotionListener. Instead you change fields from within those classes, call repaint() and then use the field results in your paintComponent method.
In fact in your code, if CanvasPanel has access to the lineList, all you need to do is call repaint() on it after adding a new line into the lineList collection. That's it.
Also, don't set background within paintComponent but rather within the constructor. Also you need to swap your method calls in the Line's draw method. You need to set the color before drawing the line.
e.g.,
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
#SuppressWarnings("serial")
public class Drawing extends JPanel {
public static final Color BG = Color.WHITE;
public static final Color LINE_COLOR = Color.RED;
public static final Color CURRENT_LINE_COLOR = Color.LIGHT_GRAY;
public static final int PREF_W = 800;
public static final int PREF_H = PREF_W;
private List<Line> lineList = new ArrayList<>();
private Line currentLine = null;
private CanvasPanel canvasPanel = new CanvasPanel();
public Drawing() {
MyMouse myMouse = new MyMouse();
canvasPanel.addMouseListener(myMouse);
canvasPanel.addMouseMotionListener(myMouse);
setLayout(new BorderLayout());
add(canvasPanel);
}
private class CanvasPanel extends JPanel {
public CanvasPanel() {
setBackground(BG);
}
public void paintComponent(Graphics page) {
super.paintComponent(page);
// setBackground(Color.WHITE); // !! no, not here
for (Line line : lineList) {
line.draw(page);
}
if (currentLine != null) {
currentLine.draw(page);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(PREF_W, PREF_H);
}
}
private class MyMouse extends MouseAdapter {
private int x1;
private int y1;
#Override
public void mousePressed(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
x1 = e.getX();
y1 = e.getY();
currentLine = null;
canvasPanel.repaint();
}
#Override
public void mouseReleased(MouseEvent e) {
if (e.getButton() != MouseEvent.BUTTON1) {
return;
}
Line line = createLine(e, LINE_COLOR);
lineList.add(line);
currentLine = null;
canvasPanel.repaint();
}
#Override
public void mouseDragged(MouseEvent e) {
currentLine = createLine(e, CURRENT_LINE_COLOR);
repaint();
}
private Line createLine(MouseEvent e, Color currentColor) {
int x2 = e.getX();
int y2 = e.getY();
return new Line(x1, x2, y1, y2, currentColor);
}
}
private static void createAndShowGui() {
JFrame frame = new JFrame("Drawing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new Drawing());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGui();
}
});
}
}
class Line {
private int x1, x2, y1, y2;
private Color color;
public Line(int x1, int x2, int y1, int y2, Color color) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
this.color = color;
}
public void draw(Graphics page) {
// swap these calls!
page.setColor(color); //!! This first!
page.drawLine(x1, y1, x2, y2); // **Then** this
// !! page.setColor(color);
}
}

Related

I am not able to draw after clear my jpanel

import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.border.BevelBorder;
public class Cliente extends JPanel {
private JButton adelanteButton;
private JButton undoButton;
private JPanel panel1;
private JPanel panelDibujo;
private Rectangulo rectangulo = new Rectangulo();
Originator originator;
Caretaker caretaker;
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Patron Memento");
Cliente cliente = new Cliente();
frame.setContentPane(cliente.panel1);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
for (Memento m : caretaker.history) {
System.out.println("forcitooooooo");
dibujar(m.getState(), Color.GREEN);
}
}
public Cliente() {
caretaker = new Caretaker();
originator = new Originator();
createUIComponents();
undoButton.addActionListener(e -> {
caretaker.anterior();
panelDibujo.repaint();
});
panelDibujo.setBackground(Color.WHITE);
panelDibujo.setBorder(BorderFactory.createBevelBorder(BevelBorder.RAISED));
panelDibujo.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
MousePressedEvent(e);
}
#Override
public void mouseReleased(MouseEvent e) {
MouseReleasedEvent(e);
}
});
}
private void createUIComponents() {
}
private void MousePressedEvent(MouseEvent e){
rectangulo.setX1(e.getX());
rectangulo.setY1(e.getY());
}
private void MouseReleasedEvent(MouseEvent e){
rectangulo.setX2(e.getX());
rectangulo.setY2(e.getY());
originator.setState(rectangulo);
dibujar(rectangulo, Color.orange);
caretaker.addMemento(originator.CreateMemento());
rectangulo = new Rectangulo();
}
public void dibujar(Rectangulo r, Color c) {
Graphics g = panelDibujo.getGraphics();
g.setColor(c);
g.drawRect(r.getX1(), r.getY1(), r.getX2() - r.getX1(), r.getY2() - r.getY1());
g.dispose();
}
}
Hello i am applying the memento pattern by using a jpanel and drawing some rectangles inside, right now my code is working fine about drawing with the mouse events, but the issue is when i try to undo. My logic so far is clear the jpanel and redo all the rectangles minus the last one.
But after clearing my jpanel is not drawing again :( can someone help me to fix it? thank you
Caretaker.java
import javax.swing.*;
import java.awt.*;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Stack;
public class Caretaker {
LinkedList<Memento> history;
int indice;
public Caretaker(){
history = new LinkedList<>();
indice = 0;
}
void addMemento(Memento m){
if (history.size() == indice || history.isEmpty()){
indice++;
history.add(m);
}else {
indice = history.size()-1;
history.subList(indice +1, history.size()).clear();
}
}
Memento anterior(){
if (history.size() > 0){
indice--;
return history.removeLast();
}
JOptionPane.showMessageDialog(null, "No hay mas wey!");
return null;
}
Memento siguiente(){
if (indice < history.size()+1){
indice++;
return history.get(indice+1);
}
JOptionPane.showMessageDialog(null, "No hay mas wey!");
return null;
}
public void redibujar(JPanel f){
Graphics g = f.getGraphics();
for (Memento m: history) {
g.drawRect(m.getState().getX1(), m.getState().getY1(), m.getState().getX2() - m.getState().getX1(), m.getState().getY2() - m.getState().getY1());
g.dispose();
}
}
public void clear(){
history.clear();
indice = 0;
}
}
Memento.java
public class Memento {
Rectangulo state;
/*
Constructor, unica manera de mandar/crear/guardar los datos
*/
public Memento(Rectangulo state) {
this.state = state;
}
public Memento(){
state = new Rectangulo();
}
Rectangulo getState(){
return state;
}
}
Originator.java
public class Originator {
Rectangulo state;
public void setState(Rectangulo rectangulo){
this.state = rectangulo;
}
public Memento CreateMemento(){
return new Memento(state);
}
public void setMemento(Memento m) {
setState(m.getState());
}
}
Rectangulo.java
import java.awt.*;
public class Rectangulo {
private int x1;
private int x2;
private int y1;
private int y2;
Rectangulo(){
}
public Rectangulo(int x1, int x2, int y1, int y2) {
this.x1 = x1;
this.x2 = x2;
this.y1 = y1;
this.y2 = y2;
}
public int getX1() {
return x1;
}
public void setX1(int x1) {
this.x1 = x1;
}
public int getX2() {
return x2;
}
public void setX2(int x2) {
this.x2 = x2;
}
public int getY1() {
return y1;
}
public void setY1(int y1) {
this.y1 = y1;
}
public int getY2() {
return y2;
}
public void setY2(int y2) {
this.y2 = y2;
}
public void draw(Graphics g){
g.setColor(Color.orange);
g.drawRect(this.getX1(), this.getY1(), this.getX2() - this.getX1(), this.getY2() - this.getY1());
}
}
Again, you're not drawing correctly. You are trying to render using a JPanel, cliente, that is never added to the GUI, and you're trying to use a Graphics object that is extracted from this unrendered component, making the Graphics object thus obtained short-lived and unstable.
Instead, do all drawing in the paintComponent method. You can use a BufferedImage and draw that in paintComponent if desired, especially if you want images with objects that show different colors, or you can use your List (here a LinkedList, but ArrayList will work) and draw in paintComponent. For instance, something simple like:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import javax.swing.*;
public class Cliente2 extends JPanel {
private static final int BI_WIDTH = 800;
private static final int BI_HEIGHT = 650;
private Rectangle drawingRect = null;
// private java.util.List<Rectangulo> rectangulos = new ArrayList<>();
List<Rectangulo2> rectangulos = new ArrayList<>();
private JButton clearBtn = new JButton("Clear");
public Cliente2() {
setBackground(Color.WHITE);
MyMouse myMouse = new MyMouse();
addMouseListener(myMouse);
addMouseMotionListener(myMouse);
clearBtn.addActionListener(e -> clear());
add(clearBtn);
}
private void clear() {
rectangulos.clear();
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(BI_WIDTH, BI_HEIGHT);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
if (drawingRect != null) {
g2.setColor(Color.LIGHT_GRAY);
g2.draw(drawingRect);
}
for (Rectangulo2 rectangulo : rectangulos) {
rectangulo.draw(g2);
}
}
private class MyMouse extends MouseAdapter {
private Point p0;
#Override
public void mousePressed(MouseEvent e) {
p0 = e.getPoint();
}
#Override
public void mouseDragged(MouseEvent e) {
drawingRect = createDrawingRect(e);
repaint();
}
private Rectangle createDrawingRect(MouseEvent e) {
Point p1 = e.getPoint();
int x = Math.min(p0.x, p1.x);
int y = Math.min(p0.y, p1.y);
int width = Math.abs(p0.x - p1.x);
int height = Math.abs(p0.y - p1.y);
return new Rectangle(x, y, width, height);
}
#Override
public void mouseReleased(MouseEvent e) {
// lets create some random colors:
float hue = (float) Math.random();
float brightness = (float) Math.random();
Color color = Color.getHSBColor(hue, 1f, brightness);
Rectangulo2 rectangulo = new Rectangulo2(color, p0, e.getPoint());
rectangulos.add(rectangulo);
drawingRect = null;
repaint();
}
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
JFrame frame = new JFrame("Patron Memento");
// Cliente cliente = new Cliente();
// frame.setContentPane(cliente.panel1);
frame.add(new Cliente2());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
class Rectangulo2 {
private static final Stroke STROKE = new BasicStroke(3f);
private Color color;
private Point p0, p1;
public Rectangulo2() {
}
public Rectangulo2(Color color, Point p0, Point p1) {
super();
this.color = color;
this.p0 = p0;
this.p1 = p1;
}
public Color getColor() {
return color;
}
public Point getP0() {
return p0;
}
public Point getP1() {
return p1;
}
public void draw(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setColor(color);
int x = Math.min(p0.x, p1.x);
int y = Math.min(p0.y, p1.y);
int width = Math.abs(p0.x - p1.x);
int height = Math.abs(p0.y - p1.y);
g2.fillRect(x, y, width, height);
g2.setStroke(STROKE);
g2.setColor(Color.BLACK);
g2.drawRect(x, y, width, height);
g2.dispose();
}
}

Passing variables from method to draw a line - Java

I want to call a method from a button click and from that method I want to pass variables to the class DrawPanel which extends Jpanel to draw a line. I have 4 classes, MainFem, DrawPanel, DrawLine and Callmethod1.
The problem is that the new values don't get added in the LinkedList.
Main class: MainFem
package paintpack;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.Dimension;
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;
public class MainFem extends JFrame {
JPanel buttonsPanel = null;
JButton dcomp = null;
DrawPanel drawPanel = null;
public MainFem(){
add(getDrawPanel(),BorderLayout.CENTER);
add(getButtonPanel(), BorderLayout.SOUTH);
getButtonPanel().add(getDcomp());
}
private JPanel getButtonPanel() {
if(buttonsPanel == null){
buttonsPanel = new JPanel();
buttonsPanel.setBorder(BorderFactory.createLineBorder(Color.black));
buttonsPanel.setPreferredSize(new Dimension(500, 100));
}
return buttonsPanel;
}
private DrawPanel getDrawPanel(){
if(drawPanel == null){
drawPanel = new DrawPanel();
drawPanel.setVisible(true);
}
return drawPanel;
}
private JButton getDcomp() {
if(dcomp == null){
dcomp = new JButton("Click");
dcomp.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Callmethod1 call1 = new Callmethod1();
call1.passmethod1();
getDrawPanel().repaint();
}
});
}
return dcomp;
}
public static void main(String[] args) {
MainFem wnd = new MainFem();
wnd.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
wnd.setPreferredSize(new Dimension(800, 600));
Container c = wnd.getContentPane();
c.setBackground(Color.red);
wnd.pack();
wnd.setVisible(true);
}
}
DrawPanel class
package paintpack;
import java.awt.Graphics;
import javax.swing.JPanel;
public class DrawPanel extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L;
private DrawLines dlines;
public DrawPanel() {
dlines = new DrawLines();
}
public void method1(int x1, int y1, int x2, int y2) {
dlines.addLine(x1, y1, x2, y2);
repaint();
//System.out.println("bingo");
}
// beging PAINTING
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
dlines.draw(g);
}
}
DrawLines
package paintpack;
import java.awt.Graphics;
import java.util.LinkedList;
public class DrawLines{
public DrawLines() {
}
private static class Line {
final int x1;
final int y1;
final int x2;
final int y2;
public Line(int x1, int y1, int x2, int y2) {
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
}
}
private final LinkedList<Line> lines = new LinkedList<Line>();
public void addLine(int x1, int y1, int x2, int y2) {
lines.add(new Line(x1, y1, x2, y2));
}
public void clearLines() {
lines.clear();
}
public void draw(Graphics g){
for (Line line : lines) {
g.drawLine(line.x1, line.y1, line.x2, line.y2);
}
}
}
Callmethod1
package paintpack;
public class Callmethod1 {
private DrawPanel pass1;
public Callmethod1() {
pass1 = new DrawPanel();
}
public void passmethod1(){
pass1.method1(300, 300, 200, 200);
pass1.repaint();
}
}
The problem is that you allocate a new instance of DrawPanel in the constructor of Callmethod1. So you are drawing lines on another instance of DrawPanel which is invisible. To fix it just pass an instance of existing DrawPanel, ei:
public Callmethod1(DrawPanel drawPanel) {
this.pass1 = drawPanel;
}
And in the action listener:
#Override
public void actionPerformed(ActionEvent e) {
Callmethod1 call1 = new Callmethod1(drawPanel);
call1.passmethod1();
}
As a side note, you can utilize existing Line2D class to draw lines.

Draw lines, circles anything (Java)

so i'm new in stackoverflow.
I am about to create a line, a triangle anything, but i'm just focusing on the line and in a good Object orient Programming.
So i create the class Point2D:
package draw;
/**
*
* #author Pedro
*/
public class Point2D {
private int x,y;
// Construtores
public Point2D(){
this(0,0);
}
public Point2D(int x, int y){
this.x=x;
this.y=y;
}
// Set's e Get's
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
Later i create the class line using the class point2D to get the starting point and final point
package draw;
/**
*
* #author Pedro
*/
public class Linha extends Figura{
private Point2D pinicial;
private Point2D pfinal;
//construtores
public Linha(int xinicial, int yinicial, int xfinal, int yfinal){
pinicial=new Point2D(xinicial, yinicial);
pfinal=new Point2D(xfinal, yfinal);
}
public Linha(Point2D pinicial, Point2D pfinal){
this.pinicial=pinicial;
this.pfinal=pfinal;
}
//Get's e Set's
public Point2D getPinicial() {
return pinicial;
}
public void setPinicial(Point2D pinicial) {
this.pinicial = pinicial;
}
public Point2D getPfinal() {
return pfinal;
}
public void setPfinal(Point2D pfinal) {
this.pfinal = pfinal;
}
}
And then i created a Jframe with a button called "line" and put it a panel inside the jFrame that is the place where its going to get the line draw.
The problems is ... I dont know how to draw the line or how should i cal it.
Can you help me?
simply, in your JPanel class ovverride paintComponent() method:
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g)
g.drawLine(x1, y1, x2, y2);
}
}
Where x1, y1, x2, and y2, are the cords of your line.
If you ONLY want it to draw line AFTER the button is pressed, create a global boolean variable, in your main class, and when the button is pressed, set it to true, then when you create your JPanel do:
JPanel panel = new JPanel() {
#Override
protected void paintComponent(Graphics g) {
if (myBoolean) {
super.paintComponent(g)
g.drawLine(x1, y1, x2, y2);
}
}
}
Though the advice given in the other answer is too good, but just couldn't stop myself, from adding a word or two to the same, like, in order for the painting to take place, you need to call repaint(), from inside the actionPerformed attached to JButton.
As already stated by #camickr, the use of getPreferredSize() inside the extended class for Drawing, that will provide a valid staging area, where the drawing needs to be done. This example might can help too in this direction.
Moreover, in case you wanted to keep all the lines which have been drawn on the Board so far intact, then you can simply store them in a List and iterate on this List to draw them all again, whenever a new line is to be drawn.
A simple example is as follows:
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import javax.swing.*;
public class LineExample {
private DrawingBoard board;
private JButton drawLineButton;
private Random random;
private ActionListener buttonAction = new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae) {
int width = board.getWidth();
int height = board.getHeight();
Line line = new Line(random.nextInt(width),
random.nextInt(height),
random.nextInt(width),
random.nextInt(height));
board.setValues(line);
}
};
public LineExample() {
random = new Random();
}
private void displayGUI() {
JFrame frame = new JFrame("Drawing Lines Example");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
JPanel contentPane = new JPanel(new BorderLayout(5, 5));
board = new DrawingBoard(400, 400);
contentPane.add(board, BorderLayout.CENTER);
drawLineButton = new JButton("LINE");
drawLineButton.addActionListener(buttonAction);
contentPane.add(drawLineButton, 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 LineExample().displayGUI();
}
};
EventQueue.invokeLater(runnable);
}
}
class DrawingBoard extends JPanel {
private int width;
private int height;
private List<Line> lines;
public DrawingBoard(int w, int h) {
width = w;
height = h;
lines = new ArrayList<Line>();
}
public void setValues(Line line) {
lines.add(line);
repaint();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(width, height);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
for (Line line : lines) {
int xs = line.getXStart();
int ys = line.getYStart();
int xe = line.getXEnd();
int ye = line.getYEnd();
g.drawLine(xs, ys, xe, ye);
}
}
}
class Line {
private Point startPoint;
private Point endPoint;
public Line(int xs, int ys, int xe, int ye) {
startPoint = new Point(xs, ys);
endPoint = new Point(xe, ye);
}
public int getXStart() {
return startPoint.getX();
}
public int getYStart() {
return startPoint.getY();
}
public int getXEnd() {
return endPoint.getX();
}
public int getYEnd() {
return endPoint.getY();
}
}
class Point {
private int x;
private int y;
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}

How can I animate a drawLine?

import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Line{
public static void main(String[] args){
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawLine(150,300,350,300));
frame.setSize(500,500);
frame.setVisible(true);
}
}
class DrawLine extends JPanel{
int x1;
int y1;
int x2;
int y2;
int midx;
int midy;
public DrawLine(int x1, int y1, int x2, int y2){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
midx = (x1+x2)/2;
midy = (y1+y2)/2;
}
public void animateLine(Graphics g){
g.drawLine(x1,y1,midx,midy);
g.drawLine(x2,y2,midx,midy);
}
public void paintComponent(Graphics g){
final Graphics2D g2d = (Graphics2D)g;
animateLine(g2d);
}
}
So, I have a some pretty basic code here to draw a line from each end towards a middle point. I am trying to make an animation of the middle point's Y value decreasing, so it will make something like an arrow. From what I have gathered I will need to use an action listener and a timer to accomplish this, but I have been unable to figure out exactly how to do it. If someone could please enlighten me on where to place and how to use the timer and repaint() so you can watch the arrow form from the line I would greatly appreciate it. I am trying to use this simple example so I can adapt it into a more complicated animation/drawing.
Update the coordinates in the actionPerformed() method of your javax.swing.Timer and invoke repaint().
import java.awt.event.*;
import java.awt.*;
import javax.swing.*;
public class Line{
public static void main(String[] args){
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new DrawLine(150,300,350,300));
frame.setSize(500,500);
frame.setVisible(true);
}
});
}
}
class DrawLine extends JPanel implements ActionListener{
int x1;
int y1;
int x2;
int y2;
int midx;
int midy;
Timer time = new Timer(10, (ActionListener) this);
public DrawLine(int x1, int y1, int x2, int y2){
this.x1 = x1;
this.y1 = y1;
this.x2 = x2;
this.y2 = y2;
midx = (x1+x2)/2;
midy = (y1+y2)/2;
time.start();
}
public void animateLine(Graphics2D g){
g.drawLine(x1,y1,midx,midy);
g.drawLine(x2,y2,midx,midy);
}
public void actionPerformed(ActionEvent arg0) {
if(midy>123){
midy--;
repaint();
}
}
public void paintComponent(Graphics newG){
super.paintComponent(newG);
Graphics2D g2d = (Graphics2D)newG;
animateLine(g2d);
}
}
I figured it out.

Drawing a circle in Java

I want to draw a circle which has the follow properties:
Center is the point where the user first clicks the mouse on the window
Radius should be the length of the distance between when the mouse is first clicked and when it's released (i.e. mouse dragging).
Here's what I have so far but it's not doing what I need it to do:
package assignment;
import java.awt.*;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.*;
public class DrawCircle extends JFrame implements MouseListener
{
private int centerX;
private int centerY;
private int endPtX;
private int endPtY;
private double radius;
private double w;
private double h;
private CirclePanel circPanel;
/** constructor **/
public DrawCircle()
{
this.setTitle("Click to Draw Circle");
this.setSize(500, 500);
this.setPreferredSize(new Dimension(500, 500));
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.setVisible(true);
this.setResizable(false);
this.addMouseListener(this);
this.circPanel = new CirclePanel();
this.circPanel.setPreferredSize(new Dimension(500, 500));
this.add(this.circPanel);
pack();
}
public void mousePressed(MouseEvent e)
{
centerX = e.getX();
centerY = e.getY();
circPanel.set(centerX, centerY, radius, radius);
repaint();
pack();
}
public void mouseReleased(MouseEvent e)
{
endPtX = e.getX();
endPtY = e.getY();
radius = Math.sqrt(Math.pow(endPtX - centerX, 2) + Math.pow(endPtY - centerY, 2));
}
public void mouseEntered(MouseEvent e) {}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e){}
//circle panel
private class CirclePanel extends JComponent
{
private int x;
private int y;
private int w;
private int h;
public void set(int x, int y, double width, double height)
{
this.x = x;
this.y = y;
w = (int) width;
h = (int) height;
}
public void paintComponent(Graphics g)
{
g.drawOval(x, y, w, h);
}
}
//main method
public static void main (String [] args)
{
new DrawCircle();
}
}
It looks like you are doing the
circPanel.set(centerX, centerY, radius, radius);
repaint();
pack();
in the wrong place you shouldn't draw the circle until the user lets go of the mouse because that's when the radius is set and before that the radius is 0 so there is nothing drawn. Try moving that to the mouseReleased method.

Categories