Sunday Apr 13, 2008

TIP: Making JOptionPane dialog resizable

It is a well known issue that the dialogs shown by the javax.swing.JOptionPane are not resizable. In the last blog entry there was a tip in the code about just how to make the dialogs shown by javax.swing.JOptionPane resizable. Here is the relevant snippet of code:

        // TIP: Make the JOptionPane resizable using the HierarchyListener
editorPane.addHierarchyListener(new HierarchyListener() {
public void hierarchyChanged(HierarchyEvent e) {
Window window = SwingUtilities.getWindowAncestor(editorPane);
if (window instanceof Dialog) {
Dialog dialog = (Dialog)window;
if (!dialog.isResizable()) {
dialog.setResizable(true);
}
}
}
});

The tip works if you are using any java.awt.Component subclass as the message in javax.swing.JOptionPane. The tip works by listening to the hierarchy event on the message component, finding the java.awt.Dialog component and setting it's resizable property to true.

Tuesday Aug 07, 2007

BorderLayout implemented in terms of GroupLayout

Just for fun. Here is a java.awt.BorderLayout implemented in terms of javax.swing.GroupLayout:

import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class BorderLayoutGroupLayout {
    public static void main(String[] args) {
        JButton west = new JButton("West");
        JButton north = new JButton("North");
        JButton east = new JButton("East");
        JButton south = new JButton("South");
        JButton center = new JButton("Center");
       
        JPanel panel = new JPanel();
        GroupLayout groupLayout = new GroupLayout(panel);
        panel.setLayout(groupLayout);
       
        groupLayout.setHorizontalGroup(
            groupLayout.createParallelGroup(GroupLayout.Alignment.LEADING)
                .addComponent(north, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addGroup(groupLayout.createSequentialGroup()
                    .addComponent(west)
                    .addComponent(center, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(east))
                .addComponent(south, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
        );
        groupLayout.setVerticalGroup(
            groupLayout.createSequentialGroup()
                .addComponent(north)
                .addGroup(groupLayout.createParallelGroup(GroupLayout.Alignment.CENTER)
                    .addComponent(west, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(center, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addComponent(east, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
                .addComponent(south)               
        );
        JDialog dialog = new JDialog((JFrame)null, "", true);
        dialog.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
        dialog.setContentPane(panel);
        dialog.pack();
        dialog.setVisible(true);
    }
}

Monday Jun 04, 2007

TIP: Declaration and initialization of an unmodifiable static final Set

    static final Set<String> stringSet =
            Collections.unmodifiableSet(
                new HashSet<String>(Arrays.asList(
                    "foo",
                    "bar",
                    "baz"
                    )));

Modified based on a tip by Rafael de F. Ferreira. I cannot use a trailing comma on each line though for easy addition/removal of entries.

Thursday Jan 11, 2007

A simple program to toggle CVSROOT of existing checked out workspace

One may check out a cvs workspace using a CVSROOT e.g. :pserver:username@extranet.foo.com:/cvs. This value of CVSROOT is recorded in the CVS/Root file in the checkedout directories. At some later time, depending on the network connectivity, it may be faster to use an alternate (aliased) CVSROOT e.g. :pserver:username@intranet.foo.com:/cvs. The following simple program provides the functionality to fix the CVSROOT settings in the CVS/Root file. It skips the entries specified in the .cvsignore file.

CAUTION: Care must be taken to make sure that both cvs servers are really the same servers or mirros that are in sync.

Usage:

java fixcvsroot.Main NEWCVSROOT
DISCLAIMER: This is experimentalcode. So no guarantees. Use the code at your own risk.
package fixcvsroot;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.HashSet;
import java.util.Set;
/\*\*
 \* A simple program to fix the CVSROOT. 
 \* <p>
 \* One may check out a cvs workspace using a CVSROOT e.g.
 \* <code>:pserver:username@extranet.foo.com:/cvs</code>. This value of CVSROOT
 \* is recorded in the <code>CVS/Root</code> file in the checkedout directories.
 \* At some later time, depending on the network connectivity, it may be faster
 \* to use an alternate (aliased) CVSROOT e.g.
 \* <code>:pserver:username@intranet.foo.com:/cvs</code>.
 \*
 \* This simple program provides the functionality to fix the CVSROOT settings
 \* in the <code>CVS/Root</code> file. It skips the entries specified in the
 \* <code>.cvsignore</code> file.
 \*
 \* <b>CAUTION:</b> Care must be taken to make sure that both cvs servers are
 \* really the same servers or mirros that are in sync.
 \*
 \* Usage:
 \* <code>java fixcvsroot.Main NEWCVSROOT</code>
 \*
 \* <b>DISCLAIMER:</b> This is an experimental program. Use at your own risk.
 \*
 \* @author Sandip V. Chitale (Sandip.Chitale@Sun.Com)
 \*/
public class Main {
    private Main() {
    }
    public static void main(String[] args) {
        if (args.length != 1) {
            System.err.println("Usage: java fixcvsroot.Main NEWCVSROOT");
            System.exit(1);
        }
        fixcvsroot(args[0]);
        System.exit(0);
    }
    private static void fixcvsroot(String cvsroot) {
        try {
            fixcvsroot(new File(".").getAbsoluteFile(), cvsroot);
        } catch (IOException ex) {
            System.err.println(ex.getMessage());
            return;
        }
        System.out.println();
        System.out.println("Done.");
    }
    private static void fixcvsroot(File directory, String cvsroot)
            throws IOException {
        if (directory.isDirectory()) {
            if ("CVS".equals(directory.getName()) &&
                    new File(directory, "Entries").exists() &&
                    new File(directory, "Repository").exists()) {
                try {
                    if (Boolean.getBoolean("fixcvsroot.Main.log")) {
                        System.out.println("Writing '" + cvsroot + "' to "
                                + directory.getAbsolutePath()
                                + directory.separator + "Root");
                    } else {
                        System.out.print(".");
                    }
                    PrintWriter out = new PrintWriter(
                            new BufferedWriter(new FileWriter(
                                new File(directory, "Root"))));
                    out.println(cvsroot);
                    out.close();
                } catch (IOException ex) {
                    throw new IOException("Error: " + ex.getMessage()
                            + ": Writing '" + cvsroot
                            + "' to " + directory.getAbsolutePath()
                            + directory.separator + "Root");
                }
            } else {
                // Load .cvsignore
                Set<File> ignored = null;               
                File cvsIgnore = new File(directory, ".cvsignore");
                if (cvsIgnore.exists() && cvsIgnore.isFile()) {
                    ignored = new HashSet<File>();
                    BufferedReader bufferedReader = new BufferedReader(
                            new FileReader(cvsIgnore));
                    String ignoredEntry = null;
                    while ((ignoredEntry = bufferedReader.readLine()) != null) {
                        ignored.add(new File(directory, ignoredEntry));
                    }
                }
                File[] files = directory.listFiles();
                for (File subFile:files) {
                    if (subFile.isDirectory()) {
                        // skip ignored sub directories
                        if (ignored!= null &&
                                ignored.size() > 0 &&
                                ignored.contains(subFile)) {
                            continue;
                        }
                        fixcvsroot(subFile, cvsroot);
                    }
                }
            }
        }
    }
}

Does anyone know other better technics/scripts to solve this problem?

Saturday Oct 14, 2006

TIP: Multiline tooltip

Say you want to display the message from a Throwable in a JLabel and the Throwable's stack trace in the label's tootip - you could do something like the code below:

From the GUI standards point of view this may not be a good practice because the tooltip text is not selectable/copyable. I am using the contrived example only to demonstrate the tip. In fact I wish the Swing tooltip had a mode in which the tooltip text could be selected/copied.

        Throwable throwable = new Throwable("Sample message from a Throwable");
       
        JLabel messageLabelWithSingleLineTooltip = ...;
	StringWriter stringWriter = new StringWriter();
        throwable.printStackTrace(new PrintWriter(stringWriter)); // capture the stack trace as a string
        messageLabelWithSingleLineTooltip.setText(throwable.getMessage() + "(Single line tooltip)");
        messageLabelWithSingleLineTooltip.setToolTipText(
                stringWriter.toString()
                );

You get the following wide, single line tooltip (truncated to keep the image size small).

Not very useful. The stack trace is very hard to read. The problem happens because normally the tooltip text is shown as a single line of text where as the stack trace is in the form of a multiline text. The newlines are simply stripped off. There is a simple solution to the problem though. The Swing tooltip supports html syntax. Thus you can use "<html><pre>" + multilineText  + "</pre>" and let the <pre> tag handle the multiline text. Here is the code:

        JLabel messageLabelWithMultiLineTooltip = ...;
	messageLabelWithMultiLineTooltip.setText(throwable.getMessage() + "(Multiline tooltip)");
        messageLabelWithMultiLineTooltip.setToolTipText(
                "<html><pre>"
                + stringWriter.toString()
                + "</pre>"
                );

With the above code you get: multil line tooltip as shown below:

For the details of html support in Swing components see: Using HTML in Swing Components. A lot of interesting things can be done with this functionality.

If you want to play with code here is a Netbeans 5.5 project.

DISCLAIMER: This code is experimental. So no guarantees. Use the code at your own risk.

Also see TIP: Images in Tooltips blog entry which is based on the same technique.

Sunday Jun 11, 2006

TIP: Wrap a Swing JComponent in a background image

One technique for showing a background image on a JPanel is to override paintComponent() method. This works, but requires subclassing. There is a composition based alternative. It makes use of a transparent JComponent in front of a JLabel that paints the background image (Icon). The overlap of the JComponent and JLabel is achieved using GridBagLayout.

In the following code there are two factory methods to wrap a Swing component in a background image (javax.swing.Icon) :

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;

public class BackgroundImagePanelExample {    
    
    // Set up contraints so that the user supplied component and the
    // background image label overlap and resize identically
    private static final GridBagConstraints gbc;
    static {
        gbc = new GridBagConstraints();
        gbc.gridx = 0;
        gbc.gridy = 0;
        gbc.weightx = 1.0;
        gbc.weighty = 1.0;
        gbc.fill = GridBagConstraints.BOTH;
        gbc.anchor = GridBagConstraints.NORTHWEST;
    }
    
    /\*\*
     \* Wraps a Swing JComponent in a background image. Simply invokes the overloded
     \* variant with Top/Leading alignment for background image.
     \*
     \* @param component - to wrap in the a background image
     \* @param backgroundIcon - the background image (Icon)
     \* @return the wrapping JPanel
     \*/
    public static JPanel wrapInBackgroundImage(JComponent component,
            Icon backgroundIcon) {
        return wrapInBackgroundImage(
                component,
                backgroundIcon,
                JLabel.TOP,
                JLabel.LEADING);
    }
    
    /\*\*
     \* Wraps a Swing JComponent in a background image. The vertical and horizontal
     \* alignment of background image can be specified using the alignment
     \* contants from JLabel.
     \*
     \* @param component - to wrap in the a background image
     \* @param backgroundIcon - the background image (Icon)
     \* @param verticalAlignment - vertical alignment. See contants in JLabel.
     \* @param horizontalAlignment - horizontal alignment. See contants in JLabel.
     \* @return the wrapping JPanel
     \*/
    public static JPanel wrapInBackgroundImage(JComponent component,
            Icon backgroundIcon,
            int verticalAlignment,
            int horizontalAlignment) {
        
        // make the passed in swing component transparent
        component.setOpaque(false);
        
        // create wrapper JPanel
        JPanel backgroundPanel = new JPanel(new GridBagLayout());
        
        // add the passed in swing component first to ensure that it is in front
        backgroundPanel.add(component, gbc);
        
        // create a label to paint the background image
        JLabel backgroundImage = new JLabel(backgroundIcon);
        
        // set minimum and preferred sizes so that the size of the image
        // does not affect the layout size
        backgroundImage.setPreferredSize(new Dimension(1,1));
        backgroundImage.setMinimumSize(new Dimension(1,1));
        
        // align the image as specified.
        backgroundImage.setVerticalAlignment(verticalAlignment);
        backgroundImage.setHorizontalAlignment(horizontalAlignment);
        
        // add the background label
        backgroundPanel.add(backgroundImage, gbc);
        
        // return the wrapper
        return backgroundPanel;
    }
    
    public static void main(String[] args) {
        JFrame frame = new JFrame("Background Image Panel Example");

        // Create some GUI
        JPanel foregroundPanel = new JPanel(new BorderLayout(10, 10));
        foregroundPanel.setBorder(
                BorderFactory.createEmptyBorder(10,10,10,10));
        foregroundPanel.setOpaque(false);
        
        foregroundPanel.add(new JLabel("Comment:"), BorderLayout.NORTH);
        foregroundPanel.add(new JScrollPane(new JTextArea(5,30)),
                BorderLayout.CENTER);
        foregroundPanel.add(
                new JLabel(
                "Please enter your comments in text box above." +
                " HTML syntax is allowed."), BorderLayout.SOUTH);
        
        frame.setContentPane(wrapInBackgroundImage(foregroundPanel,
                new ImageIcon(
                BackgroundImagePanelExample.class.getResource("bg.jpg"))));
        
        frame.pack();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(true);
    }
}

The above code uses the following image as the background:

Background image

Note: Make sure to place this image in the same folder as the above java class.

Running the above code shows the following GUI:

Background image

The other advantage of this technique is that it only uses property settings. Therefore this can be used in the GUI builders like Matisse from Netbeans. Here is sample Netbeans project. Here is a screenshot of panel with a background image in Matisse GUI builer:

Matisse

Sunday May 21, 2006

TIP: Images in Tooltips

Here is a simple tip:

The Swing tooltips support html syntax via use of the <html> tag. This can be exploited to show images in tooltips.

For example, with the following layout:

src
   org
      mypackage
         ImageInTooltip.java
         tooltip.gif
and source code:
package org.mypackage;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ImageInTooltip {
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		JLabel label = new JLabel("Label with image in Tooltip!");
		label.setToolTipText(
			"<html><img src=\\"" +
			ImageInTooltip.class.getResource("tooltip.gif") +
			"\\"> Tooltip "
			);
		label.setHorizontalAlignment(JLabel.CENTER);
		frame.setContentPane(label);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setBounds(100, 100, 200, 100);
		frame.setVisible(true);
	}
}
give you this:

Sunday Feb 12, 2006

GridBagLayout simplified ?

The java.awt.GridBagLayout has a (dis)reputation of being a complex layout manager. This funny flash animation is a testament to that.

IMHO this is partly due to the following factors:

All of this makes the code complex and long. I have written a simple class GridBagHelper to manage the complexity of the layout code and make it compact.
/\*\*
 \*
 \* Author: Sandip Chitale (Sandip.Chitale@Sun.Com)
 \*/
import java.awt.\*;
import java.awt.event.\*;

/\*\*
 \*
 \* This helps manage and organize the <code>GridBagLayout</code> code.
 \*
 \* For example:
 \* 
 \* The following table is based on the Scott Stanchfield's (Swing course instructor)
 \* tip for taming the GridBagLayout. The only difference is that the row
 \* and column from his tip are transposed. i.e. the constraints are in a row
 \* and components go downwards.
 \*
 \* <code>
 \* <pre>
JLabel     entryLabel  = new JLabel("Entry");
JButton    browse      = new JButton("Browse...");
JTextField entry       = new JTextField();
JButton    add         = new JButton("Add");
JLabel     entriesLabel= new JLabel("Entries");
JButton    delete      = new JButton("Delete");
JList      entries     = new JList();
JButton    modify      = new JButton("Modify");
JButton    moveUp      = new JButton("Move Up");
JButton    moveDown    = new JButton("Move Down");

// Non last rows insets
Insets    i  = new Insets(5,5,0,0);
// last row insets
Insets    ir = new Insets(5,5,5,0);
// last col insets
Insets    ic = new Insets(5,5,0,5);
// last row,col insets
Insets    irc= new Insets(5,5,5,5);

GridBagHelper gbh[] = {
//____________________________________________________________________________________________________________________________________
//                            |    |    |     |      |   |   |                            |                             |     |   |
//                  Component | col| row|     |      |wt |wt |        anchor              |            fill             |insts|pad|pad 
//                            |  x |  y |width|height| x | y |                            |                             |     | x | y
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entryLabel  , 0  , 0  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.NONE      , i   , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(browse      , 1  , 0  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entry       , 0  , 1  , 1   , 1    , 1 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, i   , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(add         , 1  , 1  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entriesLabel, 0  , 2  , 1   , 1    , 1 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.NONE      , i   , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(delete      , 1  , 2  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(entries     , 0  , 3  , 1   , 3    , 0 , 1 ,GridBagConstraints.NORTHWEST,GridBagConstraints.BOTH      , ir  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(modify      , 1  , 3  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(moveUp      , 1  , 4  , 1   , 1    , 0 , 0 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, ic  , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
new GridBagHelper(moveDown    , 1  , 5  , 1   , 1    , 0 , 1 ,GridBagConstraints.NORTHWEST,GridBagConstraints.HORIZONTAL, irc , 0 ,0),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
};

Panel mainPanel = new Panel();

GridBagHelper.createGUI(mainPanel, gbh); 
 \* </pre>
 \* </code>
 \* <p>
 \* @author Sandip Chitale (Sandip.Chitale@Sun.Com)
 \* @see GridBagLayout
 \* @see GridBagConstraints
 \*
 \*/
public class GridBagHelper
{
    private Component         component;
    private GridBagConstraints gbc;

    /\*\*
     \* Create an instance for a component and its constraints
     \*
     \* @param component  the component for which the following constraints apply
     \* @param gridx      the cell column
     \* @param gridy      the cell row
     \* @param gridwidth  the number of columns spanned  
     \* @param gridheight the number of rows spanned
     \* @param weightx    the ratio of horzontal expansion
     \* @param weighty    the ratio of vertical expansion 
     \* @param anchor     the point in the cell where the component gravitates N, NE, E, SE, S, SW, W, NW, C
     \* @param fill       the direction in which the component fills the cell NONE, HORIZONTAL, VERTICAL, BOTH
     \* @param insets     the margins around the component
     \* @param ipadx      the horizontal padding between cells
     \* @param ipady      the vertical padding between cells
     \*/
    public GridBagHelper(Component component
                         ,int gridx
                         ,int gridy
                         ,int gridwidth
                         ,int gridheight
                         ,double weightx
                         ,double weighty
                         ,int anchor
                         ,int fill
                         ,Insets insets
                         ,int ipadx
                         ,int ipady
                         )
    {
        this.component = component;
        gbc = new GridBagConstraints();
        gbc.gridx = gridx;
        gbc.gridy = gridy;
        gbc.gridwidth = gridwidth;
        gbc.gridheight = gridheight;
        gbc.weightx = weightx;
        gbc.weighty = weighty;
        gbc.anchor = anchor;
        gbc.fill = fill;
        gbc.insets = insets;
        gbc.ipadx = ipadx;
        gbc.ipady = ipady;    
    }

    /\*\*
     \* createGUI - adds the components with suitable constraints.
     \*
     \* @param c a value of type 'Container'
     \* @param gbh[] a value of type 'GridBagHelper'
     \*/
    public static void createGUI(Container c, GridBagHelper gbh[])
    {
        c.setLayout(new GridBagLayout());
        for (int i = 0; i < gbh.length;i++){
            c.add(gbh[i].component, gbh[i].gbc);
        }
    }
}
I use a simple algorithm to deal with the layout using GridBagHelper class above.
  • Create the containing panel p.
  • Sketch out a grid in which components will be added.
  • Create all the required components.
  • Create insets. I use a value of 5 pixels. However this should be controlled by the look and feel guidelines you follow.
    • Insets i = new Insets(5,5,0,0); - for cells that do not touch the right or bottom edge of the grid
    • Insets ir = new Insets(5,5,5,0); - for cells that the bottom edge of the grid (i.e. last row cells).
    • Insets ic = new Insets(5,5,0,5); - for cells that touch the right edge of the grid (i.e. last column cells).
    • Insets irc= new Insets(5,5,5,5); - for cells that touch the right and bottom edge of the grid (i.e. last row and column cell).
  • Start with empty table:
GridBagHelper gbh[] = {
//____________________________________________________________________________________________________________________________________
//                            |    |    |     |      |   |   |                            |                             |     |   |
//                  Component | col| row|     |      |wt |wt |        anchor              |            fill             |insts|pad|pad 
//                            |  x |  y |width|height| x | y |                            |                             |     | x | y
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
};
  • For each component c:
    • Create a row:
new GridBagHelper(            ,    ,    ,     ,      ,   ,   ,                            ,                             ,     ,   , ),
//____________________________|____|____|_____|______|___|___|____________________________|_____________________________|_____|___|___
    • Add component reference c under Component column.
    • Enter the cell column number in the col x column
    • Enter the cell row number in the row y column.
    • How many columns cells does the component span. Enter that value in width column. This may affect the col x number of the components to the right.
    • How many row cells does the component span. Enter that value in height column. This may affect the row y number of the components to the below.
    • When the containing panel is resized should the changes in width affect this component's width and to what proportion. Enter that value in wt x column.
    • When the containing panel is resized should the changes in height affect this components height and to what proportion. Enter that value in wt x column. Note: This is affected by how the fill contraint.
    • How will the component be aligned vertically and horizontally in the cell. I mostly use GridBagConstraints.NORTHWEST.
    • Should the component be stretched to fill the cell
      • if the answer is no  enter the value GridBagConstraints.NONE in fill column.
      • if the answer is horizontally enter the value GridBagConstraints.HORIZONTAL in fill column.
      • if the answer is vertically enter the value GridBagConstraints.VERTICAL in fill column.
      • if the answer is horizontally  and vertically enter the value GridBagConstraints.BOTH in fill column.
    • Enter the inset reference in the insts column based on the position of the cell in the grid. See the insets creation step above.
    • Enter any padding in pad x and pad y columns
  • Some times it is necessary to add two panel - one in the last column and one in the last row with the following constraints to force the layout to move to north west.
    • wt x = 1.0
    • wt y = 1.0
    • anchor = GridBagConstraints.NORTHWEST
    • fill = GridBagConstraints.BOTH
  • Now do the layout by calling
GridBagHelper.createGUI(p, gbh);

Thats all. I hope this will you make use of the powerful GridBagLayout to layout your GUI panels. Enoy!

Wednesday Feb 01, 2006

Good (not!), bad, ugly?

WaitCursor.java

import java.awt.Cursor;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.SwingUtilities;
import sun.security.krb5.internal.crypto.e;

public class WaitCursor {
    public static void main(String[] args) {
        final JFrame    frame = new JFrame("Wait Cursor");

        JMenuBar        menuBar               = new JMenuBar();
        JMenu           fileMenu              = new JMenu("File");
        JMenuItem       launchLongRunningTask = new JMenuItem("Launch Long Running Task");

        launchLongRunningTask.addActionListener(new ActionListener() {
                public void actionPerformed(final ActionEvent e) {
                    // At least show wait cursor
                    SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                frame.setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
                            }
                        });
                    SwingUtilities.invokeLater(new Runnable() {
                            public void run() {
                                try {
                                    // simulated long running operation
                                    Thread.currentThread().sleep(10000);
                                } catch (InterruptedException e) {
                                    System.err.println(e.getMessage());
                                } finally {
                                    // reset the cursor to default
                                    frame.setCursor(Cursor.getDefaultCursor());
                                }
                            }
                        });
                }
            });
        
        fileMenu.add(launchLongRunningTask);
        menuBar.add(fileMenu);
        frame.setJMenuBar(menuBar);

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setBounds(400, 400, 200, 100);
        frame.setVisible(true);
    }
}

Comments?

Wednesday Jan 25, 2006

Desktop version of Desktop Sampler Tool

Download the desktop version of the Desktop Sampler here.

Screenshots

Desktop Sampler

Desktop Sampler showing Magnifier

To run

  • simply double click on the downloaded DesktopSampler.jar or
  • execute command java -jar DesktopSampler.jar

DISCLAIMER: This tool is experimental. So no guarantees. Use the tool at your own risk.

About

sandipchitale

Search

Archives
« April 2014
SunMonTueWedThuFriSat
  
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
29
30
   
       
Today