How To Put Stuff On The Screen?
Let’s get back to putting stuff on the screen now that we’ve learned a little bit about how events work (we’ll learn more later). Before returning to event handling, we’ll spend a few minutes experimenting with some fun ways to get graphics.
1 Put widgets on a frame
Add buttons, menus, radio buttons, etc.
frame.getContentPane().add(myButton);
The javax.swing package has more than a dozen widget types.
2 Draw 2D graphics on a widget
Use a graphics object to paint shapes.
graphics.fillOval(70,70,100,100);
You can paint a lot more than boxes and circles; the Java2D API is full of fun, sophisticated graphics methods.
3 Put a JPEG on a widget
You can put your own images on a widget.
graphics.drawImage(myPic,10,10,this);
How To Make Your Own Drawing Widget?
If you want to display your own graphics on the screen, you should create your own paintable widget. You place that widget on the frame like a button or any other widget, but when it appears, it will contain your images. You can also make those images move in an animation or change the colors on the screen when you click a button.
It’s easy as pie.
Make a JPanel subclass and override one method, paintComponent ().
The paintComponent() method contains all of your graphics code. Consider the paintComponent() method to be the system’s way of saying, “Hey widget, it’s time to paint yourself”.
If you want to draw a circle, the paintComponent() method will contain the necessary code, paintComponent() is called when the frame containing your drawing panel is displayed, and your circle appears. If the user iconifies/minimizes the window, the JVM recognizes that the frame requires “repair” when it is de-iconified and calls paintComponent() once more. Your paintComponent() method will be called whenever the JVM believes the display needs to be refreshed.
Another thing is that you never call this method yourself! This method’s argument (a Graphics object) is the actual drawing canvas that is slapped onto the actual display. You cannot obtain this on your own; it must be provided by the system. However, as you’ll see later, you can ask the system to refresh the display (repaint()), which causes paintComponent() to be called.
// do not forget to import this package
import java.awt.*;
// you also have to import this package to draw a widget
import javax.swing.*;
// make JPanleDemo a subclass of JPanel by extending JPanel
// by doing so your JPanelDemo class becomes a JPanel
// a widget that you can add to a frame just like
// anything else. Except this one is your
// own customized widget.
class JPanelDemo extends JPanel {
/*This is the Big Important Graphics method.
You will NEVER call this yourself. The
system calls it and says, "Here's a nice
fresh drawing surface, of type Graphics,
that you may paint on now */
public void paintComponent(Graphics g) {
/*Imagine that 'g' is a painting machine. You're
telling it what color to paint with and then
what shape to paint (with coordinates for
where it goes and how big it is) */
g.setColor(Color.RED);
g.fillRect(30,40,200,100);
}
}
If you compile this program then it will compile without any errors. But if you try to run this program then it will show the following error:
Error: Main method not found in class JPanelDemo, please define the main method as:
public static void main(String[] args)
or a JavaFX application class must extend javafx.application.Application
This is because we do not have a main method in this class. This class is just a paintable widget that we created to draw our own drawings. Try to figure out how this class can be used to paint our custom drawings on the display.
Hint: Make an object of this class and add that to an instance of JFrame object much like a JButton.
How To Display An Image?
public void paintComponent(Graphics g) {
/* Your file name goes to the constructor as an argument.
Note: If you’re using an IDE and have difficulty,
try this line of code instead:
Image image = new ImageIcon(getClass().
getResource("anImage.jpg")).getImage();
*/
Image image = new ImageIcon("anImage.jpg").getImage();
/*
The first argument is the image object you want to display.
The next two arguments are the x,y coordinates for where the
picture's top left corner should go. This says "3 pixels from
the left edge of the panel and 4 pixels from the top edge of the
panel". These numbers are always relative to the widget (in this
case your JPanel subclass), not the entire frame.*/
g.drawImage(image,3,4,this);
}
In this example, we have removed the repeated code and only defined the paintComponent() method. If you are puzzled, consider the preceding example.
How To Paint A Randomly-Colored Circle On A Black Background?
import javax.swing.*;
import java.awt.*;
class RandomCircleWidget extends JPanel{
@Override
public void paintComponent(Graphics g) {
/*The first two args define the (x,y) upper left
corner, relative to the panel, for where drawing
starts, so 0, 0 means "start 0 pixels from the
left edge and 0 pixels from the top edge." The
other two args say, "Make the width of this
rectangle as wide as the panel (this.width()), and
make the height as tall as the panel (this.height)" */
g.fillRect(0,0,this.getWidth(), this.getHeight());
int redColor = (int) (Math.random() * 256);
int greenColor = (int) (Math.random() * 256);
int blueColor = (int) (Math.random() * 256);
/*You can make a color by passing in 3 ints
to represent the RGB values. */
Color randColor = new Color(redColor, greenColor, blueColor);
g.setColor(randColor);
/*start 50 pixels from the left, 50 from
the top, make it 200 pixels wide, and
200 pixels tall. */
g.fillOval(50,50,200,200);
}
}
public class RandomCircleDemo{
public static void main(String[] args) {
JFrame frame = new JFrame();
RandomCircleWidget rcw = new RandomCircleWidget();
frame.getContentPane().add(rcw);
// do not forget to add the following two lines
// otherwise you will not see anything on the display.
frame.setSize(400, 400);
frame.setVisible(true);
// to exit the program when you close the window
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
Output
The Graphics2D Object
Behind every good Graphics reference is a Graphics2D object.
public void paintComponent(Graphics g) {
}
So the parameter ‘g’ IS-A Graphics object. That is, it could be a subclass of Graphics (because of polymorphism).
And, indeed, it is. The object referenced by the ‘g’ parameter is actually an instance of the Graphics2D class.
Why should you care? Because a Graphics2D reference allows you to do things that a Graphics reference does not. A Graphics2D object can do more than a Graphics object, and it really is a Graphics2D object lurking behind the Graphics reference.
Keep your polymorphism in mind. The compiler determines which methods can be called based on the reference type rather than the object type. If you have a Cat object that is referenced by an Animal variable:
Animal animal = new Cat();
You CANNOT say:
animal.meow();
Despite the fact that you know it’s a Cat back there. The compiler examines ‘a,’ notices that it is of type Animal, and discovers that there is no remote control button for meow() in the Animal class. However, you can still return the object to the Cat it truly is. by saying:
Cat cat = (Cat) animal;
cat.meow;
So the Graphics object’s bottom line is this:
If you need to use a method from the Graphics2D class, you cannot directly use the paintComponent parameter ('g'). However, you can cast it using a new Graphics2D variable.
Graphics2D g2d = (Graphics2D) g;
Methods you can call on a Graphics reference:
drawImage() drawLine() drawPolygon drawRect() drawOval() fillRect() fillRoundRect() setColor()
To cast the Graphics2D object to a Graphics2D reference:
Graphics2D g2d = (Graphics2D) g;
Methods you can call on a Graphics2D reference:
fill3DRect() draw3DRect() rotate() scale() shear() transform() setRenderingHints()
These are not complete method lists; for more information, consult the API. Experiment with the API to gain a better understanding of graphics. It is impossible to cover everything in this tutorial.