« February 2007 »
S M T W T F S
1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28
You are not logged in. Log in

Programming Tips
Saturday, 24 February 2007
Displaying
Mood:  chillin'
Topic: VC++

There is an exported function in ntlanman.dll that does this. The name of the function is ServerBrowseDialogA0. 

HMODULE hModule = LoadLibrary( _T( "ntlanman.dll" ));

typedef DWORD ( WINAPI *FNNTBrowseDlg )( HWND hwnd, 
                                                                         CHAR *pchBuffer,
                                                                         DWORD cchBufSize );
FNNTBrowseDlg lpfn = 0;
CHAR szT[UNCLEN + 1] = { 0 };
lpfn = ( FNNTBrowseDlg )GetProcAddress( hModule, "ServerBrowseDialogA0" );
lpfn( m_hWnd, szT, UNCLEN );

FreeLibrary( hModule );


Posted by Nibu babu thomas at 1:35 PM
Updated: Saturday, 24 February 2007 1:42 PM
Thursday, 22 February 2007
How to Create a GUID programmatically
Mood:  cool
Topic: VC++

Do the following... 

GUID guId = { 0 };
CoCreateGuid( &guId );

or
    
UUID uid = { 0 };
UuidCreate( &uid );

To convert to string use...

PUCHAR pChar = 0;
// Convert to string

UuidToString( &uid, &pChar );
MessageBox( NULL, (char*)pChar, NULL, MB_OK );

//Don't forget to free allocated string
RpcStringFree( &pChar );


Posted by Nibu babu thomas at 3:18 PM
Tuesday, 13 February 2007
getch and getche in Windows console apps!!
Mood:  mischievious
Topic: VC++

Ever wondered how to implement getch and getche in Windows console application...

Here is how we do this...

int getch()
{
    HANDLE hStdIn = GetStdHandle(STD_INPUT_HANDLE);
    if( hStdIn == INVALID_HANDLE_VALUE )
    {
        return 0;
    }// End if

    DWORD dwInputMode = 0;
    GetConsoleMode( hStdIn, &dwInputMode );

    // Code that disables line input and echoing of entered character
    SetConsoleMode( hStdIn, dwInputMode & ~ENABLE_LINE_INPUT &
                                          ~ENABLE_ECHO_INPUT );

    char cBuff = 0;
    DWORD dwBytesRead = 0;
    if( !ReadFile( hStdIn, &cBuff, sizeof( cBuff ), &dwBytesRead, 0 ))
    {
        return 0;
    }

    // Return to previous settings
    SetConsoleMode( hStdIn, dwInputMode );

    return cBuff;
}// End getch

int getche()
{
    HANDLE hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
    if( hStdOut != INVALID_HANDLE_VALUE )
    {
        char cGetCh = getch();
        DWORD dwBytesWritten = 0;
        WriteFile( hStdOut, &cGetCh, sizeof( cGetCh ), &dwBytesWritten, NULL );
       
        return cGetCh;
    }// End if
   
    return 0;
}// End getche


Posted by Nibu babu thomas at 1:38 PM
Updated: Tuesday, 13 February 2007 2:10 PM
Useful windows tips
Mood:  loud
Topic: Windows

Shift + Click -- on any hyperlink to open it in a new window.

Ctrl + + -- Resize any list control to it's contents.
 
* -- Expand any tree node and all it's sub nodes in windows.
+ -- Expand any tree node
- -- Collapse any tree node

Shift + Click -- on any folder inside explorer to open it in a new window with explorer bar at it's side showing the path leading to that folder.

Shift + Enter - Does the same as above

Ctrl + Enter will open any folder in a new window

Ctrl + Double Click will open any folder in a new window

Ctrl + Double click on any explorer title bar including internal explorer to see that window in full screen mode.

Alt + Drag to select in columns.

Ctrl + Shift + F8 to do the above using keyboard.

WinKey + L to lock the desktop

Alt + Enter on any file to view it's property pages.

Alt + Double Click on any folder to open it's property pages.

Alt + Spacebar to open System menu of any window

Alt + - to open system menu of main child windows, for eg: Word document windows

 

Shift + Close button ( On caption bar ) to close all parent windows of a child explorer window at once.

Winkey + D -- Show desktop
Winkey + M -- Minimize all
Winkey + Shift + M -- Undo Minimize All
WinKey + R -- Opens run dialog
Winkey + E -- Opens explorer.
Winkey + U -- Opens Utility manager.
Winkey -- Opens start menu


