I've done this plenty of times but I'm stuck. I've checked previous projects of mine and can't find the answer. The rectangle is supposed to show up at 400,400 and be 100,100 big, (Bottom right corner). When the start button is press I want it to show the rectangle. Thanks in advance!
!!!: There are multiple classes in this I just didn't post them since they don't have a use, if they do I'll post them.
class MazeRunner extends JFrame implements ActionListener, MouseMotionListener {
JButton b1;
int pkp = 0;
MazeRunner(){
b1= new JButton("Start");
add(b1);
b1.addActionListener(this);
b1.setBounds(10,10,50,50);
addMouseMotionListener(this);
setTitle("Maze Runner");
setLayout(null);
setSize(500, 500);
setResizable(false);
setVisible(true);
}
public static void main(String[] args) {
new MazeRunner();
}
#Override
public void actionPerformed(ActionEvent e) {
if(e.getSource() == b1){
remove(b1);
pkp++;
validate();
repaint();
}
}
#Override
public void mouseDragged(MouseEvent e) {
}
#Override
public void mouseMoved(MouseEvent e) {
if (pkp == 1) {
if(e.getX() >= 400 && e.getX() <= 500 && e.getY() >= 400 && e.getY() <= 500) {
dispose();
}
}
}
protected void paintComponent(Graphics g) {
draw(g);
}
private void draw(Graphics g) {
if(pkp == 1) {
g.setColor(Color.BLACK);
g.fillRect(400, 400, 100, 100);
}
repaint();
}
}
First of all the method paintComponent() is missing it's constructor so it should look like
public void paintComponent(Graphics g){
super.paintComponent(g);
draw(g);
}
second of all, im not sure if Graphics g object has a method called "fillRect"
so I would recommend you to convert it to object of type Graphics2D, so in this case it would be:
public void draw(Graphics g){
Graphics2D g2 = (Graphics2D) g;
if(pkp == 1) {
g2.setColor(Color.BLACK);
g2.fillRect(400, 400, 100, 100);
}
repaint();
}
Related
Problem definition: I want to use graphics in java to print ball and a rectangle ,the ball should move towards the rectangle by arrow keys or mouse moved.
the Problem with the code is that it is printing the ball, again and again, I want to print the ball once only
public class MouseGui extends javax.swing.JFrame implements
MouseMotionListener, MouseListener, KeyListener {
int x = 10, y = 10;
public MouseGui() {
initComponents();
addKeyListener(this);
addMouseListener(this);
}
#Override
public void paint(final Graphics g) {
g.setColor(Color.red);
g.fillOval(x, y, 50, 50);
g.setColor(Color.blue);
g.fillRect(200, 300, 100, 80);
if (x > 180 || y > 280) {
g.drawString("Target hit!!", 80, 20);
}
}
public static void main(final String args[]) {
MouseGui obj = new MouseGui();
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
new MouseGui().setVisible(true);
}
});
}
#Override
public void mouseMoved(final MouseEvent e) {
x = e.getX();
y = e.getY();
repaint();
}
#Override
public void keyPressed(final KeyEvent e) {
int a = e.getKeyCode();
if (e.getKeyCode() == VK_UP) {
y = y - 10;
repaint();
} else if (e.getKeyCode() == VK_DOWN) {
y = y + 10;
repaint();
} else if (e.getKeyCode() == VK_RIGHT) {
x = x + 10;
repaint();
} else if (e.getKeyCode() == VK_LEFT) {
x = x - 10;
repaint();
}
}
}
Here is how this code shows output :
The problem is not that the ball gets painted multiple times, the problem is that old drawings are never cleared.
When you override paint methods, it is recommended that you call the super method, so that it does its own stuff first .
Calling super.paint(g) here , will clear the Graphics object :
#Override
public void paint(final Graphics g) {
super.paint(g);
g.setColor(Color.red);
g.fillOval(x, y, 50, 50);
g.setColor(Color.blue);
g.fillRect(200, 300, 100, 80);
if (x > 180 || y > 280) {
g.drawString("Target hit!!", 80, 20);
}
}
Also, as suggested by #JoopEggen, when doing custom painting on Swing components, you usually use a lower-level component like a JPanel and override its paintComponent method, i.e :
#Override
public void paintComponent(final Graphics g) {
super.paintComponent(g);
g.setColor(Color.red);
g.fillOval(x, y, 50, 50);
g.setColor(Color.blue);
g.fillRect(200, 300, 100, 80);
if (x > 180 || y > 280) {
g.drawString("Target hit!!", 80, 20);
}
}
See this lesson to get some examples : Performing Custom Painting
Calling super.paintComponent(g) is a must.
I have a question. I created the Round Button, the code references from someone else cause I'm beginner. I want to set the position for it, but It seem to be unsuccessful. I thought the error is from its contains.
public final class ButtonDesigned extends JButton {
public ButtonDesigned (String label) {
super(label);
Dimension size = getPreferredSize();
size.width = size.height = Math.max(size.width,size.height);
setPreferredSize(size);
setContentAreaFilled(false);
}
protected void paintComponent(Graphics g) {
if (getModel().isArmed()) {
g.setColor(Color.lightGray);
} else {
g.setColor(getBackground());
}
g.fillOval(0, 0, getSize().width-1,getSize().height-1);
super.paintComponent(g);
}
protected void paintBorder(Graphics g) {
g.setColor(getForeground());
g.drawOval(0, 0, getSize().width-1, getSize().height-1);
}
Shape shape;
public boolean contains(int x, int y) {
if (shape == null ||
!shape.getBounds().equals(getBounds())) {
shape = new Ellipse2D.Float(0, 0, getWidth(), getHeight());
}
return shape.contains(x, y);
}
public static void main(String[] args) {
JButton button = new ButtonDesigned ("Click");
button.setBackground(Color.gray);
button.setLocation(70, 70);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "you have clicked");
}
});
enter code here
JFrame frame = new JFrame();
frame.getContentPane().add(button);
frame.getContentPane().setLayout(new FlowLayout());
frame.setSize(300, 300);
frame.setVisible(true);
}
}
I am trying to draw a circle when a button is pressed.
public Buttons(Panel panel){
addStud = new JButton("+ Student");
addStud.setToolTipText("Add a student");
addStud.addActionListener(new AbstractAction() {
#Override
public void actionPerformed(ActionEvent e) {
//draw circle here
}
});
This is my button in Button.java
public void draw(Graphics g){
g.setColor(Color.BLUE);
g.fillOval(200, 200, 400, 50);
}
This is what I am trying to call in Panel.java
I have a public void paintComponent(Graphics g) but I don't want the circle to be drawn immediately.
I have tried initializing Panel() and calling it with no success. What can I do here?
class MyPanel extends JPanel {
Boolean drawBlue = false;
public void drawBlueCircle( Boolean draw ) {
drawBlue = draw;
repaint();
}
protected void paintComponent( Graphics g ) {
if ( drawBlue ) {
g.setColor(Color.BLUE);
g.fillOval(200, 200, 400, 50);
}
}
}
Then in your button's actionPerformed method call
myPanel.drawBlueCircle(true);
where myPanel is the instance of MyPanel that you created.
i am trying to make a simple java game with a bat(paddle) and ball. So far i have painted the 2 objects onto the panel, however i cant get them to move. i have added key events for the bat and a move() method for the ball. Below are all my classes.
Game class:
public class Game extends JFrame {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
new Game();
}});
}
MyDrawingPanel myDrawingPanel = new MyDrawingPanel(this);
MyUIPanel myUIPanel = new MyUIPanel(this);
public Game()
{
setSize(1160,660); // you may change frame and panel sizes
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Container cp = getContentPane();
cp.setLayout(new FlowLayout());
cp.add(myDrawingPanel);
cp.add(myUIPanel);
setVisible(true);
}
}
MyDrawingPanel class:
class MyDrawingPanel extends JPanel {
Game game;
Ball ball = new Ball(this);
Bat bat = new Bat(this);
public MyDrawingPanel(Game game)
{
this.game=game;
setPreferredSize(new Dimension(800,600));
setBackground(Color.RED);
requestFocus();
}
public void paint(Graphics g)
{
super.paint(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
Graphics2D gBat = (Graphics2D) g;
bat.paint(gBat);
}
}
Ball class:
public class Ball {
int x = 0;
int y = 0;
int xa = 1;
int ya = 1;
private MyDrawingPanel myDrawingPanel;
public Ball(MyDrawingPanel myDrawingPanel) {
this.myDrawingPanel = myDrawingPanel;
}
public void move() {
if (x + xa < 0)
xa = 1;
if (x + xa > myDrawingPanel.getWidth() - 30)
xa = -1;
if (y + ya < 0)
ya = 1;
if (y + ya > myDrawingPanel.getHeight() - 30)
ya = -1;
x = x + xa;
y = y + ya;
}
public void paint(Graphics2D g) {
g.fillOval(x, y, 30, 30);
}
}
Bat class:
public class Bat{
int x = 0;
int xa = 0;
private MyDrawingPanel myDrawingPanel;
public Bat(MyDrawingPanel myDrawingPanel)
{
this.myDrawingPanel = myDrawingPanel;
}
public void move(){
if(x + xa > 0 && x + xa <myDrawingPanel.getWidth()-60 )
x = x + xa;
}
public void paint(Graphics2D g)
{
g.setColor(Color.BLUE);
g.fillRoundRect(x, 500, 100, 20, 10, 10);
}
public void keyPressed(KeyEvent e)
{
if(e.getKeyCode() == KeyEvent.VK_LEFT)
xa = -1;
if(e.getKeyCode() == KeyEvent.VK_RIGHT)
xa = 1;
}
public void keyReleased(KeyEvent e)
{
xa = 0;
}
}
Methods such as keyPressed and keyReleased don't do anything without a KeyListener implementation. So currently, your methods are useless. What you should do have the DrawingPanel class implement the KeyListener, like this
public class DrawingPanel extends JPanel implements KeyListener {
...
}
The methods, keyPressed and keyReleased should be in that class. You'll also want setter methods for what ever variables are updated in the Bat class, like x and xa, is those are the variables that determine the movement of the Bat.
So in the keyPressed, which should be in the DrawingPanel class, it could look something like this
public void keyPressed(KeyEvent e) {
if (e.getKeyCode() == KeyEvent.VK_LEFT) {
bat.setXa(bat.getXa() - 1);
repaint();
}
if (e.getKeyCode() == KeyEvent.VK_RIGHT) {
bat.setXa(1);
repaint();
}
}
Notice how I call repaint(). That's what you need to do after you move something.
This should get you started in the right direction
EDIT Forget the majority of the above answer.
Instead of using a KeyListener though I would recommeng using key binding. You may face focus problems using KeyListener. I implemented the keybinding for the DrawingPanel and it works fine. It'll give you some ideas to work with.
class MyDrawingPanel extends JPanel {
Game game;
Ball ball = new Ball(this);
Bat bat = new Bat(this);
public MyDrawingPanel(Game game) {
this.game = game;
setPreferredSize(new Dimension(800, 600));
setBackground(Color.RED);
requestFocus();
Action rightAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
bat.x += 10;
repaint();
}
};
Action leftAction = new AbstractAction() {
public void actionPerformed(ActionEvent e) {
bat.x -= 10;
repaint();
}
};
InputMap inputMap = getInputMap(JPanel.WHEN_IN_FOCUSED_WINDOW);
ActionMap actionMap = getActionMap();
inputMap.put(KeyStroke.getKeyStroke("RIGHT"), "rightAction");
actionMap.put("rightAction", rightAction);
inputMap.put(KeyStroke.getKeyStroke("LEFT"), "leftAction");
actionMap.put("leftAction", leftAction);
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ball.paint(g2d);
Graphics2D gBat = (Graphics2D) g;
bat.paint(gBat);
}
}
See How to use key bindings
I need to draw a rectange,circle and line and then animate them(press left -> it(all objects) moves left for examp.)
I draw objects like this
class MyCanvas extends JComponent {
int x = 10;
int y = 10;
public MyCanvas()
{
Action someaction = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e) {
x+=30;
//revalidate();
repaint();
}
};
this.getInputMap().put(KeyStroke.getKeyStroke("SPACE"), someaction);
}
#Override
public void paintComponent(Graphics g) {
g.drawRect(x,y, 200, 200);
g.drawOval(x, y, 50, 50);
g.drawLine(x, y, 50, 30);
}
}
But it doesn't move.
use paintComponent(Graphics g) for Swing JComponents instead of paint(Graphics g)
use KeyBindings for KeyEvents for Swing JComponents
put Objects (prepare before paintComponent(Graphics g)) to the Array, paint elements from Array in paintComponent(Graphics g)