Drawing on a canvas declared in another function - java

I have an application which has a swing user interface class, which has buttons that send variables to a canvas class like so;
public class createWindow extends JFrame implements ActionListener
{
createCanvas canvas = new createCanvas(10, 10);
JPanel mainPanel = new JPanel();
public createWindow()
{
mainPanel.add(canvas, BorderLayout.CENTER);
}
}
createCanvas is a class which declares a paintComponent;
public class createCanvas extends JPanel
{
int xValue;
int yValue;
int xCoordinate;
int yCoordinate;
public createCanvas(int x, int y)
{
xValue = x;
yValue = y;
}
public void setXCoordinate(int x)
{
xCoordinate = x;
}
public void setYCoordinate(int y)
{
yCoordinate = y;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
drawGrid(g, this.xValue, this.yValue);
g.fillArc(xCoordinate, yCoordinate, 6, 6, 0, 360);
}
public drawGrid(Graphics g, int xLength, int yLength)
{
//creates a grid that is xLength x yLength
}
}
However, I also have a selection of Objects which I want to have a .draw() function, which can use the paintComponent in createCanvas.
The problem is, of course, when I need to draw the node on the grid, I can set the coordinates, but how do I display the node on the canvas I declared in createWindow?
public class Node()
{
int xCoordinate;
int yCoordinate;
//Suitable constructors, sets, gets
public void draw()
{
createCanvas canvas = new createCanvas();
canvas.setXCoordinate(this.xCoordinate);
canvas.setYCoordinate(this.yCoordinate);
canvas.repaint();
}
}
So, I am wondering if there is a way for me to keep what I have drawn on the canvas in createWindow, as well as what I draw in my Object class.
Thanks.

What you want to do is have the draw method in your object take a Graphics argument. This Graphics object will be the same Graphics context in your paintComponent method. You can create the object in your JPanel class. Something like this
public class Circle {
int x, y;
public Circle(int x, int y) {
this.x = x;
this.y = y;
}
public void drawCirlce(Graphics g) {
g.fillRect(x, y, 50, 50);
}
}
Then in you JPanel class
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}
You can have a setter for the x and y in your Circle class. You should change them somewhere in your JPanel class then call repaint() afterwards. You could move it with the press of a key or you can animate it with a java.util.Timer. For example
With a Timer
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
public CirclePanel() {
Timer timer = new Timer(50, new ActionListener(){
#Override
public void actionPerfomed(ActionEvent e) {
circle.x += 10;
repaint();
}
});
timer.start();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}
With a key binding
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
public CirclePanel() {
InputMap inputMap = getInputMap(JComponent.WHEN_FOCUSED_IN_WINDOW);
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "moveRight");
getActionMap().put("moveRight", new AbstractAction(){
public void actionPerformed(ActionEvent e) {
circle.x += 10;
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}
With a button press
public class CirclePanel extends JPanel {
Circle circle = new Circle(100, 100);
public CirclePanel() {
JButton button = new JButton("Move Right");
button.addActionListener(new ActionListener(){
public void actionPerformed(ActionEvent e) {
circle.x += 10;
repaint();
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
circle.drawCircle(g);
}
}

Related

How do you move the square to whitch it is bieng pressed

I'm currently working on a project for a snake game, and I need help on moving the Snake Square that I created. This is what I did to create the square:
import javax.swing.*;
import java.awt.*;
public class ShapeTest extends JFrame{
public ShapeTest(){
setSize(300,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String a[]){
new ShapeTest();
}
public void paint(Graphics g){
g.drawRect(80, 30, 100, 100); // FOR SQUARE
}
}
So now on my main Snake Class I want to move the square sort of like an Action. I would love you all so much if you could help me! Thank you so much!
Here is my main Snake Class:
import javax.swing.*;
import java.awt.*;
public class ShapeTest extends JFrame{
public ShapeTest(){
setSize(300,400);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String a[]){
new ShapeTest();
}
public void paint(Graphics g){
g.drawRect(80, 30, 100, 100); // FOR SQUARE
}
}
Edit: Is this the right path?
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// do some action
}
});
Thankyou so much i understand now! Love you guys!
That is not how you do custom painting. Don't override the paint() method of a JFrame.
Custom painting is done by overriding the paintComponent() of a JPanel and then you add the panel to the frame.
Check out the section from the Swing tutorial on Custom Painting. The example in the tutorial will show you how to better structure your code. It also shows how to paint a square where you click with the mouse.
As promised, here is my example. The most important things:
I overrode paintComponent(), not paint(), of a JPanel
The Sprite-class has the variables x, y, width, height and the corresponding getters & setters.
The Sprite-class has the method draw(Graphics g) which allows the panel to draw the Sprite
The Sprite-class has the methods moveLeft(), moveRight(), moveUp() and moveDown(), each changing the x/y variable accordingly.
I added Key Bindings to the panel in order to call the methods mentioned at point 4. when the corresponding arrow-keys are pressed. Please read the link for a further explanation of Key Bindings.
Code:
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.KeyEvent;
import javax.swing.*;
public class Example {
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new Example();
}
});
}
public Example() {
JFrame frame = new JFrame("Example");
Sprite sprite = new Sprite(50, 50, 10, 10);
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
sprite.draw(g);
}
};
// Key Bindings
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_LEFT, 0), "left");
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "right");
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_UP, 0), "up");
panel.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_DOWN, 0), "down");
panel.getActionMap().put("left", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
sprite.moveLeft();
panel.repaint();
}
});
panel.getActionMap().put("right", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
sprite.moveRight();
panel.repaint();
}
});
panel.getActionMap().put("up", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
sprite.moveUp();
panel.repaint();
}
});
panel.getActionMap().put("down", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent arg0) {
sprite.moveDown();
panel.repaint();
}
});
frame.setContentPane(panel);
frame.setSize(300, 200);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public class Sprite {
private int x, y, width, height;
protected Sprite(int x, int y, int width, int height) {
setX(x);
setY(y);
setWidth(width);
setHeight(height);
}
protected void draw(Graphics g) {
g.setColor(Color.RED);
g.fillRect(getX(), getY(), getWidth(), getHeight());
}
protected void moveLeft() {
setX(getX() - 10);
}
protected void moveRight() {
setX(getX() + 10);
}
protected void moveUp() {
setY(getY() - 10);
}
protected void moveDown() {
setY(getY() + 10);
}
protected int getX() {
return x;
}
protected void setX(int x) {
this.x = x;
}
protected int getY() {
return y;
}
protected void setY(int y) {
this.y = y;
}
protected int getWidth() {
return width;
}
protected void setWidth(int width) {
this.width = width;
}
protected int getHeight() {
return height;
}
protected void setHeight(int height) {
this.height = height;
}
}
}