Posted by Nibu babu thomas at 1:24 PM
Updated: Monday, 26 February 2007 5:11 PM
Monday, 12 February 2007
Auto expanding #define's and #include's
Mood:  a-ok
Topic: VC++

Did you ever feel the need for having all the macros defined in a file to get expanded automatically...

Now you may wonder why do we need such a thing, one reason could be to learn the intricacies of these macros.

For eg: BEGIN_MESSAGE_MAP, DECLARE_DYNAMIC, IMPLEMENT_DYNAMIC...

Now the question is how to do this... Here is nice little compiler option...

/P - PreProcess to File
/EP - Preprocess to stdout, no #line
/E - Preprocess to stdout

Now here is how we do this...

cl /P CMyDlg.cpp

This command will create a CMyDlg.i file which contains the entire source contents of CMyDlg.cpp along with all include files expanded with it's contents and all macros expanded to actual code.

But before all this just look at the size of CMyDlg.i. It could be in MB's. :)) But our source file's size was in KB's right? ;)

Well this shows the real thing that's going on.

I would like to give you a task, go through all the compiler options and find out what they do. Maybe take a printout of these options and hang it somewhere near to you, so that you can have a quick look at all compiler options, and understand what they do.

Hope this helps you and me to learn.


Posted by Nibu babu thomas at 2:53 PM
Updated: Monday, 26 February 2007 5:12 PM
Tuesday, 6 February 2007
Extracting bytes in a floating point variable
Mood:  crushed out
Topic: VC++

The easiest way to get the bytes in a floating point variable...

BYTE byFloatBytes[sizeof( float )] = { 0 };
float fFloatNumber = 0.191911f;
memcpy( &byFloatBytes, &fFloatNumber, sizeof( byFloatBytes ));

or

BYTE byDoubleBytes[sizeof( double )] = { 0 };
double dDoubleNumber = 0.191911;
memcpy( &byDoubleBytes, &dDoubleNumber, sizeof( byDoubleBytes ));

or

float fFloatVar = 21343.34f;
LPBYTE lpFloatBytes = reinterpret_cast< LPBYTE >( &fFloatVar );

// Now lpFloatBytes can be accessed as an array likewise
lpFloatBytes[0]
lpFloatBytes[1]
lpFloatBytes[2]
lpFloatBytes[3]

or

// Use a union
union
{
      double dDoubleVar;
      BYTE byBytes[sizeof( double )];
}AUnion;

AUnion.dDoubleVar = 234234.233123;

// Now AUnion byBytes should be holding the double value in bytes
AUnion.byBytes[0], AUnion.byBytes[1], AUnion.byBytes[2],AUnion.byBytes[3]...

etc.

Be sure that you don't step out of the size of the floating point variable which could lead to disaster. The first two methods are safe, the second last one should be only used if you are absolutely confident as to what you are doing.


Posted by Nibu babu thomas at 5:14 PM
Updated: Monday, 26 February 2007 5:32 PM
Stringizer ( #) and Token pasting (## ) operator.
Mood:  hug me
Topic: VC++
The Stringizer operator... # and Token pasting operator ##

A powerful preprocessor operator which you can use for surrounding your strings with quotes... and to combine your string tokens during compile time

I always use these operators for returning error constants as string...

For eg: If I have an error constant like ERROR_INVALID_EXP_DATE.

What should I do to return it as a string... Normally we will declare an LPCTSTR constant as follows...

static const LPCTSTR lpctszErrInvalidExpDate = _T( "ERROR_INVALID_EXP_DATE" );

Which becomes a hard chore if the error code to be returned is one two many, now the question how can we automate this...

A small macro can do the trick for us.

#define SWITCH_CASE_STRING( constVar )\
case constVar:\
{\
     static LPCTSTR constVar##ReturnValue = _T(
#
constVar );\
     return constVar
##
ReturnValue;\
}

LPCTSTR GetErrorString( const DWORD dwErrorCode_i )
{
     SWITCH_CASE_STRING( SUCCESS )
     
SWITCH_CASE_STRING( ERROR_INVALID_EXP_DATE )
..etc
}// End GetErrorString

During compile time SWITCH_CASE_STRING expands to the following statements

case SUCCESS:
{
    
static LPCTSTR SUCCESSReturnValue = _T( "SUCCESS" );
     return SUCCESSReturnValue;
}

