Easy to Learn Java: Programming Articles, Examples and Tips

Start with Java in a few days with Java Lessons or Lectures

Home

Code Examples

Java Tools

More Java Tools!

Java Forum

All Java Tips

Books

Submit News
Search the site here...
Search...
 
Search the JavaFAQ.nu
1000 Java Tips ebook

1000 Java Tips - Click here for the high resolution copy!1000 Java Tips - Click here for the high resolution copy!

Java Screensaver, take it here

Free "1000 Java Tips" eBook is here! It is huge collection of big and small Java programming articles and tips. Please take your copy here.

Take your copy of free "Java Technology Screensaver"!.

Easy Learn Java: Programming Articles, Examples and Tips - Page 483


Previous 1060 Stories (530 Pages, 2 Per Page) Next

Easy Java Lecture 12a: Painting Concepts. Teach/learn online

Go to all tips in Java Lectures by Anatoliy Malyarenko

Introduction to Painting Concepts

by: Anatoliy Malyarenko

Contents

  • The Coordinate System
  • The Graphics Object and Graphics2D
  • Implementing a Custom Component
  • Example
  • GraphicsDemo.html
  • GraphicsPanel.java
  • GraphicsDemo.java
  • Conclusion

The Coordinate System


Each component has its own integer coordinate system, ranging from (0, 0) to (width - 1, height - 1), where width and height are the size of the component in pixels. As the following figure shows, the upper left corner of a component's painting area is (0, 0). The x coordinate increases to the right, and the y coordinate increases downward.

When painting, you must take into account not only the component's size but also the size of the component's border, if any. For example, a border that paints a one-pixel line around a component effectively changes the top leftmost corner of the component's non-background painting area from (0,0) to (1,1) and reduces the width and the height of the painting area by two pixels each (one pixel per side). The following figure demonstrates this:


You can get the width and height of any JComponent using its getWidth and getHeight methods. The getSize method is another option that works for all Components. To deter mine the border size, use the getInsets method.

The Graphics Object and Graphics2D

The Graphics object passed into the paintComponent method provides both a context and some methods for simple painting. In almost every case, Graphics objects are actually Graphics2D objects. The Graphics2D class extends Graphics to provide more sophisticated control over geometry, coordinate transformations, colour management, and text layout.

You can cast any Graphics parameter into a Graphics2D object as long as your program uses the Java 2 platform (1.2 or later).

The painting methods defined by Graphics include such standbys as drawRect, fillRect, and drawLine. The Graphics2D class adds more flexible methods such as draw(Shape) and fill(Shape).

The graphics context provided by a Graphics object consists of state such as the current painting colour, the current font, and the current painting area. The Graphics2D class adds more state, such as the alpha compositing mode, stroke, rendering hints, and colour patterns such as textures and gradients.

In JComponents, the Graphics object is initialised just before it's passed to paintComponent, so that its colour and font are set to the foreground colour and font of the component.

Implementing a Custom Component

If you really need to perform custom painting, then you need to decide which superclass to use. Your component can extend JComponent, JPanel, or a more specialised Swing component class.

For example, if you're creating a custom button class, you should probably implement it by extending a button class such as JButton or JToggleButton. That way you'll inherit the state management provided by those classes. If you're creating a component that paints on top of an image, you might want to create a JLabel subclass. A component that's a specialised
container should probably extend JPanel. On the other hand, if you're implementing a component that generates and displays a graph, for example -- with or without providing user interaction -- then you might want to use a JComponent subclass.

When implementing custom painting code for a component, keep these rules in mind:

  • Your custom painting code should be in a method with the signature protected void paintComponent(Graphics).
  • You can -- and probably should -- use a border to paint the outside edges of your component.
  • Except when painting the background of the component, you should avoid painting over the border area of the component. You can determine this area using the getInsets method.
  • Make sure that when the paintComponent method exits, the Graphics object that was passed into it has the same state that it had at the start of the method.
  • To gain access to the power of the 2D graphics API, you can cast the Graphics parameter into a Graphics2D object.

Example

Our example consists of three files.

GraphicsDemo.html

Here is the first file, GraphicsDemo.html.

