Hot questions for Using Applets in graphics

Question:

First Java project so this question is probably very amateur. I'm trying to run the method paintComponent for drawing shapes in a class that extends JFRAME I just can't figure out how to call it. Do I need to create a graphics variable to act as the background so I can call paintComponent(background)? Or maybe a new Planel?

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.Graphics.*;
import java.awt.event.*;
import java.text.*;
public class Pythag extends JFrame implements ActionListener
{

JTextField text1,text2;
JLabel label1,label2,label3;
JButton buttonC;
public Pythag(){
    super ("Pythagorean Theorem");
    // Set up the frame
    this.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
    this.setBounds (300, 300, 200, 350);
    //creating objects
    JPanel boxY = new JPanel ();
    boxY.setLayout(new BoxLayout(boxY,BoxLayout.Y_AXIS));
    label1 = new JLabel ("A side length",JLabel.CENTER);
    label2 = new JLabel ("B side length",JLabel.CENTER);
    label3 = new JLabel ("Type in side lengths to calculate hypotenuse",JLabel.CENTER);
    buttonC = new JButton ("Button1");
    text1 = new JTextField (10);
    text2 = new JTextField (10);

    //Nestled flow layouts:
    //layout1
    JPanel line = new JPanel();
    line.add(label1);
    line.add(text1);
    boxY.add(line);

    //layout2
    JPanel line2 = new JPanel();
    line2.add(label2);
    line2.add(text2);
    boxY.add(line2);
    //layout 3

    JPanel line3 = new JPanel();
    line3.add(label3);
    boxY.add(line3);
    //layout 4

    JPanel line4 = new JPanel();
    line4.add(buttonC);
    boxY.add(line4);
    //Adding listeners
    buttonC.addActionListener (this);
    text1.addActionListener (this);        
    text2.addActionListener (this);        

    //Setting up
    this.setContentPane (boxY);
    this.setVisible (true);
    this.setSize(450,200);
    // this.add(panel);
    //  Graphics bg = backbuffer.getGraphics();

}

public void actionPerformed (ActionEvent e)
{
    if (e.getSource () == buttonC)
    { 
        calculate();

    }

}

public void calculate(){
    double a,b;
    DecimalFormat Formatter = new DecimalFormat("#0.00");
    try
    {
        a = Double.parseDouble (text1.getText());
        b = Double.parseDouble (text2.getText());
        double hypot=Math.sqrt(a*a + b*b);
        label3.setText("The length of the hypotenuse is: " + Formatter.format(hypot));
    }
    catch (NumberFormatException ex)
    {

        label3.setText("You're clearly a confused, please use NUMBERS for side lengths.");

    }

}
public void paintComponent(Graphics g){
    super.paintComponent(g);
    g.fillRect(100,100,20,20);

}


public static void main (String[] args)
{
    new Pythag ();

} // main method
} 

Answer:

If you do want to override paint(), then only of top-level-containers, see this for a fuller explanation. Still, the "cleanest" way is to create a new class that extends JPanel and overrides paintComponent(). If you want to repaint the panel at runtime, you can just call repaint(). This is an example:

import javax.swing.*;
import javax.swing.event.*;
import java.awt.*;
import java.awt.Graphics.*;
import java.awt.event.*;
import java.text.*;
import java.util.Random;

public class Pythag {

    public Pythag() {

        JFrame frame = new JFrame("JFrame");

        frame.setContentPane(new MyPanel());

        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setSize(500, 500);
        frame.setVisible(true);

    }

    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new Pythag();
            }
        });

    }

    public class MyPanel extends JPanel {

        int x;
        int y;

        public MyPanel() {

            ActionListener al = new ActionListener() {
                Random r = new Random();

                @Override
                public void actionPerformed(ActionEvent e) {

                    x = r.nextInt(getWidth()); // Random x-coordinate
                    y = r.nextInt(getHeight()); // Random y-coordinate
                    repaint(); // Repaints the panel

                }
            };

            Timer timer = new Timer(500, al); // Runs ever 500 milliseconds.
            timer.start();

        }

        @Override
        public void paintComponent(Graphics g) {

            super.paintComponent(g); // Removes previous drawings

            g.setColor(Color.RED);
            g.fillRect(x, y, 10, 10);

        }

    }

}