That's it. Now you don't have to write up a case statement every time a new error is introduced...

Since the variables are static they won't be created unless the particular error occurs. And they won't be created every time since the variables are static.

Hope this helps you.


Posted by Nibu babu thomas at 5:09 PM
Updated: Monday, 26 February 2007 5:25 PM
Auto completion
Mood:  chillin'
Topic: VC++

Goto Start->Run

Type C:\.....

You will get a dropdown list box with all the files and folders in C: drive.

Have you ever thought about incorporating this kind of a behavior into your application...

There is an API which does this... ( Microsoft was generous enough to create one and share it ). :)

The API is SHAutoComplete.

All you should have is an edit box. Get the handle to the edit box and pass it to this function. You will get a drop down

list box for the path that you are typing in the edit box.

Cool isn't it. :)

NOTE: Don't forget to call CoInitialize before using this function and of course CoUninitialize

Do look up this API in MSDN. You will find interesting options.

Have fun.


Posted by Nibu babu thomas at 4:45 PM
Updated: Monday, 26 February 2007 5:17 PM
Monday, 27 November 2006
How to retrieve language name and country name from a Language ID
Mood:  happy
Topic: VC++

Ever wondered how to get language name and country name from a given language id like 1033.

Well this is how we do  it...

TCHAR szBuffer[MAX_PATH] = { 0 };

// Get language name, for eg: English  
GetLocaleInfo( MAKELCID( 1033, SORT_DEFAULT ), LOCALE_SENGLANGUAGE, szBuffer, MAX_PATH );
MessageBox( szBuffer );

// Get country name, for eg: United states.
GetLocaleInfo( MAKELCID( 1033, SORT_DEFAULT ), LOCALE_SENGCOUNTRY, szBuffer, MAX_PATH );
MessageBox( szBuffer );

JESUS Rulz :))


Posted by Nibu babu thomas at 4:01 PM
Updated: Monday, 27 November 2006 6:25 PM
Tuesday, 31 October 2006
How to get the string that is used to register a message using RegisterWindowMessage
Mood:  party time!
Topic: VC++

It's quite common that we use RegisterWindowMessage to register a message that is used for all instances of this application.

Have you ever wondered how to get the text back from from the message number that is returned by RegisterWindowMessage?

This will make it more clear...

const UINT uMyWndMessageReg = ::RegisterWindowMessage( _T( "Nibu is testing" ));

Now how to get back "Nibu is testing" from uMyWndMessageReg?

Well this is how we do it...

TCHAR szMsgBuf[ MAX_PATH ];
GetClipboardFormatName( uMyWndMessageReg, szMsgBuf, MAX_PATH );

MessageBox( NULL, szMsgBuf, _T( "RegisterWindowMessage String" ), MB_OK | MB_ICONINFORMATION );

Ah wait I have a question for you, can you tell me what's going behind the scenes of RegisterWindowMessage. ;)


Posted by Nibu babu thomas at 2:00 PM
Updated: Monday, 27 November 2006 6:32 PM
Saturday, 20 May 2006
How to convert a ANSI string to UNICODE string and vice versa?
Mood:  don't ask
Well quite simple,  but still quite frequently asked in forums... :)

There are two macros that does this for us. They are as follows.

Note: You must include atlconv.h

A2W - ANSI to UNICODE
W2A - UNICODE to ANSI

Before using these two macros you have to use this macro too...

USES_CONVERSION

Here is a code snippet for you... ;)

//#include <atlconv.h>
//An example for converting from ANSI to UNICODE

//use this first
USES_CONVERSION;

//An ANSI string
LPSTR lpsz_ANSI_String = "An ANSI String";

//ANSI string being converted to a UNICODE string
LPWSTR lpUnicodeStr = A2W( lpsz_ANSI_String )


//Another example for converting from UNICODE to ANSI

//Use this first
USES_CONVERSION

//A UNICODE string
LPWSTR lp_UNICODE_STR = L"A Unicode String";

//UNICODE string being converted to a ANSI string
LPSTR  lpsz_ANSI_STR = W2A( lp_UNICODE_STR );

So that's it we are done with it.

Ah wait don't leave here's a homework for you...

Rip apart CW2A and CA2W  :))

Posted by Nibu babu thomas at 3:49 PM
Updated: Saturday, 20 May 2006 3:53 PM
How to prevent MDI applications from showing a template dialog at startup?
Mood:  a-ok
Topic: VC++