Java mouseListener's mousemove not working

I am trying to make a plotting program, the program should show the point the user is currently on, i tried using mousemove for this function (using console for now to view result) but it's not working.
public class drawArea extends JPanel implements MouseListener {
Image img;
int w=580;
int h=580;
String equation = "";
int clicks = 0;
public drawArea(){
init();
this.addMouseListener(this);
}
private void init(){
setPreferredSize( new Dimension( w, h ) );
setVisible(true);
img = new ImageIcon("assets/Graph.png").getImage();
}
private void initializeGrid(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img, 0, 0, this);
}
private void drawFunction(Graphics g, String function) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.blue);
double p=0.01; //plotting precision
for(double x=-5;x<5;x+=p){
int drawingX1=gx((x));
int drawingY1=gy(f(x));
int drawingX2=gx(x+p);
int drawingY2=gy(f(x+p));
g2d.drawLine(drawingX1, drawingY1, drawingX2, drawingY2);
}
}
private double f(double x){
return x*x;
}
private int gx(double x){
return (int) ((x+5)*(w/10));
}
private int gy(double y){
return (int) (h-(y+5)*(h/10));
}
public void setEquation(String equ){
equation=equ;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
initializeGrid(g);
drawFunction(g,"Function");
}
public void mouseClicked(MouseEvent e) {
if(clicks<3){
MainUI.points[clicks][0] = e.getX();
MainUI.points[clicks][1] = e.getY();
System.out.println(e.getX()+","+e.getY());
System.out.println(MainUI.points[clicks] [0]+","+MainUI.points[clicks][1]);
clicks++;
}
}
public void mouseEntered(MouseEvent e) {
//not needed
}
public void mouseExited(MouseEvent arg0) {
//not needed
}
public void mousePressed(MouseEvent arg0) {
//not needed
}
public void mouseReleased(MouseEvent arg0) {
//not needed
}
public void mouseMoved(MouseEvent e) {
System.out.println(e.getX()+","+e.getY());
}
}
Thanks in Advance
MouseListener does not have a mouseMoved method.
You have to add the declaration that you are going to also implement the Mouse Motion Listener interface:
public class drawArea extends JPanel
implements MouseListener, MouseMotionListener
Additionally, you have to add this mouse motion listener in the constructor
this.addMouseMotionListener(this);

using paintComponent method in JApplet