Question:

I'm trying to teach myself java and I "try" to code a little game.

I have a problem and I guess the solution is very simple but I'm struggling.

The basic idea is that I am controlling a circle and I want to spawn circles every 5 seconds at random locations within the boundries of my window . The circles should move towords the location of the circle that I'm controlling.

Here's what I have so far:

Window-Class:

package TestGame;
import java.awt.Graphics;

public class Window extends GameIntern{

    public void init(){
        setSize(854,480);   
        Thread th = new Thread(this);
        th.start();
        offscreen = createImage(854,480);
        d = offscreen.getGraphics();
        addKeyListener(this);
    }

    public void paint(Graphics g){
        d.clearRect(0,0,854,480);
        d.drawOval(x, y, 20, 20);
        g.drawImage(offscreen,0,0,this);
    }

    public void update(Graphics g){
        paint(g);
    }
}

GameIntern-Class:

package TestGame;


import java.applet.Applet;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class GameIntern extends Applet implements Runnable , KeyListener {

    public int x,y;
    public Image offscreen;
    public Graphics d;
    public boolean up,down,left,right;

    public void run() {
        x = 100;
        y = 100;

        while(true){
            if(left == true){
                if(x>=4){
                x-=4;
                }else{ x=0;}
                repaint();
            }
            if(right == true){
                if(x<=826){
                    x+=4;
                    }else{ x=830;}
                repaint();
            }
            if(up == true){
                if(y>=4){
                y-=4;
                }else{ y=0;}
                repaint();
            }
            if(down == true){
                if(y<=454){
                y+=4;
                }else{y=459;}
                repaint();
            }
            try {
                Thread.sleep(20);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public void keyPressed(KeyEvent e) {

        if(e.getKeyCode() == 37){
            left=true;
        }
        if(e.getKeyCode() == 38){
            up=true;
        }
        if(e.getKeyCode() == 39){
            right=true;
        }
        if(e.getKeyCode() == 40){
            down=true;
        }

    }


    public void keyReleased(KeyEvent e) {

        if(e.getKeyCode() == 37){
            left=false;
        }
        if(e.getKeyCode() == 38){
            up=false;
        }
        if(e.getKeyCode() == 39){
            right=false;
        }
        if(e.getKeyCode() == 40){
            down=false;
        }


    }

    public void keyTyped(KeyEvent e){}
}

I know it's nothing fancy but I'm struggling with how to create and spawn the "enemy"-circles and how to controll the x/y values of every single created circle to move towards the controllable circle.

Any form of help is appreciated.


Answer:

Note Using thread.sleep in a game is not a good idea. This is an example of a game loop with 60 iterations a second.

public void run() {
    double ns = 1000000000.0 / 60.0;
    double delta = 0;

    long lastTime = System.nanoTime();

    while (running) {
        long now = System.nanoTime();
        delta += (now - lastTime) / ns;
        lastTime = now;

        while (delta >= 1) {
            tick();
            delta--;
        }
    }
}

You would then need to move your code that controls your game into a tick() method. (or the equivalent)

private void tick() {
    if(left == true){
        if(x>=4){
            x-=4;
            }else{ x=0;}
            repaint();
        }
        if(right == true){
            if(x<=826){
                x+=4;
                }else{ x=830;}
            repaint();
        }
        if(up == true){
            if(y>=4){
            y-=4;
            }else{ y=0;}
            repaint();
        }
        if(down == true){
            if(y<=454){
            y+=4;
            }else{y=459;}
            repaint();
}

Answer I would make a new class containing the information for your enemies. It needs a constructor with an int x and int y and a tick() method.

public class Enemy {

    public enemy(int x, int y) {
        this.x = x;
        this.y = y;
    }

    public void tick() {
    }
}

You can then make an ArrayList containing your enemies in your GameIntern class

private static ArrayList<Enemy> enemies = new ArrayList<Enemy>();

This allows you to have as many enemies as you want. You will need to update the enemies by calling all of their tick() methods with a for loop. The following needs to be added to the tick() method in GameIntern

for (Enemy e : enemies) {
    e.tick();
}

To add an enemy every 5 seconds with a random location inside of the screen you will need an int delay. The following is added to the tick() method in GameIntern

private int delay;
private Random random= new Random();

private void tick() {
    delay++;
    if(delay % (60 * 5) == 0)
        enemies.add(new Enemy(random.nextInt(your game width), random.nextInt(your game height));

To make the enemy chase you, add this to your tick() method in Enemy

if (x < GameIntern.x) x++;
if (x > GameIntern.x) x--;
if (y < GameIntern.y) y++;
if (y > GameIntern.y) y--;

For information about removing enemies see here

Question:

First off, this is homework so I'm not asking for the answer, just some pointers on how to continue with what I'm doing.

I've got to make a recursive applet that draws the measurement ticks from a ruler like the ones on the bottom of this:

(source: myonlineruler.com)

So far I've been able to get the tallest lines, but the marks in between aren't shrinking:

And here's my code:

import java.applet.Applet;
import java.awt.*

public class RulerOfTheWorld extends Applet
{
  private Image display;
  private Graphics drawingArea;

  public void init()
  {
    setSize( 600, 400 );
    int height = getSize().height;
    int width = getSize().width;
    display = createImage( width, height );
    drawingArea = display.getGraphics();

    drawRuler( 0, height / 2, width, height / 2, drawingArea );
  }

  public void paint( Graphics g )
  {
    g.drawImage( display, 0, 0, null );
  }

  public static void drawRuler( int leftX,
                                int leftY,
                                int rightX,
                                int rightY,
                                Graphics drawingArea )
  {
    final int STOP = 40;
    int midX = ( leftX + rightX ) / 2;
    int midY = ( leftY + rightY ) / 2;

    if(( rightX - leftX ) <= STOP )
    {
      drawingArea.drawLine( midX, leftY, midX, midY / 2 );
      drawingArea.drawLine( leftX, leftY, rightX, rightY );
    }
    else
    {
      drawRuler( leftX, leftY, midX, midY, drawingArea );
      drawRuler( midX, midY, rightX, rightY, drawingArea );
    }
  }
}

I've been poking things to see the effect on how things are drawn but I can't seem to come up with anything that works; my lines get skewed. When trying to divide the "top" y-coordinate in the recursive call by 2:

if(( rightX - leftX ) <= STOP )
{
  drawingArea.drawLine( midX, leftY, midX, midY / 2 );
  drawingArea.drawLine( leftX, leftY, rightX, rightY );
}
else
{
  drawRuler( leftX, leftY, midX, midY/2, drawingArea );
  drawRuler( midX, midY, rightX, rightY/2, drawingArea );
}

I get:

If I try dividing the "initial" y-coordinates by 2

  drawRuler( leftX, leftY/2, midX, midY, drawingArea );
  drawRuler( midX, midY/2, rightX, rightY, drawingArea );

I get:

It seems to be like there's something fundamental about drawing graphics in an applet that I'm not understanding. We didn't cover anything of the sort in class and then got this assignment dumped on us.

Like I said, I'm not looking for the answer, just some advice or corrections to what I'm trying. Thanks.


Edit 1

I should note that my instructor said we should be able to complete this by looking at an example from the book on making a "random fractal line". Here's the example from the book:

import java.applet.Applet;
import java.awt.*;


public class Fractal extends Applet
{
  private Image display;
  private Graphics drawingArea;

  public void init()
  {
    int height = getSize().height;
    int width = getSize().width;
    display = createImage( width, height );
    drawingArea = display.getGraphics();

    randomFractal( 0, height/2, width, height/2, drawingArea );
  }

  public void paint( Graphics g )
  {
    g.drawImage( display, 0, 0, null );
  }

  public static void randomFractal( int leftX,
                                    int leftY,
                                    int rightX,
                                    int rightY,
                                    Graphics drawingArea )
  {
    final int STOP = 4;
    int midX, midY;
    int delta;

    if(( rightX - leftX ) <= STOP )
    {
      drawingArea.drawLine( leftX, leftY, rightX, rightY );
    }
    else
    {
      midX = ( leftX + rightX ) / 2;
      midY = ( leftY + rightY ) / 2;

      delta = ( int ) (( Math.random() - 0.5 ) * ( rightX - leftX ) );
      midY += delta;

      randomFractal( leftX, leftY, midX, midY, drawingArea );
      randomFractal( midX, midY, rightX, rightY, drawingArea );
    }
  }
}

Edit 2

@Mike Ounsworth, I'd tried something similar but there is one set of lines that is always slanted:

I didn't change my method header but I organized my data in a similar fashion:

public static void drawRuler( int leftX,
                              int bottomY,
                              int rightX,
                              int topY,
                              Graphics drawingArea )
{
  final int STOP = 40;
  int midX = ( leftX + rightX ) / 2;

  if(( rightX - leftX ) <= STOP )
  {
    drawingArea.drawLine( leftX, bottomY, rightX, topY );
  }
  else
  {
    drawingArea.drawLine( midX, bottomY, midX, topY );

    drawRuler( leftX, bottomY, midX, topY / 2, drawingArea );
    drawRuler( midX, bottomY, rightX, topY / 2, drawingArea );
  }
}

Edit 3

Oooooo I found where the slanted lines were coming from, I wasn't using the same y-coordinates for the baseline. Woops. Here's what it looks like now:

if(( rightX - leftX ) <= STOP )
{
  drawingArea.drawLine( leftX, bottomY, rightX, bottomY );
}

And:


Answer:

Let's see if we can give you something useful to think about without giving too much:

The way recursion works is that at each step you do the same thing you did before, but on a (usually) smaller version of the data. In the code you posted you are dividing the drawing area into half and recursing on the right and left halfs, drawing lines somewhere in there. Ok. Recursive functions have two parts 1) the recursive step which is your loop, doing some work and then splitting the problem in half, and 2) the base case, which is the point at which you stop recursing because the problem can't be split any smaller. So, questions for you to think about:

1) in the recursive step, before you make the recursive call, do you want to draw a line? If so where, and how tall?

2) in the base case, when you've gotten to the bottom of your recursion and the problem can't be split any more, do you want to draw a line? If so where, and how tall?

Hint 1: you may first need to start by breaking the x-axis into 8 "1 inch" chunks and the recursing on each chunk separately.

Hint 2: Graphics.drawLine() has the following definition:

drawLine(int x1, int y1, int x2, int y2)
    Draws a line, using the current color, between the points (x1, y1) and (x2, y2) in this graphics context's coordinate system.

So if you want vertical lines, make sure x1 == x2, if you want horizontal lines, make sure y1 == y2, anything else will give slanted lines.

Hint 3 (this is fun!): try using this as a recursive step and see what happens [you'll have to tweak the method header to be drawRuler(leftX, rightX, topY, bottomY) ]

else
{
  drawingArea.drawLine( midX, bottomY, midX, topY );

  drawRuler( leftX, midX, topY/2, bottomY, drawingArea );
  drawRuler( midX, rightX, topY/2, bottomY, drawingArea );
}

Question:

For some reason, this code will not render anything. Can someone explain to me why it doesn't do anything?

import java.awt.*;   
import java.applet.*; 

public class TEST extends Applet {
    public void paint(Graphics g) {
        int xSize = 255;
        int ySize = 255;
        byte R, G, B;

        for(int x = 0; x < xSize; x++) {
            for(int y = 0; y < ySize; y++) {
                R = (byte) (x % y);
                G = (byte) (y % x);
                B = (byte) (y);
                Color pixel = new Color(R, G, B);
                g.setColor(pixel);
                g.fillRect(x, y, 1, 1);
            }
        }
    }
}

Answer:

Its not possible to get the modulus of a number relative to 0 e.g. here

R = (byte)(x%y);

in the first iteration. You're probably seeing an ArithmeticException occur at this point. You could simply start from 1:

red = (byte) (x % (y + 1));
green = (byte) (y % (x + 1));

Question:

I'm trying to write a simple program that draws fractals, and wrote the following code. I ran it to test whether it worked and found that it runs twice every time. I looked for answers and found that it likely has something to do with the graphics window redrawing and re-running the entire code as a result. In other questions I've seen, no one seemed concerned with making the code not run multiple times, but rather why it was doing so, and no remedies were provided as a result. However, Because of the fact that I'm using Scanners, it's extremely inconvenient to have the program run repeatedly and my primary concern is making it run only once.

import java.awt.*;
import java.applet.*;
import java.util.Scanner;
public class FractalCreator extends Applet
{
     public void paint(Graphics g)
     {
          Scanner s=new Scanner(System.in);
          System.out.println("How many branches do you want each node to have?");
          int branches=s.nextInt();
          System.out.println("How many times do you want the fractal to repeat?");
          int repetitions=s.nextInt();
     }
}

What I want to know is how I can stop the graphics window from redrawing and re-running everything, or, if that isn't possible, what alternatives I have to the Graphics class to draw things in.

I put the code into non-Applet code with a main method and it ran once, as it was intended to.

If it is relevant, I'm using DrJava as an IDE.


Answer:

The answer to your question is, you can't.

So you screwing a bunch of things up. An applet won't (normally) have a console for use interaction - you especially shouldn't be doing this from within the paintmethod as this could adversely effect the user interaction with your UI.

GUI's are event driven environments, that is, something happens and you respond to it. You are still thinking in a linear/procedural/console based way

My first piece of advice is, don't use applets, at all, they aren't worth your time to learn right now. If you want a graphical output, I would start by having Creating a GUI With JFC/Swing for a better understanding of how to interact with users through an event driven environment.

I'd then suggest you have a look at Painting in AWT and Swing and Performing Custom Painting for a better understanding of how painting works in Swing.

Question:

I am trying to change the y position of the rectangle, however, whenever I try to, it expands/gets bigger vertically.

public class PlayerPaddle implements Paddle {

    double yVelocity;
    final double GRAVITY = 0.94;

    //move up/down faster (if not accelerating = slow down)
    boolean upAccel, downAccel;

    //determines if player 1 or player 2 (on left or on right)
    int player;

    //position of actual paddle
    int x;
    double y;


    Rectangle panel;

    public PlayerPaddle(int player) {

        upAccel = false;
        downAccel = false;

        y = 210; //not moving initially
        yVelocity = 0;

        if (player == 1) {
            //left side
            x = 20;
        } else {
            //right side
            x = 660;
        }
    }


    @Override
    public void draw(Graphics g) {

        //draw paddle
        g.setColor(Color.WHITE);
        g.fillRect(x, (int) y, 20, 80);
    }


    @Override
    public void move() {

        if (upAccel) {
            yVelocity -= 2;
        } else if (downAccel) {
            yVelocity += 2;
        } else if ((!upAccel) && (!downAccel)) {
            yVelocity *= GRAVITY;
        }
        y += yVelocity; //changes y position of paddle
    }

    public void setUpAccel(boolean input) {
        upAccel = input;
    }

    public void setDownAccel(boolean input) {
        downAccel = input;
    }

    @Override
    public int getY() {
        return (int) y;
    }
}

I want to know how to make the rectangle move up and down vertically. A similar question had only one answer which said that the previously painted rectangle was not being cleared and as a result is expanding. But even when I say g.clearRect(...) it still expands and does not move.

I am new to Swing and Awt but I am really committed to learning. Thanks for the help.


Answer:

A similar question had only one answer which said that the previously painted rectangle was not being cleared and as a result is expanding

And that is still probably the problem here.

Somewhere, not in the code presented here, you need to invoke the draw(...) method of this class.

So in that code you need to make sure the background of the component is cleared before you draw the paddle. Since you should be overriding the paintComponent(...) method of a panel to do custom painting your code should look something like:

@Override
protected void paintComponent(Graphics g)
{
    super.paintComponent(g);
    // draw the paddle
}

Read the section from the Swing tutorial on Custom Painting for more information and working examples.

I am new to Swing and Awt but I am really committed to learning.

Then keep a link to the tutorial handy for all Swing basics.

Question:

I am trying to output a math function, but I cannot figure out how to call my class that draws/calculates the function.

In the main class, I've tried the following

public class GraphingProgram {

public static void main(String[] args) 
{

        Applet program = new Applet();
        program.setSize(300, 400);
        program.setName("Graphing Program");

        GraphApplet testFunction = new GraphApplet();
        program.add(testFunction);
        program.setVisible(true);    
}   

Class code

public class GraphApplet extends Applet
{

  double f(double x)
    {
    return (Math.cos(x/5) + Math.sin(x/7) + 2) * getSize().height/ 4;              
    }
  public void paint (Graphics g)
    {
        for(int x = 0; x< getSize().width; x++)
        g.drawLine(x, (int) f(x), x+1, (int) f(x+1));
    }
  public String getAppletInfo()
    {
        return "Draw a function graph";
    }

 }

When executing the program, we should expect to see the graph of the function of the class. For example, I should be able to out put the graph f(x) = cos(x/5) + sin(x/7) + 2 on a given interval as shown bellow

!https://i.imgur.com/przHRk6.png


Answer:

In NetBeansIDE 8.2, I had to simply press F6 while in the GraphApplet class to output the graph.

Question:

I wrote a Java applet that prints a text on the canvas at the same position after getting updated in every iteration of a loop. The text value changes and the output is correct but the clearRect() method I call in the loop to clear the area of the text before printing out each time doesn't work and the text gets overwritten. I can see the output up to 2-3 iterations but then it's not readable. The applet actually performs a countdown and displays the time in HH : MM : SS format. Below is my code. Please predict the cause of this and/or correct it:

/* Only the section of the code I'm having problems in is included */

while (t>=0) {
    //int t stores total time in seconds
    int h=(t/3600);
    int m=((t%3600)/60);
    int s=((t%3600)%60);
    str=h+" : "+m+" : "+s;
    /* String str holds data to be displayed, i.e., time in HH : MM : SS format */
    g.clearRect(20,200,150,30);
    g.drawString(str,20,200);
    try{
        Thread.sleep(1000); //elapses 1 second
    }
    catch(Exception e) {}
    t=t-1;
}

Answer:

use drawRect with a color instead of clearRect. just like how @ControlAltDel explained it. I am not sure if that code above is located in your paint or run. I would still recommend to have runnable method instead of drawing it in a loop. Similar to this link. Good luck

Question:

In my code, I would like to have the method, paintComponent1 (draw a line) to run based on whether or not the key is pressed. How would I go about that? All help is appreciated, Thanks :D!

Here is my code:

    import java.awt.event.KeyEvent;
    import java.awt.*;
    import java.applet.Applet; 


    public class Test {
    boolean x = false;

    public void paintComponent1(Graphics g){
       g.drawLine(35, 60, 100, 120);


    }


    public void keyPressed(KeyEvent e) {
      x = true;
    }

    public void keyReleased(KeyEvent e) {
      x = false;
    }


    public void paintComponent(Graphics g) {
      if (x) 
          paintComponent1();

}
}

Answer:

Why don't you just move paintComponent1() into the keyPressed method?

public void keyPressed(KeyEvent e)
{
    if(e.getKeyCode() == KeyEvent.VK_SPACE) // if you press the space bar key
    {
        paintComponent1();
    }
}

Question:

I want to do Java 3D Graphics without using external libraries to develop a game applet. Sorry I am not that experienced with Graphics and so I am not sure how hard it would be to do it by myself


Answer:

The real answer to your question is that you're thinking about it a bit sideways: you shouldn't be using an applet (they're dead), and you shouldn't try to do it all by yourself without any libraries.

I'd personally recommend Processing for beginners or libGDX for more experienced users. They both allow you to do 3D, and they both allow you to deploy as JavaScript- which is better than applets.

If you really, really, really want to try to do this without any libraries, then you'll have to do all the 3D math and whatnot yourself, then do the drawing in Java2D. A very basic example of getting started is here, but like I said, you're on your own to do all the conversions from 3D world space to 2D drawing space.

Any sane person would use something like OpenGL instead, which you can find Java wrappers for- JOGL is a pretty basic wrapper (so if your goal is to get "close to the metal" then this might be your best bet), LWJGL provides a few extra features for game development, and the already-mentioned libGDX is built on top of LWJGL.

If you're afraid of using libraries because you think they're too complicated, let me tell you that doing 3D stuff without a library is even more complicated.

Question:

I have never run a Java code and I want to run the code I am going to post below. So can someone tell me how I can run the code on Ubuntu including what things I should install?

I also want to modify it and put a heart image on the guy's chest and write I LOVE YOU. Can anyone help me with that as well?

import java.awt.*;
import java.applet.*;

public class FunnyClown extends Applet {

    public void init() {
    }

    public void paint(Graphics g) {

        g.drawString("See!  A Funny Clown=)", 30, 30 );

        //Draw a beautiful sky
        setBackground(Color.cyan);

         //Grass
        g.setColor(Color.green);
        g.fillRect(0,580,1500,3000);

        //Draw a round face
        g.setColor(Color.white);
        g.fillArc(555,300,140,150,0,360);

        //Eyes
        g.setColor(Color.black);
        g.fillArc(600,360,15,20,0,360);
        g.fillArc(640,360,15,20,0,360);

        //Smile
        g.setColor(Color.red);
        g.drawArc(615,420,20,8,190,200);

        //Hat
        g.setColor(Color.pink);
        g.fillArc(520,290,205,60,0,360);
        g.fillRect(568,220,115,100);
        g.fillArc(568,200,115,50,0,360);

        //Ribbons
        g.setColor(Color.white);
        g.fillRect(568,285,115,15);

        //Body
        g.setColor(Color.white);
        g.fillRect(543,470,25,70);
        g.fillRect(683,470,25,70);
        g.fillArc(543,535,20,25,0,360);
        g.fillArc(685,535,20,25,0,360);

        //T-shirt
        g.setColor(Color.yellow);
        g.fillRect(570,450,110,200);
        int []x1={570,500,570};
        int []y1={450,475,490};
        g.fillPolygon(x1,y1,3);
        int []x2={680,750,680};
        int []y2={450,475,490};
        g.fillPolygon(x2,y2,3);

        //Pants
        g.setColor(Color.blue);
        g.fillRect(570,580,110,150);
        g.setColor(Color.green);
        int []x3={625,598,638};
        int []y3={600,730,730};
        g.fillPolygon(x3,y3,3);

        //Shoes
        g.setColor(Color.black);
        g.fillArc(570,728,35,30,0,360);
        g.fillArc(642,728,35,30,0,360);

        //Clouds
        g.setColor(Color.white);
        g.fillArc(100,100,60,60,0,360);
        g.fillArc(120,120,70,70,0,360);
        g.fillArc(120,80,70,70,0,360);
        g.fillArc(160,70,80,80,0,360);
        g.fillArc(190,75,90,90,0,360);
        g.fillArc(240,85,60,60,0,360);
        g.fillArc(220,110,70,70,0,360);
        g.fillArc(170,120,70,70,0,360);

        //Sun
        g.setColor(Color.yellow);
        int x[]={900,1080,1180,980,1080,1180,800,900,1000};
        int y[]={100,80,150,80,100,80,110,100,60};
        g.fillPolygon(x,y,9);
        g.setColor(Color.red);
        g.fillArc(1015,50,80,80,0,360);

        //Flower
        g.setColor(Color.magenta);
        g.fillArc(80,500,20,20,0,360);
        g.fillArc(95,485,20,20,0,360);
        g.fillArc(110,500,20,20,0,360);
        g.fillArc(86,515,20,20,0,360);
        g.fillArc(103,515,20,20,0,360);
        g.setColor(Color.yellow);
        g.fillArc(95,503,20,20,0,360);
        g.setColor(Color.darkGray);
        g.fillRect(103,525,5,70);

        g.setColor(Color.magenta);
        g.fillArc(300,500,20,20,0,360);
        g.fillArc(315,485,20,20,0,360);
        g.fillArc(330,500,20,20,0,360);
        g.fillArc(306,515,20,20,0,360);
        g.fillArc(323,515,20,20,0,360);
        g.setColor(Color.yellow);
        g.fillArc(315,503,20,20,0,360);
        g.setColor(Color.darkGray);
        g.fillRect(323,525,5,70);

        g.setColor(Color.magenta);
        g.fillArc(190,500,20,20,0,360);
        g.fillArc(205,485,20,20,0,360);
        g.fillArc(220,500,20,20,0,360);
        g.fillArc(196,515,20,20,0,360);
        g.fillArc(217,515,20,20,0,360);
        g.setColor(Color.yellow);
        g.fillArc(205,503,20,20,0,360);
        g.setColor(Color.darkGray);
        g.fillRect(215,525,5,70);

        //House
        g.setColor(Color.gray);
        int []x4={850,1050,1250};
        int []y4={300,200,300};
        g.fillPolygon(x4,y4,3);
        g.setColor(Color.lightGray);
        g.fillRect(850,300,400,300);


        //Window
        g.setColor(Color.cyan);
        g.drawRect(1100,350,100,100);
        g.drawLine(1100,400,1200,400);
        g.drawLine(1150,350,1150,450);

        //Door
        g.setColor(Color.darkGray);
        g.fillRect(900,400,130,200);
        g.setColor(Color.yellow);
        g.fillArc(930,480,10,10,0,360);





    }
}

Here's what the code supposed to show when you run it:


Answer:

To draw the I love you text you can call: g.drawString(...) method and position it over the T-Shirt.

Next to draw a heart shape, you can call the same method using the ASCII's heart shape:

But be sure to use a nice (big enough) font so it can be visualized correctly, for example:

g.setFont(new Font("Verdana", Font.PLAIN, 25));
g.setColor(Color.BLACK);
g.drawString("I love you", 570, 480);

g.setColor(Color.RED);
g.drawString("♥", 620, 510);

But as you've been said, Java Applets are no longer supported by browsers, there are 2 things you can do:

  1. Convert the code into a Swing Application (recommended)
  2. Use AppletViewer (Which I've never used)

We're going to go through the 1st one:

First, we need to change:

// Draw a beautiful sky
setBackground(Color.cyan);

for:

g.setColor(Color.CYAN);
g.fillRect(0, 0, 1500, 1000); //I'm lazy to search the window size... change it accordingly

Next, we need to remove extends Applet from our class and change it to extends JPanel and change

public void paint(Graphics g) {

To:

@Override
public void paintComponent(Graphics g) {

And add another overriden method:

@Override
public Dimension getPreferredSize() {
    return new Dimension(1500, 1000); //Again, change it to the window's correct size.
}

To finish we need to create a main method as follows:

private JFrame frame;

public static void main(String[] args) {
    SwingUtilities.invokeLater(new FunnyClown()::createAndShowGui);
}

private void createAndShowGui() {
    frame = new JFrame(getClass().getSimpleName());

    this.setOpaque(true);
    frame.add(this);
    frame.pack();
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

Now, if you run the application you should see something like this:

For reference, you're going to need: