I'm a beginner in learning this.Doing a test by drawing a triangle and now I want to move it.it's not working so I want to ask what's my mistake.Sorry it's long.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
public class Test extends JFrame {
private Triangle triangle;
private final int step = 10;
private Triangle keyboardPanel = new Triangle();
public static void main(String[] args)
{
Test t = new Test();
}
public Test()
{
setTitle("TRY TRY TRY");
setLocationRelativeTo(null); // Center the frame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 500, 500);
JPanel tripanel = new JPanel();
add(tripanel);
triangle = new Triangle();
tripanel.addKeyListener(null);
tripanel.addMouseListener(null);
tripanel.addMouseMotionListener(null);
setVisible(true);
}
static class move extends JPanel implements KeyListener,MouseListener, MouseMotionListener{
private int x = 210;
private int y = 210;
private Color color = Color.BLACK;
move()
{
addKeyListener(this);
addMouseListener(this);
addMouseMotionListener(this);
}
#Override
public void keyPressed(KeyEvent ke) {
int KeyCode = ke.getKeyCode();
System.out.println("key code is" +KeyCode);
/*switch (KeyCode)
{
case KeyEvent.VK_UP:
triangle.moveTriangle(-10, 0);
break;
case KeyEvent.VK_DOWN:
triangle.moveTriangle(10, 0);
break;
case KeyEvent.VK_LEFT:
triangle.moveTriangle(0, -10);
break;
case KeyEvent.VK_RIGHT:
triangle.moveTriangle(0, 10);
break;
}
repaint();*/
}
#Override
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("hello");
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
System.out.println("hello123");
if(e.isControlDown())
color = Color.RED;
else
color = Color.BLACK;
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
System.out.println(e.getPoint());
}
}
public void paint(Graphics g)
{
super.paint(g);
triangle.drawTriangle(g);
}
public void paintComponent(Graphics g)
{
super.paintComponents(g);
triangle.drawTriangle(g);
}
}
import java.awt.Graphics;
import javax.swing.JPanel;
public class Triangle {
private Point p1;
private Point p2;
private Point p3;
int numX;
int numY;
public Triangle()
{
p1 = new Point(200,200);
p2 = new Point(170,230);
p3 = new Point(230,230);
}
public void moveTriangle(int dx, int dy)
{
p1.move(dx, dy);
p2.move(dx, dy);
p3.move(dx, dy);
}
public void drawTriangle(Graphics g)
{
g.drawLine(p1.getX(), p1.getY(),p2.getX(),p2.getY());
g.drawLine(p2.getX(),p2.getY(),p3.getX(),p3.getY());
g.drawLine(p3.getX(), p3.getY(),p1.getX(),p1.getY());
}
}
public class Point {
private int x;
private int y;
public Point(int X, int Y)
{
x = X;
y = Y;
}
public void setX(int X)
{
x = X;
}
public void setY(int Y)
{
x = Y;
}
public int getX()
{
return x;
}
public int getY()
{
return y;
}
public void move(int dx, int dy)
{
x +=dx;
y +=dy;
}
public String toString()
{
return("X = "+x+" Y= "+y);
}
}
there are lot of problems in your code .when you coding always test current code before go further.
you create a panel and add to the jframe .
JPanel tripanel = new JPanel();
add(tripanel);
but your graphical mechanism has written in move panel so you need to make a move panel instead of jpanel.
keylistners has added to panel but keylisners not get triggered because keylistners work when component is focused . it works for component like jtextfiled . but not for panels .you have to use keybinding .i have added keybind for rightarrow key ..you have to add it to other keys up ,down etc..
also move your paint method from jframe to move jpanel .
example code (run this code and press right arrow ->)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.AbstractAction;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
public class Test extends JFrame {
private Triangle triangle;
private final int step = 10;
private Triangle keyboardPanel = new Triangle();
public static void main(String[] args) {
Test t = new Test();
}
public Test() {
setTitle("TRY TRY TRY");
setLocationRelativeTo(null); // Center the frame
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 500, 500);
JPanel tripanel = new move();
add(tripanel);
triangle = new Triangle();
setVisible(true);
}
class move extends JPanel implements MouseListener, MouseMotionListener {
private int x = 210;
private int y = 210;
private Color color = Color.BLACK;
move() {
addMouseListener(move.this);
addMouseMotionListener(move.this);
this.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW).put(KeyStroke.getKeyStroke(KeyEvent.VK_RIGHT, 0), "moveright");
this.getActionMap().put("moveright", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
triangle.moveTriangle(10, 0);
repaint();
}
});
}
#Override
public void mouseClicked(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseEntered(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseExited(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("hello");
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
// TODO Auto-generated method stub
}
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
System.out.println("hello123");
if (e.isControlDown()) {
color = Color.RED;
} else {
color = Color.BLACK;
}
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
// TODO Auto-generated method stub
//System.out.println(e.getPoint());
}
#Override
public void paint(Graphics g) {
super.paint(g);
triangle.drawTriangle(g);
}
}
class Triangle {
private Point p1;
private Point p2;
private Point p3;
int numX;
int numY;
public Triangle() {
p1 = new Point(200, 200);
p2 = new Point(170, 230);
p3 = new Point(230, 230);
}
public void moveTriangle(int dx, int dy) {
p1.move(dx, dy);
p2.move(dx, dy);
p3.move(dx, dy);
}
public void drawTriangle(Graphics g) {
g.drawLine(p1.getX(), p1.getY(), p2.getX(), p2.getY());
g.drawLine(p2.getX(), p2.getY(), p3.getX(), p3.getY());
g.drawLine(p3.getX(), p3.getY(), p1.getX(), p1.getY());
}
}
class Point {
private int x;
private int y;
public Point(int X, int Y) {
x = X;
y = Y;
}
public void setX(int X) {
x = X;
}
public void setY(int Y) {
x = Y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public void move(int dx, int dy) {
x += dx;
y += dy;
}
public String toString() {
return ("X = " + x + " Y= " + y);
}
}
}
output >>
Related
I'm trying to make a game with ducks, the ducks are moving on the screen and I can't get a mouse click on them. I'm obviously doing something wrong because despite setting a MouseListener, its methods are not called. This is my code, I omitted getters and the DuckGame class, which is only generating ducks.
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
public class DuckGameScreen extends JPanel {
private int initialDuckNum = 7;
private final int INTERVAL = 25;
private final int INTERVAL_BTWN_DUCKS = 1000;
private Timer duckTimer;
private int ducksStarted = 0;
private DuckGame duckGame;
public DuckGameScreen() {
setBackground(Color.cyan);
askAboutDifficulty();
startTimer();
startGame();
startDifficultyIncrease();
}
private void startGame() {
duckGame = new DuckGame(initialDuckNum);
startDucks();
addDuckListeners();
}
private void addDuckListeners() {
for (Duck duck : duckGame.getDucks()) {
duck.addMouseListener(new MouseListener() {
#Override
public void mouseClicked(MouseEvent e) {}
#Override
public void mousePressed(MouseEvent e) {
System.out.println("Duck clicked");}
#Override
public void mouseReleased(MouseEvent e) {}
#Override
public void mouseEntered(MouseEvent e) {}
#Override
public void mouseExited(MouseEvent e) {}
});
}
}
#Override
public void paint(Graphics g) {
super.paint(g);
drawDucks(g);
Toolkit.getDefaultToolkit().sync();
}
private void animateDuck(Duck duck) {
new Thread() {
#Override
public void run() {
super.run();
while (!duck.isDuckStopped()) {
try {
Thread.sleep(INTERVAL);
duck.move();
if (duck.getX() - duck.getWidth() >= Toolkit.getDefaultToolkit().getScreenSize().width) {
duck.resetPosition();
}
repaint();
} catch (InterruptedException e) {
e.printStackTrace();
duck.stop();
break;
}
}
}
}
.start();
}
private void drawDucks(Graphics g) {
for (Duck duck : duckGame.getDucks()) {
duck.paintComponent(g);
}
}
}
And my Duck class:
public class Duck extends JComponent {
private final static int INIT_X = -100;
private int x = INIT_X;
private int y = 100;
private int width = 0;
private int height = 0;
private Image image = null;
private boolean isDuckStopped = false;
private final int STEP = 5;
public Duck() {
initRandomPosition();
loadImage();
setVisible(true);
setBounds(x, y, width, height);
}
private void initRandomPosition() {
y = getRandomY();
}
public void move() {
x += STEP;
}
private void loadImage() {
ImageIcon imageIcon = new ImageIcon(getFilePath(Images.DUCK.getFileName()));
Dimension newDimension = Utils.getScaledDimension(100, 100, imageIcon.getIconWidth(), imageIcon.getIconHeight());
image = imageIcon.getImage().getScaledInstance(newDimension.width, newDimension.height, Image.SCALE_DEFAULT);
width = image.getWidth(null);
height = image.getHeight(null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponents(g);
drawDuck(g);
Toolkit.getDefaultToolkit().sync();
}
private void drawDuck(Graphics g) {
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(image, x, y, this);
setBounds(x, y, width, height);
}
public void stop() {
isDuckStopped = true;
setVisible(false);
}
public void resetPosition() {
x = INIT_X;
y = getRandomY();
}
}
Here I have two classes, one including main function. I want to draw a rectangle which moves automatically. But the starting point of rectangle is not the same as the point i clicked with mouse. I could not figure out this problem. Can you help me?
This is the first class including main function
import java.awt.Graphics;
import java.awt.event.*;
import javax.swing.*;
public class BuyuyenSuDamlalari extends JPanel implements ActionListener {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setSize(600,400);
BuyuyenSuDamlalari bsd1 = new BuyuyenSuDamlalari();
frame.setContentPane(bsd1);
BuyuyenSuDamlalariClickListener bscl = new BuyuyenSuDamlalariClickListener(bsd1);
bsd1.addMouseListener(bscl);
frame.setResizable(false);
frame.setDefaultCloseOperation(frame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
int x;
int y;
int radius;
int click;
public BuyuyenSuDamlalari() {
super();
setFocusable(true);
Timer zaman = new Timer(40, this); // bir saniyede 25 resim oluyor
zaman.start();
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (click>0) {
g.drawRect(x, y, radius, radius);
}
}
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;
}
public void actionPerformed(ActionEvent arg0) {
radius++;
repaint();
}
public void setClick(int click) {
this.click = click;
}
}
This is the second class wihich includes motionListener
import java.awt.event.*;
public class BuyuyenSuDamlalariClickListener extends MouseAdapter {
private BuyuyenSuDamlalari bsd = new BuyuyenSuDamlalari();
private int x;
private int y;
public BuyuyenSuDamlalariClickListener(BuyuyenSuDamlalari bsd) {
super();
this.bsd = bsd;
}
public void mousePressed(MouseEvent e) {
if (e.getClickCount()>0) {
bsd.setX(e.getX()-25);
bsd.setY(e.getY()-25);
}
bsd.setClick(1);
}
}
I have a project that a circle goes with random x and y values and with selected colors but when the user pressed the space bar the color of the circle must be changed. My circle moves both x and y coordinate and I want to change the color of the circle when I press the space button. But it does not work when I pressed it. It goes with its original color. So how can I make this code right?
public class c {
private int x,y,r;
private Color co;
private int Re,G,B;
private Random ran;
public c() {
// TODO Auto-generated constructor stub
ran= new Random();
x=100;
y=50;
r= ran.nextInt(200)+50;
Re=ran.nextInt(255);
G=ran.nextInt(255);
B=ran.nextInt(255);
co= new Color(Re,G,B);
}
public int getRe() {
return Re;
}
public int getG() {
return G;
}
public int getB() {
return B;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getR() {
return r;
}
public void setCo(int Re,int G,int B) {
co= new Color(Re,G,B);
}
public Color getCo() {
return co;
}
public Random getRan() {
return ran;
}
public void setX(int x) {
this.x=x;
}
public void setY(int y) {
this.y=y;
}
}
public class Circle extends JFrame implements ActionListener,KeyListener{
private Timer timer;
private int x,y,a=5,b=5;
private Random rand;
c circ = new c();
public Circle() {
setLayout(new BorderLayout());
x=circ.getX();
y=circ.getY();
timer=new Timer(50,this);
timer.start();
addKeyListener(this);
setSize(550,550);
setVisible(true);
}
public void paint(Graphics g) {
super.paint(g);
g.fillOval(x,y,100,100);
g.setColor(circ.getCo());
}
public static void main(String[]args) {
new Circle();
}
#Override
public void actionPerformed(ActionEvent e) {
moveWithTimer();
repaint();
}
public void moveWithTimer() {
x=x+b;
y=y+a;
if(x<0) {
b=5;
}
if(x+50>500) {
b=-5;
}
if(y<0){
a=5;
}
if(y+50>500) {
a=-5;
}
}
#Override
public void keyPressed(KeyEvent e) {
// TODO Auto-generated method stub
if(e.getKeyCode()==e.VK_SPACE) {
circ.setCo(rand.nextInt(255),rand.nextInt(255),rand.nextInt(255));
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
But it does not work when I pressed it. It goes with its original color. So how can I make this code right?
KeyListener is fickle, better to use the Key Bindings API which overcomes the primary, focus related, issues of KeyListener
As a general rule of thumb, you shouldn't override paint of top level containers like JFrame, they are compound components and it's just a real mess.
Instead, start with a JPanel and override it's paintComponent method. It's generally more flexible. Have a look at Performing Custom Painting for more details.
Your movement code is wrong. You assign the x/y values of the circle class to some other variables, the problem here is, changing the values of these variables will have no affect on the variables in you circle class, instead, you need assign them back...
public void moveWithTimer() {
int x = circ.getX();
int y = circ.getY();
x = x + b;
y = y + a;
if (x < 0) {
b = 5;
}
if (x + 50 > 500) {
b = -5;
}
if (y < 0) {
a = 5;
}
if (y + 50 > 500) {
a = -5;
}
circ.setX(x);
circ.setY(y);
}
Your "circle" class could also use a couple of additional methods. One to randomise the color (it already has a Random object, might as well use it) and one to paint the object.
public class Circle {
//...
public void paint(Graphics2D g2d) {
g2d.setColor(co);
g2d.fillOval(x, y, r * 2, r * 2);
}
//...
public void randomColor() {
setCo(ran.nextInt(255), ran.nextInt(255), ran.nextInt(255));
}
//...
}
If it was me, I'd be tempted to add a move method as well, but that's me ;)
As a runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.Random;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.Timer;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Timer timer;
private int a = 5, b = 5;
private Random rand;
private Circle circ = new Circle();
public TestPane() {
timer = new Timer(50, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
moveWithTimer();
repaint();
}
});
timer.start();
InputMap im = getInputMap(WHEN_IN_FOCUSED_WINDOW);
ActionMap am = getActionMap();
im.put(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0), "spaced");
am.put("spaced", new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
circ.randomColor();
repaint();
}
});
}
public void moveWithTimer() {
int x = circ.getX();
int y = circ.getY();
x = x + b;
y = y + a;
if (x < 0) {
b = 5;
}
if (x + 50 > 500) {
b = -5;
}
if (y < 0) {
a = 5;
}
if (y + 50 > 500) {
a = -5;
}
circ.setX(x);
circ.setY(y);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(500, 500);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
circ.paint(g2d);
g2d.dispose();
}
}
public class Circle {
private int x, y, r;
private Color co;
private int Re, G, B;
private Random ran;
public Circle() {
// TODO Auto-generated constructor stub
ran = new Random();
x = 100;
y = 50;
r = ran.nextInt(50) + 50;
Re = ran.nextInt(255);
G = ran.nextInt(255);
B = ran.nextInt(255);
co = new Color(Re, G, B);
}
public void paint(Graphics2D g2d) {
g2d.setColor(co);
g2d.fillOval(x, y, r * 2, r * 2);
}
public int getRe() {
return Re;
}
public int getG() {
return G;
}
public int getB() {
return B;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
public int getR() {
return r;
}
public void randomColor() {
setCo(ran.nextInt(255), ran.nextInt(255), ran.nextInt(255));
}
public void setCo(int Re, int G, int B) {
co = new Color(Re, G, B);
}
public Color getCo() {
return co;
}
public Random getRan() {
return ran;
}
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
}
}
I suggest you should set the color of the graphics object within paint(g) before painting the circle.
public void paint(Graphics g) {
super.paint(g);
g.setColor(circ.getCo());
g.fillOval(x,y,100,100);
}
In general, you should not override the paint() method of the JFrame. Instead, create a JPanel, add it to your frame and override the paintComponent() method of the panel.
I have a problem with repaint() method in my Java code. I want to call it in another class but I can't, something doesn't work at all. I've searched on forums, but nothing was able to help me out.
My Main class:
public class Main {
public static Main main;
public static JFrame f;
public Main(){
}
public static void main(String[] args) {
main = new Main();
f = new JFrame();
Ball b = new Ball();
f.getContentPane().setBackground(Color.GRAY);
f.add(b);
f.setSize(500, 500);
f.setLocationRelativeTo(null);
f.setTitle("Test");
f.setVisible(true);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.addMouseMotionListener(b);
f.addKeyListener(new Key());
}
}
Ball class where I created 2DGraphics for moving shapes:
public class Ball extends JLabel implements MouseMotionListener{
public Ball(){
}
public static double x = 10;
public static double y = 10;
public static double width = 40;
public static double height = 40;
String nick;
boolean isEllipse = true;
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if(isEllipse){
Ellipse2D e2d = new Ellipse2D.Double(x, y, width, height);
g2d.setColor(Color.RED);
g2d.fill(e2d);
}
else{
Rectangle2D r2d = new Rectangle2D.Double(x, y, width, height);
g2d.setColor(Color.GREEN);
g2d.fill(r2d);
}
}
#Override
public void mouseDragged(MouseEvent e) {
isEllipse = false;
x = e.getX() - 30;
y = e.getY() - 40;
this.repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
x = e.getX() - 30;
y = e.getY() - 40;
isEllipse = true;
this.repaint();
}
}
And Key class where I put KeyListener for move the shapes by key pressing:
public class Key extends Ball implements KeyListener {
public Key() {
}
#SuppressWarnings("static-access")
#Override
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
super.x += 10;
super.repaint();
System.out.println("x: " + super.x);
}
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
#Override
public void keyTyped(KeyEvent e) {
// TODO Auto-generated method stub
}
}
But something is wrong with this code: super method doesn't work for Key class. Everything in Ball class is working well. Where is the problem?
Super works fine, but your interpretation of what it does is wrong. Your problem is that you're trying to use inheritance to solve a problem that isn't solved with inheritance. You need to call repaint() on the actual visualized and used Ball instance, not on an instance of some completely different class, Key, that inappropriately extends from Ball. First off, make Key not extend Ball, pass in a true Ball reference into Key and the solution will fall from that.
Perhaps do something like this:
f.addKeyListener(new Key(b));
and
public class Key implements KeyListener {
private Ball ball;
public Key(Ball ball) {
this.ball = ball;
}
public void keyPressed(KeyEvent e) {
if(e.getKeyCode() == KeyEvent.VK_W){
b.incrX(10); // give Ball a public method for this
b.repaint();
// System.out.println("x: " + super.x);
}
}
// .... etc...
Note, myself, I'd use Key Bindings for this, not a KeyListener, since then I wouldn't have to futz with keyboard focus.
For example:
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.*;
import javax.swing.AbstractAction;
import javax.swing.ActionMap;
import javax.swing.InputMap;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
public class MoveBall {
private static final int PREF_W = 500;
private static final int PREF_H = PREF_W;
private static void createAndShowGui() {
BallPanel ballPanel = new BallPanel(PREF_W, PREF_H);
MyMouse myMouse = new MyMouse(ballPanel);
ballPanel.addMouseListener(myMouse);
ballPanel.addMouseMotionListener(myMouse);
new CreateKeyBindings(ballPanel);
JFrame frame = new JFrame("MoveBall");
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.getContentPane().add(ballPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> {
createAndShowGui();
});
}
}
#SuppressWarnings("serial")
class BallPanel extends JPanel {
private static final Color ELLIPSE_COLOR = Color.RED;
private static final Color SQUARE_COLOR = Color.GREEN;
private static final int BALL_WIDTH = 40;
private int prefW;
private int prefH;
private boolean isEllipse = true;
private int ballX;
private int ballY;
public BallPanel(int prefW, int prefH) {
this.prefW = prefW;
this.prefH = prefH;
}
public boolean isEllipse() {
return isEllipse;
}
public void setEllipse(boolean isEllipse) {
this.isEllipse = isEllipse;
}
public int getBallX() {
return ballX;
}
public void setBallX(int ballX) {
this.ballX = ballX;
}
public void setXY(int x, int y) {
ballX = x;
ballY = y;
repaint();
}
public void setXYCenter(int x, int y) {
ballX = x - BALL_WIDTH / 2;
ballY = y - BALL_WIDTH / 2;
repaint();
}
public void setXYCenter(Point p) {
setXYCenter(p.x, p.y);
}
public int getBallY() {
return ballY;
}
public void setBallY(int ballY) {
this.ballY = ballY;
}
public void incrementBallX(int x) {
ballX += x;
repaint();
}
public void incrementBallY(int y) {
ballY += y;
repaint();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
if (isEllipse) {
g2.setColor(ELLIPSE_COLOR);
g2.fillOval(ballX, ballY, BALL_WIDTH, BALL_WIDTH);
} else {
g2.setColor(SQUARE_COLOR);
g2.fillOval(ballX, ballY, BALL_WIDTH, BALL_WIDTH);
}
}
#Override
public Dimension getPreferredSize() {
if (isPreferredSizeSet()) {
return super.getPreferredSize();
}
return new Dimension(prefW, prefH);
}
}
class MyMouse extends MouseAdapter {
private BallPanel ballPanel;
public MyMouse(BallPanel ballPanel) {
this.ballPanel = ballPanel;
}
#Override
public void mousePressed(MouseEvent e) {
ballPanel.setXYCenter(e.getPoint());
}
#Override
public void mouseDragged(MouseEvent e) {
ballPanel.setXYCenter(e.getPoint());
}
#Override
public void mouseReleased(MouseEvent e) {
ballPanel.setXYCenter(e.getPoint());
}
}
enum Direction {
UP(KeyEvent.VK_UP), DOWN(KeyEvent.VK_DOWN), LEFT(KeyEvent.VK_LEFT), RIGHT(KeyEvent.VK_RIGHT);
private int key;
private Direction(int key) {
this.key = key;
}
public int getKey() {
return key;
}
}
// Actions for the key binding
#SuppressWarnings("serial")
class MyKeyAction extends AbstractAction {
private static final int STEP_DISTANCE = 5;
private BallPanel ballPanel;
private Direction direction;
public MyKeyAction(BallPanel ballPanel, Direction direction) {
this.ballPanel = ballPanel;
this.direction = direction;
}
#Override
public void actionPerformed(ActionEvent e) {
switch (direction) {
case UP:
ballPanel.incrementBallY(-STEP_DISTANCE);
break;
case DOWN:
ballPanel.incrementBallY(STEP_DISTANCE);
break;
case LEFT:
ballPanel.incrementBallX(-STEP_DISTANCE);
break;
case RIGHT:
ballPanel.incrementBallX(STEP_DISTANCE);
break;
default:
break;
}
}
}
class CreateKeyBindings {
private BallPanel ballPanel;
public CreateKeyBindings(BallPanel ballPanel) {
this.ballPanel = ballPanel;
int condition = JComponent.WHEN_IN_FOCUSED_WINDOW;
InputMap inputMap = ballPanel.getInputMap(condition);
ActionMap actionMap = ballPanel.getActionMap();
for (Direction direction : Direction.values()) {
KeyStroke keyStroke = KeyStroke.getKeyStroke(direction.getKey(), 0);
String keyString = keyStroke.toString();
inputMap.put(keyStroke, keyString);
actionMap.put(keyString, new MyKeyAction(ballPanel, direction));
}
}
}
Pong.Java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
public class Pong {
private static final int WIDTH = 900, HEIGHT = 700;
JFrame win = new JFrame();
Paddle paddleOne = new Paddle(1);
Paddle paddleTwo = new Paddle(2);
Graphics g;
Pong(){
init();
}
void init(){
win.setTitle("PONG");
win.setSize(WIDTH, HEIGHT);
win.addKeyListener(keyListener);
win.setLocationRelativeTo(null);
win.getContentPane().setBackground(Color.black);
win.setVisible(true);
win.getContentPane().validate();
win.repaint();
}
public void paintComponent(Graphics g){
g.setColor(Color.white);
g.fillRect(paddleOne.getX(), paddleOne.getY(), paddleOne.getHEIGHT(), paddleOne.getWIDTH());
System.out.println("drawn");
}
KeyListener keyListener = new KeyListener() {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch(key){
case 87:
System.out.println("Player 1 Up");
break;
case 83:
System.out.println("Player 1 Down");
break;
case 38:
System.out.println("Player 2 Up");
break;
case 40:
System.out.println("Player 2 Down");
break;
}
win.getContentPane().validate();
win.repaint();
}
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
};
public static void main(String[] args) {
Pong p = new Pong();
}
}
Paddle.Java
public class Paddle{
private int WIDTH = 50, HEIGHT = 150, X, Y;
int playerNum;
Paddle(int playerNum){
if(playerNum == 1){
X = 10;
Y = 10;
}else if (playerNum == 2){
X = 500;
Y = 10;
}
}
public void setX(int x){
X = x;
}
public void setY(int y){
Y = y;
}
public int getWIDTH() {
return WIDTH;
}
public int getHEIGHT() {
return HEIGHT;
}
public int getX() {
return X;
}
public int getY() {
return Y;
}
}
I'm relatively new to Java programming, or more specifically Awt & Swing, what my question is, why isn't my rectangle drawing? Any help is appreciated. Thank you so much!
In order for something to be painted within in Swing, it first must extend from something Swing know's how to paint, this commonly means a JComponent (or more typically a JPanel).
Then you can override one of the paint methods, which is called by the painting subsystem, in this case, it's generally preferred to override paintComponent, but don't forget to call super.paintComponent before you do any custom painting, or you're setting yourself up for some weird and generally unpredictable painting issues.
Take a look at Painting in AWT and Swing and Performing Custom Painting for more details.
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Pongo {
public static void main(String[] args) {
new Pongo();
}
public Pongo() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new PongPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class PongPane extends JPanel {
private static final int WIDTH = 900, HEIGHT = 700;
Paddle paddleOne = new Paddle(1);
Paddle paddleTwo = new Paddle(2);
public PongPane() {
setBackground(Color.BLACK);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(paddleOne.getX(), paddleOne.getY(), paddleOne.getHEIGHT(), paddleOne.getWIDTH());
//System.out.println("drawn"); //Should not put something here which may overhead.
}
}
public class Paddle {
private int WIDTH = 50, HEIGHT = 150, X, Y;
int playerNum;
Paddle(int playerNum) {
if (playerNum == 1) {
X = 10;
Y = 10;
} else if (playerNum == 2) {
X = 500;
Y = 10;
}
}
public void setX(int x) {
X = x;
}
public void setY(int y) {
Y = y;
}
public int getWIDTH() {
return WIDTH;
}
public int getHEIGHT() {
return HEIGHT;
}
public int getX() {
return X;
}
public int getY() {
return Y;
}
}
}
I would also discourage the use of KeyListener within this context and inside advice the use of the key bindings API, it doesn't suffer from the same focus related issues that KeyListener does. See How to Use Key Bindings for more details
You need to overriding paintComponents to draw.
Here is your Pong.java
import java.awt.Color;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
public class Pong {
private static final int WIDTH = 900, HEIGHT = 700;
JFrame win = new JFrame();
Paddle paddleOne = new Paddle(1);
Paddle paddleTwo = new Paddle(2);
Graphics g;
Pong() {
init();
}
void init() {
win.setTitle("PONG");
win.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
win.setSize(WIDTH, HEIGHT);
win.addKeyListener(keyListener);
win.setLocationRelativeTo(null);
win.add(new Panel(paddleOne));
win.getContentPane().setBackground(Color.black);
win.setVisible(true);
win.getContentPane().validate();
win.repaint();
}
KeyListener keyListener = new KeyListener() {
public void keyPressed(KeyEvent e) {
int key = e.getKeyCode();
switch (key) {
case 87:
System.out.println("Player 1 Up");
break;
case 83:
System.out.println("Player 1 Down");
break;
case 38:
System.out.println("Player 2 Up");
break;
case 40:
System.out.println("Player 2 Down");
break;
}
win.getContentPane().validate();
win.repaint();
}
public void keyReleased(KeyEvent arg0) {
// TODO Auto-generated method stub
}
public void keyTyped(KeyEvent arg0) {
// TODO Auto-generated method stub
}
};
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Pong();
}
});
}
}
Here Panel.java in where paintComponent overridden.
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JPanel;
public class Panel extends JPanel{
private Paddle paddleOne;
public Panel(Paddle pdl) {
paddleOne = pdl;
}
#Override
public void paintComponent(Graphics g){
super.paintComponent(g);
g.setColor(Color.white);
g.fillRect(paddleOne.getX(), paddleOne.getY(), paddleOne.getHEIGHT(), paddleOne.getWIDTH());
//System.out.println("drawn"); //Should not put something here which may overhead.
}
}