Many times we don't want the MDI template dialog to be shown during startup of an MDI application.

Well the million dollar question is how can we prevent it from popping up. Well this is how we do it... :)

Goto your applicationname.cpp file and edit the InitInstance method at the specified place as shown here...

// Parse command line for standard shell commands, DDE, file open
CCommandLineInfo cmdInfo;
ParseCommandLine(cmdInfo); 
 
//this is the line that you should add
cmdInfo.m_nShellCommand = CCommandLineInfo::FileNothing; 

// Dispatch commands specified on the command line
if (!ProcessShellCommand(cmdInfo))
    return FALSE;

There is a member variable in the class CCommandLineInfo which is called m_nShellCommand.

This is the variable that tells the command line parser to start a new file at startup. 
This variable is by default set to FileNew. We have to assign a new value to this variable i.e. FileNothing. 
Well this means empty file so MDI will be blank initially and the template dialog doesn't pop up. 

We have to click on New file to see the template dialog again and then choose any 
template from a set of multiple templates that we have created.

Posted by Nibu babu thomas at 3:03 PM
Updated: Saturday, 20 May 2006 3:27 PM
Eh! An Unmovable Dialog!
Mood:  sharp
Topic: VC++
Just try this...

CMenu* pSysMenu = GetSystemMenu(FALSE);
pSysMenu->RemoveMenu(SC_MOVE, MF_BYCOMMAND);

Lol lol now it's not moving. 


Ah no!!! Now tell me how can I make it movable again?

Lol the funniest question of the century...ROTFL.

Posted by Nibu babu thomas at 3:00 PM
Updated: Saturday, 6 May 2006 12:29 PM
Wednesday, 5 April 2006
Increase statusbar height and width!
Mood:  silly
Topic: VC++
This is real simple:

m_YourStatusBar.SetBorders(
 1 //cxleft
,5 //cytop
,1 //cxright 
,5 //cybottom
);

:)

Posted by Nibu babu thomas at 1:17 PM
How to disable close button in the caption bar?
Mood:  cheeky
Topic: VC++
This is how we do it:

CMenu *pMenu = GetSystemMenu(FALSE);
pMenu->RemoveMenu(SC_CLOSE, MF_BYCOMMAND);

Yeap done!

Posted by Nibu babu thomas at 12:26 PM
Updated: Wednesday, 5 April 2006 3:05 PM
Tuesday, 20 December 2005
To retrieve the machine name
Mood:  hungry
Topic: VC++
It is easy to get the name of a machine. Make sure your application supports "winsock"


      WSADATA WSAData;
      ::ZeroMemory(&WSAData, sizeof(WSAData));
      //init winsock
      ::WSAStartup(MAKEWORD(1,0), &WSAData);

Now get the host name:

      char szHostName[MAX_PATH];
      ::gethostname(szHostName, MAX_PATH);

szHostName has got the host name

Now close winsock.

      //close winsock
      ::WSACleanup();

Posted by Nibu babu thomas at 1:33 PM
Updated: Tuesday, 20 December 2005 1:38 PM
Monday, 21 November 2005
Always on top dialogs and windows
Mood:  surprised
Topic: VC++
Ever wondered how to create an always on top dialog!

Here, take a look. :)

::SetWindowPos(m_hWnd /*Handle to the window*/, 
		HWND_TOPMOST /*Places the window at the top of the Z-Order*/, 
		0 /*New x*/, 
		0 /*New y*/, 
		0 /*New Width*/, 
		0 /*New Height*/, 
		SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE/*Flags*/
		);

Now you might be wondering how to remove this feature. Just replace HWND_TOPMOST with HWND_NOTOPMOST

Happy days ahead.

Posted by Nibu babu thomas at 2:08 PM
Updated: Monday, 21 November 2005 2:12 PM
Friday, 18 November 2005
A round dialog box!
Mood:  on fire
Topic: VC++
Ever wondered how those cute little round dialog boxes are created. I too wondered for some time.

But let me tell you it is easy.
So you don't trust me eh. Take a look:

//Create a region object globally.
CRgn m_EllipticRegion;

//a rect object
CRect crDialogRect;

//get your dialog size
this->GetClientRect(crDialogRect);

//Now create the elliptic region from the client rect
m_EllipticRegion.CreateEllipticRgn(0/*x*/,
                  0/*y*/,
                  crDialogRect.Width()/*width*/,
                  crDialogRect.Height() /*Height*/
                  );