I have create a program in Java which allows dragging of two oval shapes. Now I want to convert it to a JApplet so I made the class extend JApplet instead of original JPanel. The problem with this is that super.paintComponent(g) does not work as it is no longer a parent class.
I have tried creating a JPanel within the class then referring to this but I get the error: The method paintComponent(Graphics) from the type JComponent is not visible
Any heads up on what I need to do or any help would be much appreciated thanks.
Here is my code.
public class Main extends JPanel
{
private static final String TITLE = "Drag me!";
private static final int W = 640;
private static final int H = 480;
private Point origin = new Point(W / 2, H / 2);
private Point mousePt;
public Main() {
this.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
this.addMouseListener(new MouseAdapter()
{
#Override
public void mousePressed(MouseEvent e)
{
mousePt = e.getPoint();
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter()
{
#Override
public void mouseDragged(MouseEvent e)
{
int dx = e.getX() - mousePt.x;
int dy = e.getY() - mousePt.y;
origin.setLocation(origin.x + dx, origin.y + dy);
mousePt = e.getPoint();
repaint();
}
});
}
#Override
public Dimension getPreferredSize() {
return new Dimension(W, H);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawOval(0, origin.y, getWidth(), origin.y);
g.drawOval(origin.x, 0, origin.x, getHeight());
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame f = new JFrame(TITLE);
f.add(new Main());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setLocationRelativeTo(null);
f.setVisible(true);
}
});
}
}
Instead of modifying your JPanel, keep it and create a new class, your JApplet class:
public class YourJApplet extends JApplet{
public void init(){
final JPanel panel = new YourPanel();
this.setContentPane(panel);
}
}
That's it--now whatever was going on with your panel is now your JApplet.

adding squares to an animation

I'm trying to create a program that runs an animation similar to the one on this video but I'm having trouble adding more squares. I tried to add all the squares to an array list but I couldn't figure out where it goes.
so far this is my code:
public class Animation extends JFrame{
CrazySquares square = new CrazySquares();
Animation(){
add(new CrazySquares());
}
public static void main (String[] args){
Animation frame = new Animation();
frame.setTitle("AnimationDemo");
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(250, 250);
frame.setVisible(true);
}
}
class CrazySquares extends JPanel{
private final int numberOfRectangles=100;
Color color=new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
private int x=1;
private int y=1;
private Timer timer = new Timer(30, new TimerListener());
Random random= new Random();
int randomNumber=1+(random.nextInt(4)-2);
Random rand= new Random();
int rando=1+(rand.nextInt(4)-2);
CrazySquares(){
timer.start();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width=getWidth();
int height=getHeight();
g.setColor(color);
g.fillRect(x+width/2,y+(int)(height*.47), 20, 20);
}
class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
x += rando;
y+= randomNumber;
repaint();
}
}
}
You've got code to paint out one rectangle, here:
int width=getWidth();
int height=getHeight();
g.setColor(color);
g.fillRect(x+width/2,y+(int)(height*.47), 20, 20);
Now what I would recommend, would be that you port these values into a Square object. Or, better yet, use the Rectangle object. If you went with the custom approach:
public class Square
{
public Square(int x, int y, int height, int width)
{
// Store these values in some fields.
}
public void paintComponent(Graphics g)
{
g.fillRect() // Your code for painting out squares.
}
}
Then, all you need to do, is call each object's paintComponent method in some list. Let's assume you have some List:
List<Square> squares = new ArrayList<Square>();
for(Square sq : squares)
{
sq.paintComponent(g);
}
this is the code so far. I know its nasty but its because i've been trying different things a none of them work. i really appreciate your help. thanks. #ChrisCooney
public class SquaresAnimation extends JFrame{
SquaresAnimation(){
add(new CrazySquares());
}
public static void main (String[] args){
SquaresAnimation frame = new SquaresAnimation();
frame.setTitle("AnimationDemo");
frame.setLocationRelativeTo(null); // Center the frame
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(250, 250);
frame.setVisible(true);
}
}
class Square{
private int x;
private int y;
public int height;
public int width;
Square(int x, int y, int height, int width)
{
// Store these values in some fields.
this.x=x;
this.y=y;
this.height=height;
this.width=width;
}
public void paintComponent(Graphics g)
{
g.setColor(Color.CYAN);
g.fillRect(x+width/2,y+(int)(height*.47), 20, 20);
}
}
class CrazySquares extends JPanel {
private final int numberOfRectangles=100;
Color color=new Color((int)(Math.random()*256),(int)(Math.random()*256),(int)(Math.random()*256));
private int x=1;
private int y=1;
Random random= new Random();
int randomNumber=1+(random.nextInt(4)-2);
Random rand= new Random();
int rando=1+(rand.nextInt(4)-2);
private Timer timer = new Timer(30, new TimerListener());
List<Square> squares = new ArrayList<Square>();
CrazySquares(Graphics g){
timer.start();
for(Square sq : squares){
sq.paintComponent(g);
}
}
}
//protected void paintComponent(Graphics g) {
//super.paintComponent(g);
// }
class TimerListener implements ActionListener {
#Override
public void actionPerformed(ActionEvent e) {
repaint();
}
}

