Key Listener not working - java

public void paint (Graphics g)
{
bufferGraphics.setColor (Color.black);
bufferGraphics.clearRect (0, 0, dim.width, dim.width);
while (input != KeyEvent.VK_SPACE)
{
bufferGraphics.fillRect (0, 0, dim.width, dim.height);
}
bufferGraphics.drawImage (track, 0, 0, dim.width, dim.height, this);
bufferGraphics.setFont (new Font ("Calibri", Font.PLAIN, 25));
bufferGraphics.drawString ("Level: " + level, 30, 30);
bufferGraphics.drawImage (car, 620, myCarY, 70, 120, this);
bufferGraphics.drawImage (opponent, 415, oppCarY, 70, 120, this);
move ();
This is the code as it stands now. When executed, I get a frozen blank window that cannot even be closed.

Your issue is in your if statement.
if(run = false)
will never execute, as assignment returns the value being assigned (e.g. false).
You need to change your = to an ==.
You may also want to change your infinite for loop to a while loop, something like
while(input != KeyEvent.VK_SPACE) {
}
Also make sure that your KeyListener is being added to your class (in ctor)
addKeyListener(new MyKeyListener())
I just tested the code, and it worked.

Related

how do I detect key presses with just one method in java?

I'm trying to paint 6 colors, 10 shapes, a jpeg image, and 3 things that change when a key is pressed in java.
However I'm trying to program all of this in one method. I've done everything else except detecting a key press. I've looked at a lot of examples, but all of them use different methods or classes that work together to detect a key press. But how to do I detect key presses and at the same time change pictures/images in JPanel all in just one method.
I tried to write some code but it doesn't work (nothing shows up on the JPanel/screen) Here's my code so far:
public void paint(Graphics g){
g.setColor(Color.WHITE);
g.fillRect(0, 0, 1000, 1000);
BufferedImage photo = null;
try
{
File file = new File("holiday.jfif");
photo = ImageIO.read(file);
}
catch (IOException e)
{
g.drawString("Problem reading the file", 100, 100);
}
g.drawImage(photo,0,0,800,800,null);
g.setColor(Color.BLACK);
g.fillRect(120,300,100,100 );
g.setColor(Color.GREEN);
g.fillOval(270,130,50,100 );
g.setColor(Color.BLUE );
g.fillRect(350,200,100,150 );
g.setColor(Color.PINK);
g.fillOval(460, 270, 50, 50);
g.setColor(Color.GRAY);
g.fillArc(500, 300, 110, 100, 5, 150);
g.setColor(Color.YELLOW);
g.fillRect(500,450,100,100);
g.setColor(Color.YELLOW);
g.fillOval(550,500,100,100);
int[] xpoints = {50,150,20,180};
int[] ypoints = {500,500,550,550};
g.setColor(Color.BLACK);
g.drawPolygon(xpoints,ypoints,4);
int[] xpoint = {250,220,380,350};
int[] ypoint = {500,550,550,500};
g.drawPolygon(xpoint,ypoint,4);
int[] x = {600,500,700};
int[] y = {20,100,100};
g.drawPolygon(x,y,3);
g.setColor(Color.ORANGE);
g.fillRect(10,50,220,30);
g.fillRect(115,80,20,100);
Scanner input = new Scanner(System.in);
String press;
boolean stop = false;
while(!stop)
{
//Scanner input = new Scanner(System.in);
press = input.next();
if (press != null)
{
g.clearRect(115,80,20,100);
g.clearRect(500,450,100,100);
stop = true;
}
}
}

paintComponent is stressing me out; Hangman programming project

Ok, so I have a programming project due in a few hours and I am close to finished. I can only paint certain parts of the hangman at a time, which is dependent on the amount of incorrect tries by the user. The teacher of my programming class requires the creation of the hangman drawing to be in a different class. The problem I'm having is sending over the number of incorrect tries to a class with the paintComponent.
if(updatedChallenge == challenge)
{
incorrectTries += 1;
}
challenge = updatedChallenge;
The challenge == updated challenge refers to the hidden word before the user's guess and the hidden word after the user's guess. If they are still equal that means the user made an incorrect choice. 1 gets added to the total number of incorrect tries.
Here is my other class:
class HangmanPicture extends JPanel
{
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLACK);
g.drawLine(250, 300, 300, 300); //Platform
g.drawLine(275, 300, 275, 200); //Pole
g.setColor(Color.YELLOW);
g.drawLine(275, 200, 350, 200); //Rope
g.drawLine(350, 200, 350, 225); //Noose
g.setColor(Color.CYAN);
g.drawOval(350, 225, 15, 15); //Head
g.drawLine(350, 230, 350, 260); //Torso
g.drawLine(350, 240, 340, 230); //Left Arm
g.drawLine(350, 240, 360, 230); // Right Arm
g.drawLine(350, 260, 330, 280); // Left Leg
g.drawLine(350, 260, 390, 280); // Right Leg
}
}
I want to put an if statement where each body part gets added after each incorrect try, which requires me to send the number of incorrect tries to the class. Whenever I try to send the number, it always somehow interferes with paintComponent
Any help would be greatly appreciated, I'm desperate. Thanks in advanced!
Since you are extending the JPanel class. We can add extra methods and fields to the class and use them where HangmanPicture is being used.
HangmanPicture panel = new HangmanPicture();
...
if(updatedChallenge == challenge)
{
panel.addIncorrectAttempt();
}
challenge = updatedChallenge;
class HangmanPicture extends JPanel
{
private int incorrectAttempts = 0;
// Add one to counter
public void addIncorrectAttempt(){
incorrectAttempte++;
}
// Get how many times the player entered an incorrect number
public int getIncorrectAttempts(){
return incorrectAttempts;
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
g.setColor(Color.BLACK);
if( incorrectAttempts >= 1 ){
g.drawLine(250, 300, 300, 300); //Platform
}
if( incorrectAttempts >= 2 ){
g.drawLine(275, 300, 275, 200); //Pole
}
}
}