//create a round dialog
this->SetWindowRgn(m_EllipticRegion, TRUE);

See I told you it's easy :)

Posted by Nibu babu thomas at 5:30 PM
To move a captionless dialog.
Mood:  mischievious
Topic: VC++
Have you ever wondered how do people move dialogs by simply clicking anywhere inside the dialog and dragging them. 
Have you ever wondered how captionless dialogs can be dragged arround.

If it is so then let me tell you that you can do the same with just one line of code.

Here goes the code:

void CNCHitTestProDlg::OnLButtonDown(UINT nFlags, CPoint point)
{
        //here is the code
        SendMessage(WM_NCLBUTTONDOWN, HTCAPTION, MAKELPARAM(point.x, point.y));
        CDialog::OnLButtonDown(nFlags, point);
}

Posted by Nibu babu thomas at 5:04 PM
Updated: Friday, 18 November 2005 5:07 PM
Tuesday, 15 November 2005
Drawing Boxes Around Characters and Strings
Mood:  chatty
Topic: Java
There are at least two ways to answer this question, and we'll look at both. 
The Font class offers a getStringBounds() method that returns the bounding rectangle of a String.
The Graphics class offers a getFontMetrics() method that allows you to get the string width and character dimensions
for a finer level of detail. 
Of course, there is also the option of just setting the border of a JLabel to draw the box for you. We'll look at all these here. 

All three programs take a string from the command line to draw with a bounded box. If no string is provided, the word "Money" 
is drawn, a word that offers a combination of uppercase and lowercase letters as well as a descender (the character "y," 
which extends below the baseline). 

1.     Using Font.getStringBounds()

The first way to draw a bounding box is sufficient for most cases in which you are explicitly drawing the characters. Given the 
graphics context passed into your paintComponent() method, get its font rendering context, which contains internal details 
about the font, and then ask that what the bounding rectangle is for your message. Then, draw the rectangle. 

      String message = ...;
      Graphics2D g2d = (Graphics2D)g;
      FontRenderContext frc = g2d.getFontRenderContext();
      Shape shape = theFont.getStringBounds(message, frc);
      g2d.draw(shape);

Just be sure to coordinate the location of the drawn string with the rectangle, as demonstrated by the following program: 

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

public class Bounds {

  static class BoxedLabel extends JComponent {
    Font theFont = new Font("Serif", Font.PLAIN, 100);
    String message;

    BoxedLabel(String message) {
      this.message = message;
    }

    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Insets insets = getInsets();
      g.translate(insets.left, insets.top);
      int baseline = 150;

      g.setFont(theFont);
      FontMetrics fm = g.getFontMetrics();

      // Center line
      int width = getWidth() - insets.right;
      int stringWidth = fm.stringWidth(message);
      int x = (width - stringWidth)/2;

      g.drawString(message, x, baseline);

      Graphics2D g2d = (Graphics2D)g;
      FontRenderContext frc = g2d.getFontRenderContext();
      Shape shape = theFont.getStringBounds(message, frc);
      g.translate(x, baseline);
      g2d.draw(shape);
      g.translate(-x, -baseline);
      g.translate(-insets.left, -insets.top);
    }
  }

  public static void main(String args[]) {
    final String message;
    if (args.length == 0) {
      message = "Money";
    } else {
      message = args[0];
    }
    Runnable runner = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("Bounds");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JComponent comp = new BoxedLabel(message);
        frame.add(comp, BorderLayout.CENTER);
        frame.setSize(400, 250);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);
  }
}

2.    Using Graphics.getFontMetrics()

The second mechanism demonstrates a finer level of detail that may or may not be necessary. What if you want to draw a box 
around each character of a string? With a proportional font, each character is a different width, so you can't just calculate font 
size multiplied by number of characters to get the width of the whole string. Instead, you work with the FontMetrics class to get 
the metrics of each character involved. 

      g.setFont(theFont);
      FontMetrics fm = g.getFontMetrics();

Some information you get is specific to the font, and not at the character level. When you draw a string, you specify the 
baseline -- the line where the bottom of the character is to be drawn. The space above the line for the tallest character, 
including diacritical marks like umlauts, is called the ascent. Below the line for descenders (such as the letter "y") is called 
descent. Space reserved for between lines of characters is called leading, pronounced like the metal, 
not like taking charge of a group. The height is the sum of these three. 

      int ascent  = fm.getAscent();
      int descent = fm.getDescent();
      int leading = fm.getLeading();
      int height  = fm.getHeight();