<HTML>
    <HEAD>
        <TITLE>GraphicsDemo</TITLE>
    </HEAD>
    <BODY>
        <H1>GraphicsDemo</H1>
        <HR>
        <P>
            <APPLET CODE="GraphicsDemo.class" WIDTH="640" HEIGHT="480">
            </APPLET>
        </P>
        <HR>
    </BODY>
</HTML>

This file was created automatically by RealJ. I changed only the width and the height of the applet's window.

GraphicsPanel.java

The next file is called GraphicsPanel.java. This is a subclass of JComponent:

import java.awt.*;
import javax.swing.*;

public class GraphicsPanel extends JComponent {

First of all, our class should contain a reference to trajectory:

private double[] trajectory = null;

You create trajectory in you main class in response to pressing some button. Then, you pass the reference to trajectory into the instance of GraphicsPanel, using the next method:

public void setTrajectory(double[] trajectory) {
    this.trajectory = trajectory;
}

Now we start to write our custom painting code:

public void paintComponent(Graphics g) {

First, we paint an instance of the superclass, JComponent, using its paintComponent method:

super.paintComponent(g);

Next, we must determine, is it the first appearance of our custom JComponent in applet's window? If so, then we paint nothing. Otherwise, we paint something.

How can one distinguish between two cases? The answer is: when our custom JComponent appears for the first time, the value of trajectory is equal to null. Otherwise trajectory points to some array of values. So, the next line of code is

if (trajectory != null) {

Now we prepare to paint. First, we determine the maximal and minimal values in our array:

double maxValue = trajectory[0];
double minValue = trajectory[0];
for (int i=1; i<trajectory.length; i++) {
    if (trajectory[i] > maxValue) {
        maxValue = trajectory[i];
    }
    if (trajectory[i] < minValue) {
        minValue = trajectory[i];
    }
}

In any case we plan to draw x-axis. It follows, that if the actual minimal value is positive, we must put it equal to 0:

if (minValue > 0) {
    minValue = 0;
}

To determine the width and height available for custom painting, we use the getInsets method as follows:

Insets insets = getInsets();

int currentWidth = getWidth() - insets.left - insets.right;

int currentHeight = getHeight() - insets.top - insets.bottom;

Now we create a copy of the Graphics object and cast it into a Graphics2D object.

Graphics2D g2d = (Graphics2D)g.create();

This has two consequences. First, we can guarantee, that the Graphics object g does not change its state. Second, we obtain access to the power of the 2D graphics API, while we do not actually use it in this example.

We paint a white background.

g2d.setColor(Color.white);
g2d.fillRect(insets.left,insets.top,
                    currentWidth,currentHeight);

Now we calculate, how many pixels are containing in one unit of measurement on both x- and y-axes.

double xStep = currentWidth/(trajectory.length-1);
double yStep = currentHeight/(maxValue-minValue);

We put x-axis into the bottom of our window. However, if the minimal value is negative, we must shift the axis up.

int xLocation = insets.left + currentHeight;
if (minValue <0) {
    xLocation += minValue*yStep;
}

We draw axes in black.

g2d.setColor(Color.black);
g2d.drawLine(insets.left,insets.top,
insets.left,currentHeight);
g2d.drawLine(insets.left,xLocation,
            currentWidth,xLocation);

Now we draw graph in blue

g2d.setColor(Color.blue);

for (int i=0; i<trajectory.length-1; i++) {
    g2d.drawLine(insets.left+(int)(i*xStep),
            xLocation+(int)(trajectory[i]*yStep),
            insets.left+(int)((i+1)*xStep),
            xLocation+(int)(trajectory[i+1]*yStep));
    }
and release the copy's resources
            g2d.dispose();
        }
    }
}

GraphicsDemo.java

Our main class, GraphicsDemo.java, is a subclass of JApplet:

import java.awt.*;
import java.awt.event.*;
import javax.swing.*;