Bouncing multiple lines with fixed coordinates off walls in java graphics [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
I want to store the fixed coordinates and then increment the coordinates until they reache the edge of the screen.
Here's my code:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class Name extends JPanel
{
int x, y, w, h, xdir, ydir;
public Name ()
{
}
public void paintComponent (Graphics g)
{
super.paintComponent (g);
g.drawLine(110+x, 300+y, 95+x, 400+y);
g.drawLine(110, 300, 123, 350);
g.drawLine(135, 300, 123, 350); //M
g.drawLine(135, 300, 150, 400);
g.drawOval (150, 300, 15, 15); // i
g.fillOval (150, 300, 15, 15);
g.drawLine (155, 320, 155, 400);
g.drawLine (172, 300, 172, 400); // k
g.drawLine (172, 350, 185, 300);
g.drawLine (172, 350, 185, 400);
g.drawLine (190, 360, 265, 360); // e
g.drawArc (190, 325, 75, 75, 360, 180);
g.drawArc (190, 330, 75, 75, 168, 180);
w = getSize ().width;
h = getSize ().height;
xdir = 1;
ydir = 1;
x = x + xdir;
y = y+ ydir;
if (x > w || x < 0)
{
xdir = -1 * xdir;
}
if (y > h || y < 0)
{
ydir = -1 * ydir;
}
repaint ();
MyLib.delay (25);
} // paint method
public static void main (String[] args)
{
JFrame frame = new JFrame ("NameBounce");
frame.getContentPane ().add (new Name ());
frame.setSize (500, 500);
frame.setVisible (true);
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
} // main method
} // Name class
I've tried storing the coordinates into array lists but had no luck.
I've been trying to avoid hard coding the entire program.
Use something like Path2D to define the shapes you want to draw (you can draw all the letters within a single Path2D)
Use a AffineTransform to translate the location of the Graphics and Graphics2D#draw to physically paint the Path2D
Use a Swing Timer to schedule a regular call back within which you can update the position of the Path2D and call repaint on the component to trigger an update
See
Concurrency in Swing
How to use Swing Timers
2D Graphics
for more details
Don't call Thread.sleep or any other blocking process within the paintComponent method (or from within the context of the Event Dispatching Thread) as this will prevent the EDT from updating the screen.
Make sure you are creating/updating your UI only from within the context of the EDT, see Initial Threads for more details

Decreasing a Filled Rectangle's height from top

I am using a paintComponent Class in a project of mine, and I am currently wondering how I can decrease the size of the rectangle from the top making it's way downwards.
This is the part of the code:
public Battery(){
super();
firstTime = true;
f = new Font("Helvetica", Font.BOLD, 14);
m = Toolkit.getDefaultToolkit().getFontMetrics(f);
}
public void paintComponent(Graphics g){
if(firstTime){
firstTime = false;
batteryLevel = 1 + this.getHeight();
decr = batteryLevel / 20;
}else{
g.setColor(Color.RED);
g.fillRect(1, 0, this.getWidth(), this.getHeight());
g.setColor(Color.GREEN);
g.fillRect(1, 0, this.getWidth(), batteryLevel);
g.setColor(Color.BLACK);
g.setFont(f);
g.drawString("TEST", (getWidth() - m.stringWidth("TEST")) / 2 , this.getHeight() / 2);
}
}
public void decreaseBatteryLevel(){
batteryLevel -= decr;
this.repaint();
}
PS. Sorry if I did something wrong, I'm new to this forum.
As you want the visible battery level to descend you will want to increase your Y co-ordinate in relation to the value of batteryLevel. You could use:
g.fillRect(1, getHeight() - batteryLevel, getWidth(), batteryLevel);
Instead
g.fillRect(1, 0, this.getWidth(), batteryLevel);
Do
g.fillRect(1, batteryLevel, this.getWidth(), getHeight() - batteryLevel);
Also maybe repaint(50L) instead of repaint().
If your question meant: how to animate a change in the battery level.
Use a javax.swing.Timer:
int toPaintBatteryLevel = batteryLevel;
// In the paintComponent paint upto toPaintBatteryLevel.
Timer timer = new Timer(100, new ActionListener() {
public void actionPerformed(ActionEvent e) {
if (toPaintBatteryLevl == batteryLevel) {
return;
}
if (toPaintBatteryLevl > batteryLevel) {
--toPaintBatteryLevel; // Animate slowly
} else {
toPaintBatteryLevel = batteryLevel; // Change immediately
}
repaint(50L);
};
});
timer.start();
For ease of coding, there is a permanent timer. And externally one changes the batteryLevel,
and the time determines the toPaintBatteryLevel, which paintComponent uses to paint.

Java House Applet

So I'm just starting with Applets and I am making a house with an open door and 2 open windows when the applet loads. When you click these windows or door then they will shut. My question though is what do I need to do to re-open these windows doors. I figure I need to set the Boolean variables to False somehow and repaint. Where would I do this. I don't need you guys to write the code for me, I just want to know what I should do.
Thanks ahead of time,
Rick
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
/**
Rick Armstrong
Chapter 14 - House Applet
*/
public class HouseApplet extends Applet {
boolean leftWin, rightWin, door;
public void init()
{
leftWin = false;
rightWin = false;
door = false;
setBackground(Color.white);
addMouseListener(new MyMouseListener());
}
public void paint(Graphics g)
{
super.paint(g);
// Draw the house.
g.setColor(Color.black);
g.drawRect(100, 100, 200, 100);
// Draw the roof
g.drawLine(80, 100, 320, 100);
g.drawLine(80, 100, 200, 40);
g.drawLine(200, 40, 320, 100);
// Draw the left window open.
g.fillRect(120, 130, 40, 40);
// Draw the right window open.
g.fillRect(240, 130, 40, 40);
// Draw the door open.
g.fillRect(180, 130, 40, 70);
if (leftWin) {
// Draw the left window closed.
g.setColor(Color.white);
g.fillRect(120, 130, 40, 40);
g.setColor(Color.black);
g.drawRect(120, 130, 40, 40);
g.drawLine(140, 130, 140, 170);
g.drawLine(120, 150, 160, 150);
}
if (rightWin) {
// Draw the right window closed.
g.setColor(Color.white);
g.fillRect(240, 130, 40, 40);
g.setColor(Color.black);
g.drawRect(240, 130, 40, 40);
g.drawLine(260, 130, 260, 170);
g.drawLine(240, 150, 280, 150);
}
if (door) {
// Draw the door closed.
g.setColor(Color.white);
g.fillRect(180, 130, 40, 70);
g.setColor(Color.black);
g.drawRect(180, 130, 40, 70);
g.fillOval(210, 165, 07, 07);
}
}
private class MyMouseListener implements MouseListener
{
public void mousePressed(MouseEvent e)
{
}
public void mouseClicked(MouseEvent e)
{
int currentx = e.getX();
int currenty = e.getY();
boolean WindowLeft = (currentx >= 120 && currentx < 160 && currenty >= 130 && currenty <= 170);
if (WindowLeft)
{
leftWin = true;
repaint();
}
boolean WindowRight = (currentx >= 240 && currentx < 280 && currenty >= 130 && currenty <= 170);
if (WindowRight)
{
rightWin = true;
repaint();
}
boolean Door = (currentx >= 180 && currentx < 220 && currenty >= 40 && currenty <= 200);
if (Door)
{
door = true;
repaint();
}
else;
}
public void mouseReleased(MouseEvent e)
{
}
public void mouseEntered(MouseEvent e)
{
}
public void mouseExited(MouseEvent e)
{
}
}
}
Maybe I'm misunderstanding the question, but why are you always setting the values to true in the event handler?
If you want a toggling behavior, you could simply write: value = !value and then repaint.
Since you initially set your value to false, the next click would set it to true, the next to false, etc. etc.
For example:
if (WindowLeft)
{
leftWin = !leftWin;
repaint();
}
Note that it is possible for you to cause sort of a "race condition" by clicking faster than the framework has a chance to update the view, but this is usually not a problem for initial problem.
BTW: In terms of readability, consider naming your variables in a way that conveys their meaning. For example, is the naming door evocative of a boolean? not really. but doorOpen is, and it helps interpret the meaning of the variable and its transitions.
if (WindowRight)
{
rightWin = false;
repaint();
}
else {
rightWin = true;
repaint();
}
try the above. When you click inside the window, it closes otherwise it opens

Categories

Resources