There are also values for the maximum of the three sizes, though this may be the same as the non-max value. 

      int maxAdv  = fm.getMaxAdvance();
      int maxAsc  = fm.getMaxAscent();
      int maxDes  = fm.getMaxDescent();

As far as width goes, you can ask for the width of the whole string: 

      int stringWidth = fm.stringWidth(message);

So, in the case of the bounding box of a string, you'd take its width and height to create the rectangle. 

      int stringWidth = fm.stringWidth(message);
      int height  = fm.getHeight();

To work at the character level, the FontMetrics class has a charWidth() method. 
By looping through your string, you can increase the x coordinate of your box drawing to draw the next box. 
charX += fm.charWidth(message.charAt(i));

The following program demonstrates the use of both sets of methods to box off the whole string and each character. 

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

public class Metrics {

  static class BoxedLabel extends JComponent {
    Font theFont = new Font("Serif", Font.PLAIN, 100);
    String message;

    BoxedLabel(String message) {
      this.message = message;
    }

    public void paintComponent(Graphics g) {
      super.paintComponent(g);
      Insets insets = getInsets();
      g.translate(insets.left, insets.top);
      int baseline = 150;

      g.setFont(theFont);
      FontMetrics fm = g.getFontMetrics();

      int ascent  = fm.getAscent();
      int descent = fm.getDescent();
      int height  = fm.getHeight();
      int leading = fm.getLeading();
      int maxAdv  = fm.getMaxAdvance();
      int maxAsc  = fm.getMaxAscent();
      int maxDes  = fm.getMaxDescent();

      // Center line
      int width = getWidth() - insets.right;
      int stringWidth = fm.stringWidth(message);
      int x = (width - stringWidth)/2;

      g.drawString(message, x, baseline);

      drawHLine(g, x, stringWidth, baseline);
      drawHLine(g, x, stringWidth, baseline-ascent);
      drawHLine(g, x, stringWidth, baseline-maxAsc);
      drawHLine(g, x, stringWidth, baseline+descent);
      drawHLine(g, x, stringWidth, baseline+maxDes);
      drawHLine(g, x, stringWidth, baseline+maxDes+leading);

      int charX = x;
      for (int i=0; i <= message.length(); i++) {
        drawVLine(g, charX, baseline-ascent, baseline+maxDes+leading);
        if (i != message.length()) {
          charX += fm.charWidth(message.charAt(i));
        }
      }
    }

    void drawHLine(Graphics g, int x, int width, int y) {
      g.drawLine(x, y, x+width, y);
    }

    void drawVLine(Graphics g, int x, int y, int height) {
      g.drawLine(x, y, x, height);
    }
  }

  public static void main(String args[]) {
    final String message;
    if (args.length == 0) {
      message = "Money";
    } else {
      message = args[0];
    }
    Runnable runner = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("Metrics");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JComponent comp = new BoxedLabel(message);
        frame.add(comp, BorderLayout.CENTER);
        frame.setSize(400, 250);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);
  }
}

One thing to mention about this program is that had the font been italic, the character might not have been bound to within 
the drawn box. If you need absolute control over the bounds of a string, consider looking at the TextLayout class, which 
allows you to get the outline shape of a string for further manipulation. 

3.    Setting Border of JLabel 

The JLabel class has a setBorder() method. This allows you to directly "add" the bounding box without having to subclass to 
draw it yourself. The system classes will calculate the appropriate location for you, as the following example shows. 

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

public class Bordered {

  public static void main(String args[]) {
    final String message;
    if (args.length == 0) {
      message = "Money";
    } else {
      message = args[0];
    }
    Runnable runner = new Runnable() {
      public void run() {
        JFrame frame = new JFrame("Border");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JComponent comp = new JLabel(message, JLabel.CENTER);
        comp.setFont(new Font("Serif", Font.PLAIN, 100));
        comp.setBorder(LineBorder.createBlackLineBorder());
        frame.getContentPane().setLayout(new GridBagLayout());
        frame.add(comp);
        frame.setSize(400, 250);
        frame.setVisible(true);
      }
    };
    EventQueue.invokeLater(runner);
  }
}
Happy days ahead...:)

Posted by Nibu babu thomas at 12:37 PM
Updated: Tuesday, 15 November 2005 12:51 PM

Newer | Latest | Older