Graphics Program in Java
Graphics Program in Java
The graphics program in Java is part of the Swing program in Java. In this section, we will learn about the implementation of custom graphics using some advanced examples.
Creating a Bouncing Ball
The following Java program shows how to create an animated bouncing ball using swing.
FileName: BouncingBallExample.java
// For using the containers and components present in the swing package. import javax.swing.*; // For using color and graphics of AWT import java.awt.*; // The BouncingBallExample class creates // a running animation of a bouncing ball using a customized thread public class BouncingBallExample extends JFrame { // Defining the width and height of the canvas, where the ball bounces private static final int CNVS_HEIGHT = 490; private static final int CNVS_WIDTH = 650; // Defining the interval in milliseconds // Threads sleep for the given interval of time private static final int UPDTE_INTRVL = 51; // reference variable of the DrawCanvas class // used for drawing the canvas private DrawCnvs cnvs; // Characteristics of the bouncing ball private int i = 90; // abscissa private int j = 90; // ordinate private int radius = 240; // radius of the bouncing ball private int iSpeed = 3; // defining speed in the x direction private int jSpeed = 6; // defining speed in the x direction // Constructor of the class // used for event handling and set-up purpose public Server() { cnvs = new DrawCnvs(); // object of the DrawCanvas class cnvs.setPreferredSize(new Dimension(CNVS_WIDTH, CNVS_HEIGHT)); this.setContentPane(cnvs); // terminating the program on pressing the X button this.setDefaultCloseOperation(EXIT_ON_CLOSE); // for maximizing the canvas to the specified dimensions this.pack(); this.setTitle("A Yellow Bouncing Ball"); this.setVisible(true); // Create a new thread to run update at regular interval Thread th = new Thread() { @Override public void run() { while (true) { updt(); // update the (x, y) position repaint(); // doing the repainting work try { // Making the thread to sleep for 51 milliseconds Thread.sleep(UPDTE_INTRVL); } catch (InterruptedException ignore) {} } } }; // starting the thread hence the run() method is called th.start(); } // Update the coordinates of the bouncing ball public void updt() { i = i + iSpeed; j = j + jSpeed; if (i > CNVS_WIDTH - radius || i < 0) { iSpeed = -iSpeed; } if (j > CNVS_HEIGHT - radius || j < 0) { jSpeed = -jSpeed; } } // Defining the inner class DrawCnvs // This class is used for custom drawing class DrawCnvs extends JPanel { @Override public void paintComponent(Graphics grph) { // painting the parent background super.paintComponent(grph); // Setting the background color to BLUE setBackground(Color.BLUE); // the bouncing ball is of the YELLOW colour grph.setColor(Color.YELLOW); // drawing a circle at position (i, j) grph.fillOval(i, j, radius, radius); } } // main method public static void main(String argvs[]) { // Fror performing task using a event dispatching thread SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // constructor is invoked for doing the set-up and event handling job new BouncingBallExample(); } }); } }
Output:
Explanation: The output is an animation where the yellow bouncing ball changes its direction on hitting the boundary of canvas. In the output, 4 different positions of the bouncing ball are shown.
The motion of the ball is handled by a thread that calls the updt() method. The updt() method changes the coordinates of the yellow ball. However, only changing the coordinates does not change the position of the ball. The actual change in the position is done by the repaint() method. The repaint() method cleans the window then calls the paint() method. The paint() method draws the yellow ball again with the updated coordinates. Since the thread sleeps for 51 milliseconds the update() as well as the repaint() method is called after 51 milliseconds. Therefore, the yellow ball changes its position after 51 milliseconds. Update the value of interval to increase/ decrease the speed of the yellow ball.
The SwingUtilities.invokeLater() method is a static method that allows to perform tasks asynchronously. The invokeLater() method sends the job to swing to execute on the event dispatch thread. However, the method does not guarantee the execution immediately, as it is asynchronous. This method is very handy when multithreading is used along-with Java Swing.
Moving a Line using Arrow Key
The following Java program shows how to create an animated bouncing ball Java using swing.
FileName: MovingLineExample.java
// For color and graphics import java.awt.*; // For listener interface import java.awt.event.*; // For Swing's containers and components import javax.swing.*; // The MovingLineExample class uses button / arrow keys to move the line right or left public class MovingLineExample extends JFrame { // Define constants for the various dimensions // Defining width and height of the canvas public static final int CNVS_HEIGHT = 350; public static final int CNVS_WIDTH = 550; // the line is of white colour // and the background color is black public static final Color LINE_CLR = Color.WHITE; public static final Color CNVS_BACKGROUND = Color.BLACK; // Drawing a vertical line from (i1, j1) to (i2, j2) // The position of the line is initially at center of the canvas private int i1 = CNVS_WIDTH / 2; private int j1 = CNVS_HEIGHT / 9; private int i2 = i1; private int j2 = CNVS_HEIGHT / 9 * 6; private DrawCnvs cnvs; // The custom drawing canvas (an inner class extends JPanel) // Constructor to set up the GUI components and event handlers public MovingLineExample() { // Creating a panel for buttons JPanel buttonPanel = new JPanel(new FlowLayout()); // create a button for leftward movement of the line JButton buttonLeft = new JButton("Move <- "); buttonPanel.add(buttonLeft); // adding the button to button panel buttonLeft.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { // control is reached here only when the button is pressed i1 = i1 - 11; i2 = i2 - 11; cnvs.repaint(); // repainting the canvas with new coordinates requestFocus(); // change the focus to JFrame to receive KeyEvent } }); // create a button for rightward movement of the line JButton buttonRight = new JButton("Move ->"); buttonPanel.add(buttonRight); // adding the button to the button panel buttonRight.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent event) { // control is reached here only when the button is pressed i1 = i1 + 11; i2 = i2 + 11; cnvs.repaint(); // repainting the canvas with new coordinates requestFocus(); // change the focus to JFrame to receive KeyEvent } }); // creating an object for the canvas cnvs = new DrawCnvs(); // creating a canvas of specified width and height cnvs.setPreferredSize(new Dimension(CNVS_WIDTH, CNVS_HEIGHT)); // Adding canvas and the button panel to // the content pane of the JFrame Container cp = getContentPane(); cp.setLayout(new BorderLayout()); cp.add(cnvs, BorderLayout.CENTER); cp.add(buttonPanel, BorderLayout.SOUTH); // Handling the arrow movement when left and right // arrow keys are pressed addKeyListener(new KeyAdapter() { @Override public void keyPressed(KeyEvent event) { switch(event.getKeyCode()) { case KeyEvent.VK_LEFT: // when left arrow key is pressed do the following i1 = i1 - 11; i2 = i2 - 11; repaint(); // repaint the line with new coordinates break; case KeyEvent.VK_RIGHT: // when right arrow key is pressed do the following i1 = i1 + 11; i2 = i2 + 11; repaint(); // repaint the line with new coordinates break; } } }); // Terminating the application when x button is pressed setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Setting the title setTitle("Moving a Vertical Line"); pack(); // include all the parts in the frame setVisible(true); // display it // focus should be on the frame // to get a KeyEvent requestFocus(); } // Defining the inner class DrawCnvs, which extends JPanel to do the custom // drawing. class DrawCnvs extends JPanel { // painting the canvas and drawing the line // with the specified parameters @Override public void paintComponent(Graphics grph) { // painting the background of parent super.paintComponent(grph); // setting background color setBackground(CNVS_BACKGROUND); // setting line color grph.setColor(LINE_CLR); // drawing a vertical line grph.drawLine(i1, j1, i2, j2); } } // main method public static void main(String argvs[]) { // To achieve thread safety, put the GUI codes on the Event-Dispatcher Thread SwingUtilities.invokeLater(new Runnable() { @Override public void run() { // invoking the constructor to do the set up and event hanlding job new MovingLineExample(); } }); } }
Output:
Pressing the Move -> button / right arrow key three times to change the position of the line as shown in the following snapshot.
Pressing the Move <- button / left arrow key six times the following position of the line is achieved.
Explanation: Initially, the line is positioned at the center of the canvas, which is achieved by dividing the canvas width by 2. For buttons, an appropriate panel is created. The panel is then added to the container of JFrame. The same treatment is done to canvas.
To handle the movement of the line using buttons, appropriate buttons with their actionListeners() are used. Similar scenario for the left and right arrow keys.
The requestFocus() method plays a very important role in the functioning of the application. This method shifts the focus to the keys or buttons when we move from one application to the other application. If the method is removed, the functioning of arrows keys stops, as the focus is never shifted towards the arrow key. The rest of the above-written code is similar to the previous program.