public class GraphicsDemo extends JApplet {

First of all, we define trajectory:

private double[] trajectory = null;

Next, for simplification of future changes, we define all of our text labels.

private static String generate = "Generate";

Our applet has three panels. The first one is mainPanel:

private JPanel mainPanel = null;

mainPanel has two subpanels. The first one is called commandPanel. It is the instance of the standard class JPanel:

private JPanel commandPanel = null;

The second subpanel is called graphicsPanel. It is the instance of our custom class GraphicsPanel:

private GraphicsPanel graphicsPanel = null;

Finally, we define all of our buttons.

private JButton generateButton = null;

That's all variables of our class.

All elements of the applet's graphical user interface must appear, when the applet initialises itself, i.e., in the init method:

public void init() {

In Swing, every top-level container has a content pane that contains, directly or indirectly, all the visible components (except for menus and window decorations) in the top-level container. To obtain the reference to the applet's content pane, we use the getContentPane method:

Container contentPane = getContentPane();

Now, we create mainPanel,

mainPanel = new JPanel();

set its layout as vertical box layout,

mainPanel.setLayout(
         new BoxLayout(mainPanel,BoxLayout.PAGE_AXIS));
add empty border,

mainPanel.setBorder(
        BorderFactory.createEmptyBorder(5,5,5,5));

and add mainPanel to the applet's content pane:

contentPane.add(mainPanel);

Next, we create commandPanel,

commandPanel = new JPanel();

and add black line border
commandPanel.setBorder(
            BorderFactory.createLineBorder(Color.black));

Now, we create a button,

generateButton = new JButton(generate);

and add it to commandPanel:

commandPanel.add(generateButton);

We want to handle the button-click event, so we add an event listener to the button.

generateButton.addActionListener(new ActionListener() {
    public void actionPerformed(ActionEvent event) {

Inside the listener, we first create trajectory, if it was not created before:

if (trajectory == null) {
    trajectory = new double[10];
}

Next, we fill trajectory by some values, just to show something:

for (int i=0; i<10; i++) {
    trajectory[i] = Math.sin(i);
}

Finally, we pass the reference to trajectory into graphicsPanel,

graphicsPanel.setTrajectory(trajectory);

and invoke our custom painting:

        graphicsPanel.repaint();
    }
});

Method repaint automatically calls our custom paintComponent, and the graph is painting.

Now we add commandPanel to mainPanel;

mainPanel.add(commandPanel);

and add the additional 5 pixels between our subpanels:

mainPanel.add(Box.createRigidArea(new Dimension(0,5)));

Finally, we create graphicsPanel,

graphicsPanel = new GraphicsPanel();

add the raised bevel border,

graphicsPanel.setBorder(
        BorderFactory.createRaisedBevelBorder());

and add graphicsPanel to mainPanel:

        mainPanel.add(graphicsPanel);
    }
}

That's all, folks!

Conclusions

You can use the GraphicsDemo applet as a pattern for your project. Moreover, you can do the following.

  • Try different layout managers for your content pane and control panel.
  • Realise various elements of Swing's graphical user interface inside your control panel.
  • Try to use HTML in your text labels.
  • Customise your graphical output, using different capabilities of both Graphics and Graphics2D classes.

Good luck!

References

[1] 2D Graphics, click here
[2] Class Graphics, click here
[3] The Swing tutorial, click here


14572 bytes more | comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by jalex on Monday, October 30, 2006 (21:05:00) (7017 reads)

Java String Overview (really good one)!

Go to all tips in

Java String Overview (really good one)!

In this article you will find the complete overview of the String related Java Lessons, Java Lectures, tips, How-Tos, code examples, book chapters and so on - all what was published on our site latest few years.



In most modern programming languages strings are stored in arrays of characters. But in the Java the String is a part of Java API and it is a Java Class: java.lang.String. Why the String class is made final and immutable read in one of our tips below.

In most modern programming languages strings are are stored in arrays of characters. But in the Java the String is a part of Java API and it is a Java Class: java.lang.String. Why the String class is made final and immutable read in one of our tips below.

About Java String for beginners you can read here:

The links above are gold pages for you and contains a lot of info you never thought and heard about Smile

As it was mentioned in Java Lecture 10:

The Java platform contains three classes that you can use when working with character data:

  • Character -- A class whose instances can hold a single character value. This class also defines handy methods that can manipulate or inspect single-character data.
  • String -- A class for working with immutable (unchanging) data composed of multiple characters.
  • StringBuffer -- A class for storing and manipulating mutable data composed of multiple characters.

In this lecture you can find answers to the next topics:

Creating strings and string buffers

Why two string classes?

Getting the length of a string or a string buffer

Converting strings to numbers

String to int, long, float and double conversion working java code example see below:

Code:

String myString = "123";
        String myHexadecimalString = "F5";
        int myInt = 0;
        int myHexadecimal = 0;
        long myLong = 0;
        float myFloat = 0;
        double myDouble = 0;
        try {
            System.out.println("start to parse myString " + myString);
            myInt = Integer.parseInt(myString);
            myLong = Long.parseLong(myString);
            myFloat = Float.parseFloat(myString);
            myDouble = Double.parseDouble(myString);
            myHexadecimal = Integer.parseInt(myHexadecimalString, 16);
            System.out.println("parsing myString " + myString + "to int, long, float, double passed well!");
        }
        catch (NumberFormatException e) {
            System.out.println("We have problem with String parsing!");
        }

When you convert an int, long, float or double to string it is better to use static methods from wrapping class:

Code:

Integer.toString(int)
Long.toString(long)
Double.toString(double)
Float.toString(float)

You could also do like this for an int:

Code:
String.valueOf(int)

but this example will create one String object more which must be garbage collected right away after the operation. If it is just one assignment it does not do much sense but in case of many you will find big difference Smile

The String class itself does not provide any methods for converting a String to a floating point, integer, or other numerical type. However, four of the "type wrapper" classes (Integer, Double, Float, and Long) provide a class method named valueOf.... (see more in the Characters and Strings in Java. Java Lecture 10)

The Java platform provides two classes, String and StringBuffer, that store and manipulate strings -- character data consisting of more than one character. The String class provides for strings whose value will not change. For example, if you write a method that requires string data and the method is not going to modify the string in any way, pass a String object into the method. The StringBuffer class provides for strings that will be modified; you use string buffers when you know that the value of the character data will change. You typically use string buffers for constructing character data dynamically: for example, when reading text data from a file. Because strings are constants, they are more efficient to use than are string buffers and can be shared. So it's important to use strings when you can.

Why String in Java is made immutable?

String Handling in Java

How can I find out the same word in a text if it has different case (upper or lower ) in different places?

How do I split comma or white separated string?

Question: I want to get the java.lang.String to read a stream of Chinese characters. But I am getting only rubbish characters. How can I make my program language independent?

Java String Code Example: Demonstrate behavior of java.lang.CharSequence as implemented by String, StringBuffer and CharBuffer.

The Java Lesson 17: The String class

The Java Lesson 18: The StringBuffer class

Strings to Numbers

Number to String Conversion

Question: How do I split comma or white separated string?

Comma separated into string array

java.util.StringTokenizer

String Regex Methods

I want to to have a listener for a String's change event. Is it possible?

I want to get the java.lang.String to read a stream of Chinese characters. But I ..

I placed the current date and time into String data type. But my table column is..

 

Related classes and types

char Primitive type for 16-bit Unicode characters.
String The basic class for strings. String objects can NOT be changed.
Character Primarily useful for its utility functions for working with characters.
StringBuffer StringBuffers are used to build or change strings. Conversion between String and StringBuffer is easy.
StringTokenizer Used to break a String into tokens (words).
BufferedReader
BufferedWriter
Useful for reading and writing text files.
Pattern, Matcher JDK 1.4 added java.util.Pattern and Matcher to do regular expression matching.

8982 bytes more | comments? | Printer Friendly Page  Send to a Friend | Score: 0
Posted by jalex on Monday, October 30, 2006 (20:16:13) (11718 reads)

Previous 1060 Stories (530 Pages, 2 Per Page) Next

