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
Related
This question already has answers here:
Image change on hover Java
(2 answers)
Closed 5 years ago.
So I am trying to set up this thing that changes an image when hovered over. I have already set up the mouseListener to know if the mouse is over my image. I have a variable that has the image location stored in it and it changes when the image is hovered over. When my paint command is run it paints the default image and when I hover over it, it doesn't change because it is not painted again. How can I make it so that it repaints it again when the image location is changed. BTW the mouseListener is in a different class than the image.
My image:
private String settingsConfig = snake.settingsConfig;
settingsImage = new ImageIcon(getClass().getResource(settingsConfig));
settingsImage.paintIcon(this, g, 700, 23);
My main class (painting method is in the other class)
public class snake implements MouseListener{
public static int mouseX;
public static int mouseY;
public static String settingsConfig = "/assets/settings.png";
public static void main(String[] args) {
// JFrame
JFrame obj = new JFrame("Snake");
gameplay Gameplay = new gameplay();
obj.setBounds(10, 10, 905, 700);
obj.setBackground(Color.DARK_GRAY);
obj.setResizable(false);
obj.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
obj.add(Gameplay);
obj.setVisible(true);
obj.addMouseMotionListener(new MouseAdapter() {
#Override
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
if(mouseX > 699 && mouseX < 761 && mouseY > 22 + 25 && mouseY < 54 + 25) {
settingsConfig = "/assets/settingshover.png";
}
else {
settingsConfig = "/assets/settings.png";
}
}
});
}
Very small piece of paint(Graphics g) (In a different class):
public void paint (Graphics g) {
if(moves == 0) {
snakexlength[2] = 50;
snakexlength[1] = 75;
snakexlength[0] = 100;
snakeylength[2] = 100;
snakeylength[1] = 100;
snakeylength[0] = 100;
}
if(moves >= 1) {
playing = true;
}
// Draw title image border
g.setColor(Color.WHITE);
g.drawRect(24, 10, 851, 55);
// Draw the title image and settings
titleImage = new ImageIcon(getClass().getResource("/assets/snaketitle.jpg"));
titleImage.paintIcon(this, g, 25, 11);
settingsImage = new ImageIcon(getClass().getResource(settingsConfig));
settingsImage.paintIcon(this, g, 700, 23);
// Draw the border for gameplay
g.setColor(Color.WHITE);
g.drawRect(24, 74, 851, 577);
// Draw background for the gameplay
g.setColor(Color.BLACK);
g.fillRect(25, 75, 850, 575);
// Draw score
g.setColor(Color.WHITE);
g.setFont(new Font("arial", Font.PLAIN, 14));
g.drawString("Score: " + score, 780, 30);
// Draw high score
g.drawString("High Score: " + highScore, 780, 50);
}
How can I make it so that it repaints it again when the image location is changed
Invoke reapint(); in the place where you need the paintings to be updated. For example in the listener when you mouse-over the image.
public void mouseMoved(MouseEvent e) {
mouseX = e.getX();
mouseY = e.getY();
if(mouseX > 699 && mouseX < 761 && mouseY > 22 + 25 && mouseY < 54 + 25){
settingsConfig = "/assets/settingshover.png";
}
else{
settingsConfig = "/assets/settings.png";
}
repaint();
}
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
}
}
}
For a school-project, we've recieved a set amount of figures we're supposed to paint on a canvas with the normal Java-graphics method .paint(). This is supposed to be controlled with the help of a few buttons, each painting a different mix of colors. The paint-method is quite easy and works but when we try to connect the buttons, nothing happens but the buttons appearing on the screen. The code reads as following:
import java.applet.Applet;
import java.awt.*;
import java.awt.event.*;
public class MarcusErikaGrf2 extends Applet implements ActionListener {
Button knapp, knapp2, knapp3, knapp4, knapp5;
boolean svart=false, rod=false, gul=false, gron=false, rensa=false;
int tx[],ty[],pox[],poy[],pgx[],pgy[],pgxf[],pgyf[],bx[],by[],bxf[],byf[],hf[],hy[];
Polygon txy, po, pg, pgf, b, bf, hxy;
public void init (){
this.setSize(800,900);
this.setBackground(Color.white);
this.setLocation(200,1);
knapp= new Button ("Svart");
knapp2= new Button ("Röd & Rosa");
knapp3= new Button ("Gul & Orange");
knapp4 = new Button ("Grön & Blå");
knapp5 = new Button ("Rensa fönstret");
knapp.addActionListener(this);
knapp2.addActionListener(this);
knapp3.addActionListener(this);
knapp4.addActionListener(this);
knapp5.addActionListener(this);
add(knapp);
add(knapp2);
add(knapp3);
add(knapp4);
add(knapp5);
int tx[] = {375,475,425};
int ty[] = {110,110,250};
int pox[] = {65,120,120,65,50};
int poy[] = {350,350,450,450,400};
int pgx[] = {35,88,98,88,35,25};
int pgy[] = {210,210,270,330,330,270};
int pgxf[] = {36,87,97,87,36,26};
int pgyf[] = {211,211,270,329,329,270};
int bx[] = {372, 400, 395, 420, 415, 440/*TP*/, 415, 400, 405, 382, 387 };
int by[] = {60 , 67 , 70 , 77 , 80 , 87 /*TP*/, 95, 88 , 85 , 75 , 70};
int bxf[] = {373,399,394,419,414,439,416,401,406,383,388};
int byf[] = {61,67,70,77,80,86,94,88,85,75,70};
int hx[] = {150,185,225};
int hy[] = {176,120,176};
Polygon txy = new Polygon(tx,ty,tx.length);
Polygon po = new Polygon(pox,poy,pox.length);
Polygon pg = new Polygon(pgx,pgy,pgx.length);
Polygon pgf = new Polygon(pgxf,pgyf,pgxf.length);
Polygon b = new Polygon(bx,by,bx.length);
Polygon bf = new Polygon(bxf,byf,bxf.length);
Polygon hxy = new Polygon(hx,hy,hx.length);
}
#Override
public void paint(Graphics g){
if(svart == true){
g.setColor(Color.black);
g.drawRect(50, 50, 30, 150); //Rektangel 1
g.drawRect(90,50,30,150); //Rektangel 2
g.drawOval(140, 60, 40,30); //Öga 1
g.drawOval(200, 62, 40, 30); //Öga 2
g.fillOval(147,67,15,15); //Pupill 1
g.fillOval(218,69,15,15); //Pupill 2
g.fillOval(310,100,50,120); //Svart oval, Stor
g.fillOval(310, 50, 22, 30); //Svart oval, Medium
g.fillOval(270, 220, 20, 28); //Svart oval, Liten
g.drawOval(100,230,140,40); //Rosa oval, outline
g.fillOval(370,250,100,50); //Svart oval, horisontell
g.drawRect(200,300,180,150); //Grön rektangel, outline
g.drawRect(170,369,10,130);
g.drawRect(140,369,10,130);
g.fillOval(250,480,28,40);
g.fillOval(400,480,14,20);
g.drawOval(280,520,122,200);
g.drawOval(160, 570, 80, 100);
g.drawOval(50,680,140,40);
g.drawRect(65,500,65,150);
g.drawPolygon(pg);
g.drawPolygon(b);
g.setColor(Color.white);
g.fillOval(317, 65, 8, 8); //Vit prick i svart oval, Medium
g.fillOval(277, 235, 6, 6); //Vit prick i svart oval, Liten
}
else if(rod == true){
g.setColor(Color.red);
g.fillOval(161,571,79,99);
g.fillOval(255, 150, 50, 70);
g.setColor(Color.pink);
g.fillOval(101, 231, 138, 38); //Rosa oval
g.fillPolygon(bf);
g.setColor(Color.white);
g.fillOval(255, 170, 50, 50);
}
else if(gron == true){
g.setColor(Color.blue);
g.fillRect(51, 51, 29, 149); //Rektangel 1
g.fillRect(91, 51, 29, 149); //Rektangel 2
g.fillRect(66,501,64,149);
g.fillPolygon(txy);
g.setColor(Color.green);
g.fillRect(201, 301, 179, 149); //Grön rektangel
g.fillOval(51,681,139,38);
g.fillPolygon(pgf);
}
else if(gul == true){
g.setColor(Color.yellow);
g.fillRect(171,370,9,129);
g.fillRect(141,370,9,129);
g.fillOval(281,521,120,198);
g.setColor(Color.orange);
g.fillPolygon(po);
g.fillPolygon(hxy);
g.fillOval(150, 160, 45, 45);
g.fillOval(180, 160, 45, 45);
}
else if(rensa == true){
repaint();
}
}
public void actionPerformed (ActionEvent e){
if(e.getSource() == knapp){
svart = true;
}
else if(e.getSource() == knapp2){
rod = true;
}
else if(e.getSource() == knapp3){
gul = true;
}
else if(e.getSource() == knapp4){
gron = true;
}
else if(e.getSource() == knapp5){
rensa = true;
}
}
}
What are we missing?
In your actionPerformed(...) method you need to invoke:
repaint();
This tells the component to repaint itself.
else if(rensa == true){
repaint();
}
Never invoke repaint() from within a painting method. A painting method is for doing the painting, not scheduling the painting.
I am trying to create a program that solves the popular Towers of Hanoi game. I have succeeded in printing the disks and pegs, but I want the disks to print with a delay. For example, I want disk 7 to print, then disk 6 to print 1 second later. I tried this by putting it to sleep, but all it does is delay the whole frame from displaying, how do I make it display the shape with a delay. I have attached my code, thanks for any help!
package towersofhanoi;
import javax.swing.*;
import java.awt.*;
/*g.fillOval(60 = horizontal distance , 540= vertical distance, 400 = width, 60 = height) */
public class TowersOfHanoi extends JPanel {
public static void main(String[]args){
//Print the shapes and frame
TowersOfHanoi drawRectangle = new TowersOfHanoi();
JFrame frame = new JFrame("Towers of Hanoi");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(drawRectangle);
frame.setSize(1250, 800);
frame.setVisible(true);
}
public void paintComponent(Graphics g){
super.paintComponent(g);
Color pegs = new Color (251, 129, 56);
g.setColor(pegs);
//peg 1
g.fillRect(250, 300, 25, 450);
//peg 2
g.fillRect(600, 300, 25, 450);
//peg 3
g.fillRect(950, 300, 25, 450);
//bottom
g.fillRect(200, 700, 825, 50);
//create a color for circles
Color circles = new Color (176,56, 251);
//cirle 7 (Labeled from bottom to top)
g.setColor(circles);
g.fillOval(60, 640, 400, 60);
g.setColor(Color.BLACK);
g.drawOval(60, 640, 400, 60);
try {
Thread.sleep(1000);
}
catch (InterruptedException ie) {
}
//circle 6
g.setColor(circles);
g.fillOval(85, 580, 350, 60);
g.setColor(Color.BLACK);
g.drawOval(85, 580, 350, 60);
try {
Thread.sleep(1000);
}
catch (InterruptedException ie) {
}
//circle 5
g.setColor(circles);
g.fillOval(110, 520, 300, 60);
g.setColor(Color.BLACK);
g.drawOval(110, 520, 300, 60);
//circle 4
g.setColor(circles);
g.fillOval(135, 465, 250, 55);
g.setColor(Color.BLACK);
g.drawOval(135, 465, 250, 55);
//circle 3
g.setColor(circles);
g.fillOval(160, 420, 200, 45);
g.setColor(Color.BLACK);
g.drawOval(160, 420, 200, 45);
//circle 2
g.setColor(circles);
g.fillOval(185, 380, 150, 40);
g.setColor(Color.BLACK);
g.drawOval(185, 380, 150, 40);
//circle 1
g.setColor(circles);
g.fillOval(210, 345, 100, 35);
g.setColor(Color.BLACK);
g.drawOval(210, 345, 100, 35);
}
}
My recommendation
separate out drawing in paintComponent() into the 3 constitute parts, these were previously separated by sleep statements
Use state inside the TowersOfHanoi object to control what should be drawn, I've used a simple counter
Use javax.swing.Timer to update the counter and request a repaint.
Notes
You cannot sleep on the UI thread. Swing is single threaded and this would stop events being processed.
javax.swing.Timer automatically fires the callback you give it on the UI thread.
paintComponent() can be called multiple times if windows are resized etc, therefore it is important to make it independent, hence my use of a counter.
Working example
public class TowersOfHanoi extends JPanel {
private int clock = 0;
private Color circles = new Color(176, 56, 251);
public static void main(String[] args) {
// Print the shapes and frame
TowersOfHanoi drawRectangle = new TowersOfHanoi();
JFrame frame = new JFrame("Towers of Hanoi");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(drawRectangle);
frame.setSize(1250, 800);
frame.setVisible(true);
Timer timer = new Timer(1000, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
drawRectangle.nextFrame();
drawRectangle.repaint();
}
});
timer.setRepeats(true);
timer.start();
}
public void nextFrame() {
clock++;
}
public void paintComponent(Graphics g) {
super.paintComponent(g);
frame1(g);
if (clock >= 1) {
frame2(g);
}
if (clock >= 2) {
frame3(g);
}
}
private Color frame1(Graphics g) {
Color pegs = new Color(251, 129, 56);
g.setColor(pegs);
// peg 1
g.fillRect(250, 300, 25, 450);
// peg 2
g.fillRect(600, 300, 25, 450);
// peg 3
g.fillRect(950, 300, 25, 450);
// bottom
g.fillRect(200, 700, 825, 50);
// create a color for circles
// cirle 7 (Labeled from bottom to top)
g.setColor(circles);
g.fillOval(60, 640, 400, 60);
g.setColor(Color.BLACK);
g.drawOval(60, 640, 400, 60);
return circles;
}
private void frame2(Graphics g) {
// circle 6
g.setColor(circles);
g.fillOval(85, 580, 350, 60);
g.setColor(Color.BLACK);
g.drawOval(85, 580, 350, 60);
}
private void frame3(Graphics g) {
// circle 5
g.setColor(circles);
g.fillOval(110, 520, 300, 60);
g.setColor(Color.BLACK);
g.drawOval(110, 520, 300, 60);
// circle 4
g.setColor(circles);
g.fillOval(135, 465, 250, 55);
g.setColor(Color.BLACK);
g.drawOval(135, 465, 250, 55);
// circle 3
g.setColor(circles);
g.fillOval(160, 420, 200, 45);
g.setColor(Color.BLACK);
g.drawOval(160, 420, 200, 45);
// circle 2
g.setColor(circles);
g.fillOval(185, 380, 150, 40);
g.setColor(Color.BLACK);
g.drawOval(185, 380, 150, 40);
// circle 1
g.setColor(circles);
g.fillOval(210, 345, 100, 35);
g.setColor(Color.BLACK);
g.drawOval(210, 345, 100, 35);
}
}
Have you tried using Caldender() or System.currentTimeMillis()? If you do, you can get the current time. After you have gotten the time, do a while loop to check what the time is now. When you do LastTime - Now, to check how much time has passed.
This code is not tested, (But it should work).
long lastTime = System.currentTimeMillis();
while(true){
long now = System.currentTimeMillis();
if(lastTime - now == [YOUR PREFFERD WAITING TIME IN MS]){
break;
}
}
And now draw your graphics.
You should probably restructure you code so that paint component draws the current state of the system of pegs and rings. Then use a Swing timer to call a method that moves the state of the system then calls repaint().
Im almost finished with this car project im working on but cant seem to get the key events to work. I think it has to do with my action listener with my timer but im not sure. When I press the up arrow key the timer delay is supposed to decrease and vice versa for the down arrow key. I have the commands written but they are not registering input. If anyone could give me some pointers I'd appreciate it
Code:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class RaceCar extends JFrame{
public RaceCar(){
add(new CarPic());
}
public static void main(String[] args){
JFrame frame = new RaceCar();
frame.setTitle("Brady Kedge: Race Car");
frame.setSize(300, 150);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
public class CarPic extends JPanel implements KeyListener
{
private int x = 0;
private int y = 150;
private int z = 300;
Timer mytimer = new Timer(50, new ActionListener());
public CarPic()
{
mytimer.start();
}
public void paintComponent(Graphics g)
{
super.paintComponent(g);
y = getHeight();
z = getWidth();
g.setColor(Color.WHITE);
g.fillRect(0, 0, z, y);
Polygon polygon = new Polygon();
polygon.addPoint(x + 10, y - 20);
polygon.addPoint(x + 20, y - 30);
polygon.addPoint(x + 30, y - 30);
polygon.addPoint(x + 40, y - 20);
if(x < z - 40)
{
g.setColor(Color.BLACK);
g.fillOval(x + 10, y - 10, 10, 10);
g.fillOval(x + 30, y - 10, 10, 10);
g.setColor(Color.BLUE);
g.fillRect(x, y - 20, 50, 10);
g.setColor(Color.BLUE);
g.fillPolygon(polygon);
}
else
x = 0;
}
public void actionPerformed(ActionEvent e){
x+=10;
repaint();
}
#Override
public void keyTyped(KeyEvent k) {
//Fill
}
#Override
public void keyPressed(KeyEvent k) {
int delay = mytimer.getDelay();
if(k.getKeyCode() == KeyEvent.VK_UP)
mytimer.setDelay(delay > 10 ? delay - 10 : 0);
else if(k.getKeyCode() == KeyEvent.VK_DOWN)
mytimer.setDelay(delay < 5000 ? delay + 10 : 5000);
}
#Override
public void keyReleased(KeyEvent e) {
// TODO Auto-generated method stub
}
}
}
First of all, you never register a KeyListener with your component (implementing KeyListener isn't enough).
Second of all, KeyListener will only raise KeyEvents if the component it is registered to has focus and is focusable.
A better solution would be to use the key bindings API, which provides you with the means to configure the focus level at which a component will trigger key events.
Also, personally, instead of modifying the Timer delay, I would have use a speed modifier (of type double) which would be percentage of the speed you want. In this way 1 would normal speed, 0.5 half speed and 2 double speed, for example.