Thanks for giving Balloon tip a try! You can now spice up your Java Swing applications with the balloon tip components provided in this project.
Before diving in, let's take a quick look at the things that are included in the .zip-file you've just downloaded:
Now that you know what is available in this release, let's get familiar with the features Balloon tip has to offer. The quickest way to do this is to try out the demo application. Simply double-click the balloontip_with_examples_ ... .jar-file to open the demo application.
If this doesn't work, you'll have to open up a
console/command-line window and navigate into the Balloon
tip-directory.
Just enter the following command to start the demo application:
java -jar balloontip-examples ... .jar
(Replace the "..." with the right version number.)
Once the application has started, you can start exploring
many of Balloon tip's features.
Just toy around with all possible settings and see what happens; this
probably is the easiest way to learn the terminology that is used by
the Balloon tip API.
Once you're done playing, you may proceed to the next section, which will teach you the basics in creating your own balloon tips.
The BalloonTip
class implements a basic balloon tip which is suited for most uses. A BalloonTip
instance can attach itself to about any visual component: a JButton
,
JLabel
, JTextField
,
... In order to create and show a BalloonTip
instance, all you need to do is construct one. Like most components in
Swing, the BalloonTip
class comes with
several constructors.
Starting off with the easiest constructor:
BalloonTip(JComponent attachedComponent, String
text)
The first parameter, attachedComponent
,
is the JComponent
you want to attach your
balloon tip to. The second
parameter, text
, simply is the text you want
to show inside the balloon tip.
For example, if the attached component were a JButton
called myButton
and you want the balloon to
say "Hello world!", you should write:
BalloonTip myBalloonTip = new BalloonTip(myButton,
"Hello world!");
The newly created balloon tip would then look like this:
BalloonTip
attached to a JButton
If you want to have control over the balloon tip's looks, you can try this constructor:
BalloonTip(JComponent attachedComponent, String
text, BalloonTipStyle style, boolean useCloseButton)
The parameter useCloseButton
is
easy: If true, a working close button is shown.
The style
parameter is more interesting; a BalloonTipStyle
defines the balloon tip's looks. Several different styles can be found
in the package net.java.balloontip.styles
. As
an example, I'll make a BalloonTip
with the
simplest style, the EdgedBalloonStyle
,
which gives the balloon tip sharp corners:
BalloonTipStyle edgedLook = new
EdgedBalloonStyle(Color.WHITE, Color.BLUE);
BalloonTip myBalloonTip = new BalloonTip(myButton, "Hello world!",
edgedLook, true);
Now we'll get something looking like this:
BalloonTip
with an EdgedBalloonStyle
,
which
gives the balloon its sharp corners, a white background color and a
blue border Balloon tips can also contain other components beside just
text. In fact, just about any JComponent
can serve as the contents of a balloon tip.
The following constructor allows you to add a JComponent
as the contents of a balloon tip:
BalloonTip(JComponent attachedComponent,
JComponent contents, BalloonTipStyle style, boolean useCloseButton)
For example, you could set a balloon tip's contents to a
JTable
:
BalloonTipStyle edgedLook = new
EdgedBalloonStyle(Color.WHITE, Color.BLUE);
BalloonTip myBalloonTip = new BalloonTip(myButton, new JTable(3,2),
edgedLook, true);
This creates the following result:
BalloonTip
with a JTable
as
its contents JPanel
or JTabbedPane
,
you can build entire interactive user interfaces inside a balloon tip.
(Why yes, you can even attach balloon tips to the components inside a
balloon tip!)
If you also need control over the balloon tip's position, you can use the following constructor:
BalloonTip(JComponent attachedComponent,
JComponent contents, BalloonTipStyle style, Orientation orientation,
AttachLocation
attachLocation, int horizontalOffset, int verticalOffset, boolean
useCloseButton)
This constructor has four new parameters:
orientation
: Determines whether
you want the tip of the balloon on the left or right side of the
balloon, and whether the balloon itself should be above or below the
attached componentattachLocation
: Should the balloon
tip align itself with the attached component? Or should it put the
balloon's tip on a fixed location? (e.g. fix the balloon's tip
in the center of the attached component)horizontalOffset
: The amount of
space (in pixels) between the balloon's left (or right) side and the
tip of the balloonverticalOffset
: The amount of
space (in pixels) between the balloon's bottom (or top) side and the
tip of the balloonIn order to clarify the horizontalOffset
and verticalOffset
parameters a bit better,
have a look at this picture:
BalloonTip
Here's a snippet of code that creates a balloon tip using this constructor:
BalloonTipStyle edgedLook = new
EdgedBalloonStyle(Color.WHITE, Color.BLUE);
BalloonTip myBalloonTip = new BalloonTip(myButton, new JLabel("Hello
world!"),
edgedLook, Orientation.RIGHT_BELOW, AttachLocation.ALIGNED, 40, 20,
false);
This snippet will produce the following picture:
BalloonTip
with Orientation.RIGHT_BELOW
and AttachLocation.ALIGNED
Finally, if you want full control over your balloon tip, use this constructor:
BalloonTip(JComponent attachedComponent,
JComponent contents, BalloonTipStyle style, BalloonTipPositioner
positioner, boolean
useCloseButton)
Even though this constructor has fewer parameters than the
previous one from section 1.3.4,
it is more powerful. This is because of the positioner
parameter. A BalloonTipPositioner
defines the
way a balloon tip should behave. More specifically: it determines where
a
balloon tip should position itself, whether the balloon tip should
flip, what happens when the balloon tip collides with something, ...
What the previous constructors actually did was simply instantiating
the
appropriate BalloonTipPositioner
for you.
However, this constructor will allow you to supply your own instance of
BalloonTipPositioner
.
Here's another example snippet that produces exactly the same
result as the example in the previous section:
BalloonTipStyle edgedLook = new
EdgedBalloonStyle(Color.WHITE, Color.BLUE);
BalloonTipPositioner rightBelowPositioner = new
Right_Below_Positioner(40, 20);
BalloonTip myBalloonTip = new BalloonTip(myButton, "Hello world!",
edgedLook, rightBelowPositioner, false);
This concludes the basic usage of BalloonTip
.
The other methods BalloonTip
has to offer
should now be quite straightforward to use. If you require more
information, you can always refer to the
project's Javadoc.
The CustomBalloonTip
is just like a
regular BalloonTip
, but you can attach it to
a rectangular shape within a component, instead of attaching it to the
entire component.
This can be very useful in case you're creating your own JComponent
,
such as a timeline or a calendar.
JComponent
that
displays a timeline; it has a CustomBalloonTip
attached to it Just take a look at this snippet of code, which was used in the demo application, just to see how it works:
// Create a custom JComponent that draws a huge white canvas with a small blue rectangle in it
final Rectangle customOffset = new Rectangle(640, 320, 50, 16);
final JComponent customComponent = new JComponent() {
protected void paintComponent(Graphics g) {
Rectangle clip = g.getClipBounds();
g.setColor(Color.WHITE);
g.fillRect(clip.x, clip.y, clip.width, clip.height);
g.setColor(Color.BLUE);
g.fillRect(customOffset.x, customOffset.y, customOffset.width, customOffset.height);
}
};
customComponent.setPreferredSize(new Dimension(1280, 640));
// Now create the CustomBalloonTip, such that it attaches itself to the blue rectangle
customBalloon = new CustomBalloonTip(customComponent,
"I'm a CustomBalloonTip!",
customOffset,
new EdgedBalloonStyle(Color.WHITE, Color.BLUE),
BalloonTip.Orientation.LEFT_ABOVE,
BalloonTip.AttachLocation.ALIGNED,
20, 20,
false);
A TablecellBalloonTip
is a balloon
tip that attaches itself to a JTable
cell.
The TablecellBalloonTip
is very similar to a CustomBalloonTip
:
Instead of specifying a rectangular offset, you specify a cell
row
and column. The row and column will determine which table cell
the
balloon tip should attach itself to.
Any balloon tip can be automatically closed after a certain
period of time using the TimingUtils
class.
Here's an example:
BalloonTip balloonTip = new BalloonTip(someComponent, "I will dissapear in 3 seconds.");
// Now make the balloon tip disappear in 3000 milliseconds
TimingUtils.showTimedBalloon(balloonTip, 3000);
The FadingUtils
class allows you to
add a simple linear fade-in or fade-out effect to balloon tips. An
example:
BalloonTip balloonTip = new BalloonTip(someComponent, "I will fade in over 300 ms.");
// Perform a fade-in effect lasting 300 ms, at 24 frames per second and trigger finishedAction once the effect has finished
FadingUtils.fadeInBalloon(balloonTip, finishedAction, 300, 24);
Tip: If you
desire something more complex than a linear function, you could
quite easily implement your own fade effects using
the setOpacity
method of BalloonTip
in combination with, for example, timingframework.
You can turn any balloon tip into a tooltip with the ToolTipUtils
class.
If you hover over the attached component, the balloon tip will
show up after an initial delay and then stay visible
until
the mouse no longer hovers over the component or a timeout occurs, just
like a regular tooltip. A quick
example:
tooltipBalloon = new BalloonTip(someComponent,
"I'm a balloon tooltip!");
// Now convert this balloon tip to a tooltip, such that the tooltip
shows up after 500 milliseconds and stays visible for 3000 milliseconds
ToolTipUtils.balloonToToolTip(tooltipBalloon, 500, 3000);
Because Balloon tip is suited for use with Maven, it's quite easy to import it as a Maven project into Eclipse. This can be done as follows:
net.java.balloontip.examples.complete.CompleteExample
or any of the
other supplied examples in the balloontip-examples project.It doesn't matter much if you're not familiar with Maven; you can use the balloontip and balloontip-examples projects just like they were regular Java projects. The only difference with regular projects is that Maven projects have the added bonus of Maven's functionality, which is now at your disposal.
You can import Balloon tip as a regular Java project by following these steps:
net.java.balloontip.examples.complete.CompleteExample
or any of the
other supplied examples.Balloon tip comes with its set of Maven POM files; you can use them as follows:
mvn package
.While Balloon tip doesn't come with any Ant build files, it's quite easy to automatically generate them if you have Maven installed:
mvn ant:ant
to generate Ant build files
for Balloon tip. (You'll need Maven
to be able to execute this command.)Creating a new balloon tip style is fairly easy if you're a
bit familiar with Java's Graphics
API. To
start making your own balloon tip style, you should extend the BalloonTipStyle
class. In this class, you should at least override these two methods:
public Insets getBorderInsets(Component c)
public void paintBorder(Component c, Graphics
g, int x, int y, int width, int height)
getBorderInsets
is a method that
determines where the actual contents of the balloon tip (the text, the
close button, ...) should go. (If you're familiar with Cascading Style
Sheets (CSS), you should think of getBorderInsets
as a method that returns the padding of your balloon tip.) What
you should do is return an Insets
object,
which holds four integers. To determine these four, take a look at this
picture:
getBorderInsets
Suppose the green rectangle in the above picture represents
where the contents of the balloon tip should come. The implementation
of getBorderInsets
then looks like
this:
return new Insets(top, left, bottom, right);
The second method you should implement, paintBorder
,
draws the balloon tip on a Graphics
instance.
You've got a couple of different values to work with here. The obvious
ones are the x
, y
, width
and height
-parameters. x
and y
determine the top-left coordinate of
your drawing canvas, whereas width
and height
obviously represent the width and height of the drawing canvas.
Beside these parameters, you should also take into account the current
values of the fields in BalloonTipStyle
: horizontalOffset
,
verticalOffset
, flipX
and flipY
. The meaning of these fields should
become clear when looking at this image:
BalloonTipStyle
should respect the current
values of horizontalOffset
, verticalOffset
,
flipX
and flipY
Keep in mind that you must take into account flipX
and flipY
when implementing getBorderInsets
,
as they have their effect on border insets!
Apart from getBorderInsets
and paintBorder
,
you may also want to override the methods getMinimalHorizontalOffset
and isBorderOpaque
. Override getMinimalHorizontalOffset
to define the minimum value of the horizontal offset. You may want to
do this if your balloon tip starts to look funny if you go below (or
above) a certain horizontal offset. Balloon tip positioners will then
respect the minimum horizontal offset you've defined. Secondly, you
should override isBorderOpaque
if you wish to
use transparency effects. If so, simply make the method return false
and you're allowed to use transparent colors.
Apart from all of the above, there really is nothing else to
know
about balloon tip styles. However, I did assume you are familiar with
the Java Graphics
API. If you're not, I
recommend you to take a couple of tutorials (such as http://java.sun.com/docs/books/tutorial/2d/index.html),
or take a look at the code of the existing styles in Balloon tip.
The task of a balloon tip positioner is to define the
behaviour of a balloon tip. This means it controls the position of the
balloon tip, the horizontal and vertical offset of the balloon tip and
whether the balloon tip should be flipped or not. The best way to learn
how to create your own BalloonTipPositioner
is by looking at an example. The following example demonstrates a very
simple positioner that will place the balloon tip at a fixed location
relative to the attached component:
public class SimpleTipPositioner extends BalloonTipPositioner {
int x = 0; // Current X-coordinate of the top-left corner of the bounding box around the balloon tip
int y = 0; // Current Y-coordinate of the top-left corner of the bounding box around the balloon tip
/* The balloon tip will call this method every time it wants to re-draw itself.
* The parameter of this function, attached, is the Rectangle that the balloon tip should attach itself to. */
public void determineAndSetLocation(Rectangle attached) {
/* Calculate the coordinates of the top-left corner of the bounding box around the balloon tip
* This positioner will place the balloon tip above the attached Rectangle. */
x = attached.x;
y = attached.y - balloonTip.getPreferredSize().height;
// Now move the balloon tip to the position we've just calculated
balloonTip.setBounds(x, y, balloonTip.getPreferredSize().width, balloonTip.getPreferredSize().height);
balloonTip.validate();
}
/* This method should return the location of the balloon's tip */
public Point getTipLocation() {
/* You may use the last position calculated in determineAndSetLocation to calculate the tip's location.
* The fields x and y now contain the position of the top-left corner of the bounding box of the balloon tip. */
return new Point(x + 20, y + balloonTip.getPreferredSize().height);
}
/* Whenever a balloon tip's style is changed (This includes setting it for the first time..), this method is called.
* Within this method, the positioner should take care of properly setting up this new style. */
protected void onStyleChange() {
balloonTip.getStyle().setHorizontalOffset(20);
balloonTip.getStyle().setVerticalOffset(20);balloonTip.getStyle().flipX(false);
balloonTip.getStyle().flipY(false);}
}
Using this positioner will produce the following result:
BalloonTip
with a simple custom-made BalloonTipPositioner
Here's the same picture once more, but this time it also shows the various variables that were used:
This image may also prove useful; it shows the different settings of the balloon tip's style:
horizontalOffset
,
verticalOffset
, flipX
and flipY
After examining this example, you can conclude that:
balloonTip.getTopLevelContainer().getWidth()
)
If you do need extra information, you'll need to ask for it in your
positioner's constructor.getTipLocation
.Lastly, a couple of pointers that you may find useful:
While this particular example did not produce anything spectacular, you can do some neat things with your own balloon tip positioner. You could implement a positioner that, for example: always puts the balloon's tip in the center, or tries to avoid overlapping with some other components, or tries to never move the balloon tip outside a certain area, or ...