530| 529| 528| 527| 526| 525| 524| 523| 522| 521| 520| 519| 518| 517| 516| 515| 514| 513| 512| 511| 510| 509| 508| 507| 506| 505| 504| 503| 502| 501| 500| 499| 498| 497| 496| 495| 494| 493| 492| 491| 490| 489| 488| 487| 486| 485| 484|
483
| 482| 481| 480| 479| 478| 477| 476| 475| 474| 473| 472| 471| 470| 469| 468| 467| 466| 465| 464| 463| 462| 461| 460| 459| 458| 457| 456| 455| 454| 453| 452| 451| 450| 449| 448| 447| 446| 445| 444| 443| 442| 441| 440| 439| 438| 437| 436| 435| 434| 433| 432| 431| 430| 429| 428| 427| 426| 425| 424| 423| 422| 421| 420| 419| 418| 417| 416| 415| 414| 413| 412| 411| 410| 409| 408| 407| 406| 405| 404| 403| 402| 401| 400| 399| 398| 397| 396| 395| 394| 393| 392| 391| 390| 389| 388| 387| 386| 385| 384| 383| 382| 381| 380| 379| 378| 377| 376| 375| 374| 373| 372| 371| 370| 369| 368| 367| 366| 365| 364| 363| 362| 361| 360| 359| 358| 357| 356| 355| 354| 353| 352| 351| 350| 349| 348| 347| 346| 345| 344| 343| 342| 341| 340| 339| 338| 337| 336| 335| 334| 333| 332| 331| 330| 329| 328| 327| 326| 325| 324| 323| 322| 321| 320| 319| 318| 317| 316| 315| 314| 313| 312| 311| 310| 309| 308| 307| 306| 305| 304| 303| 302| 301| 300| 299| 298| 297| 296| 295| 294| 293| 292| 291| 290| 289| 288| 287| 286| 285| 284| 283| 282| 281| 280| 279| 278| 277| 276| 275| 274| 273| 272| 271| 270| 269| 268| 267| 266| 265| 264| 263| 262| 261| 260| 259| 258| 257| 256| 255| 254| 253| 252| 251| 250| 249| 248| 247| 246| 245| 244| 243| 242| 241| 240| 239| 238| 237| 236| 235| 234| 233| 232| 231| 230| 229| 228| 227| 226| 225| 224| 223| 222| 221| 220| 219| 218| 217| 216| 215| 214| 213| 212| 211| 210| 209| 208| 207| 206| 205| 204| 203| 202| 201| 200| 199| 198| 197| 196| 195| 194| 193| 192| 191| 190| 189| 188| 187| 186| 185| 184| 183| 182| 181| 180| 179| 178| 177| 176| 175| 174| 173| 172| 171| 170| 169| 168| 167| 166| 165| 164| 163| 162| 161| 160| 159| 158| 157| 156| 155| 154| 153| 152| 151| 150| 149| 148| 147| 146| 145| 144| 143| 142| 141| 140| 139| 138| 137| 136| 135| 134| 133| 132| 131| 130| 129| 128| 127| 126| 125| 124| 123| 122| 121| 120| 119| 118| 117| 116| 115| 114| 113| 112| 111| 110| 109| 108| 107| 106| 105| 104| 103| 102| 101| 100| 99| 98| 97| 96| 95| 94| 93| 92| 91| 90| 89| 88| 87| 86| 85| 84| 83| 82| 81| 80| 79| 78| 77| 76| 75| 74| 73| 72| 71| 70| 69| 68| 67| 66| 65| 64| 63| 62| 61| 60| 59| 58| 57| 56| 55| 54| 53| 52| 51| 50| 49| 48| 47| 46| 45| 44| 43| 42| 41| 40| 39| 38| 37| 36| 35| 34| 33| 32| 31| 30| 29| 28| 27| 26| 25| 24| 23| 22| 21| 20| 19| 18| 17| 16| 15| 14| 13| 12| 11| 10| 9| 8| 7| 6| 5| 4| 3| 2| 1|


Home Code Examples Java Forum All Java Tips Books Submit News, Code... Search... Offshore Software Tech Doodling

RSS feed Java FAQ RSS feed Java FAQ News     

    RSS feed Java Forums RSS feed Java Forums

All logos and trademarks in this site are property of their respective owner. The comments are property of their posters, all the rest 1999-2006 by Java FAQs Daily Tips.

Interactive software released under GNU GPL, Code Credits, Privacy Policy