Java Racing game: JPanel component moves along when I repaint the car object

I created 2 car objects using my CarPanel. Then I used to keylistener to repaint the object so it will look like moving forward.
But the problem is the whole panel moves along, even though I just increased the distance to the 'x' coordinate.
If I were to resize the window, it sometimes doesn't even clear the component.
public class RacingCars extends JFrame {
CarPanel car1;
CarPanel car2;
//Constructor
public RacingCars(){
setLayout(new GridLayout(2,1));
car1 = new CarPanel('w',Color.RED);
car2 = new CarPanel('k',Color.blue);
car1.setBackground(Color.black);
this.add(car1, BorderLayout.NORTH);
this.add(car2, BorderLayout.SOUTH);
this.addKeyListener(new keyListener());
}
class keyListener extends KeyAdapter{
public void keyPressed(KeyEvent e){
if(e.getKeyChar()=='w'){
car1.moveCar();
}
if(e.getKeyChar()=='k'){
car2.moveCar();
}
}
}
}
CarPanel::
public class CarPanel extends JPanel {
private char forwardKey = 'w';
private boolean reachedTarget = false;
private Color color = Color.blue;
private int x= 10;
private int y= 10;
private int panelWidth;
private int panelHeight;
//default Constructor
public CarPanel(){
}
//overloaded Constructor
public CarPanel(char key, Color color){
this.forwardKey=key;
this.color = color;
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
panelWidth= getWidth();
panelHeight= getHeight();
//draw a Car
g.setColor(color);
//polygon points
int t_x[]= {x+10,x+20,x+30,x+40};
int t_y[]= {y+10,y,y,y+10};
g.fillPolygon(t_x,t_y,t_x.length);
g.fillRect(x, y+10, 50, 10);
g.fillArc(x+10, y+20, 10, 10, 0, 360);
g.fillArc(x+30, y+20, 10, 10, 0, 360);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(750,100);
}
public void moveCar(){
if(this.x < panelWidth){
this.x+=10;
repaint();
}
}
}
Solution
Because of this code, I always had that extra space. but no idea how it supposed to cause to this strange behavior.
/*
public int getX(){
return this.x;
}
*/
But the problem is the whole panel moves along, ..
No it doesn't. The 'green dot' proves that.
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class RacingCars extends JFrame {
CarPanel car1;
CarPanel car2;
//Constructor
public RacingCars(){
setLayout(new GridLayout(2,1));
car1 = new CarPanel('w',Color.RED);
car2 = new CarPanel('k',Color.blue);
car1.setBackground(Color.black);
this.add(car1, BorderLayout.NORTH);
this.add(car2, BorderLayout.SOUTH);
this.addKeyListener(new MyKeyListener());
}
class MyKeyListener extends KeyAdapter{
public void keyPressed(KeyEvent e){
if(e.getKeyChar()=='w'){
car1.moveCar();
}
if(e.getKeyChar()=='k'){
car2.moveCar();
}
}
}
public static void main(String[] args) {
//Create the frame on the event dispatching thread
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
RacingCars rc = new RacingCars();
rc.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
rc.pack();
rc.setVisible(true);
}
});
}
}
class CarPanel extends JPanel {
private char forwardKey = 'w';
private boolean reachedTarget = false;
private Color color = Color.blue;
private int x= 10;
private int y= 10;
private int panelWidth;
private int panelHeight;
//default Constructor
public CarPanel(){
}
//overloaded Constructor
public CarPanel(char key, Color color){
this.forwardKey=key;
this.color = color;
}
protected void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.GREEN);
g.fillOval(0,0,25,25);
panelWidth= getWidth();
panelHeight= getHeight();
//draw a Car
g.setColor(color);
//polygon points
int t_x[]= {x+10,x+20,x+30,x+40};
int t_y[]= {y+10,y,y,y+10};
g.fillPolygon(t_x,t_y,t_x.length);
g.fillRect(x, y+10, 50, 10);
g.fillArc(x+10, y+20, 10, 10, 0, 360);
g.fillArc(x+30, y+20, 10, 10, 0, 360);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(750,100);
}
public void moveCar(){
if(this.x < panelWidth){
this.x+=10;
repaint();
}
}
}

Categories

Resources