JToolTip
Hi All
I'm pretty new to this site so sorry if i have posted in the wrong section.
I have a JPanel which implements some code which draws coloured squares based on a value in a log file. When i try and implement the tooltip it only works for the WHOLE JPanel. What i want to do is hover my mouse over each graphic and get individual information about that square (read for another source) Can you help me with this?
Regards
gjmcnamara
Swing questions should be posted in the Swing forum.
> works for the WHOLE JPanel. What i want to do is
> hover my mouse over each graphic and get individual
> information about that square (read for another
> source) Can you help me with this?
The easiest way to do this would be to promote your squares to JComponent/JPanels and set the tooltip on each one. Your other choice is to use a mousemotionlistener and continually call setTooltipText as you mouse around your panel
Put the graphics into their own component, like another JPanel or a JLabel. And in the future, Swing questions should be posted in the Swing forum.
The answer may be to define smaller components, each with the own tool tip.
Or it may be to override [url=http://java.sun.com/javase/6/docs/api/javax/swing/JComponent.html#getToolTipText(java.awt.event.MouseEvent)]getToolTipText(MouseEvent)[/url].
From the API:
<quote>
If a component provides more extensive API to support differing tooltips at
different locations, this method should be overridden.
</quote>
Demo:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class TooltipExample extends JPanel {
public TooltipExample() {
setToolTipText(""); //trigger tool tipping
}
@Override
public String getToolTipText(MouseEvent event) {
return String.format("(%d,%d)", event.getX(), event.getY());
}
public static void main(String[] args) {
EventQueue.invokeLater(new GuiBuilder());
}
static class GuiBuilder implements Runnable {
public void run() {
JFrame f = new JFrame("TooltipExample ");
f.getContentPane().add(new TooltipExample());
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400,300);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
}
Thankyou. How would you suggest i handle the dynamic nature of the graphics that are being drawn, eg as this is based on network hosts, sometimes theremay by 1 square drawn in the JPanel and others 100. Is is possible to implement a method by which every square that is drawn (and they are drawn to specific co-ordinates) has its ToolTip set up at that point?
You could create a JPanel for each square and keep them in a Collection.
*Bing* *Bing* Did you run my sample code?
Yep, thankyou for that code. I ran it but i am still trying to visualise how i am going to implement this. Currently I have a JPanel in a JFrame that basically does JPanel diagrampanel = new DiagramPanel
where DiagramPanel is the class file that extends JPanel and contains all the code for the graphics.
I read a log file to determine how many squares to draw and what colour and then go about drawing them. From what i can understand from what you are saying, what i need to do is somehow draw a JPanel for each of the squares i am going to draw and put the graphic inside that JPanel?
>I read a log file to determine how many squares to draw and what colour and
> then go about drawing them. From what i can understand from what you are
> saying, what i need to do is somehow draw a JPanel for each of the squares i
> am going to draw and put the graphic inside that JPanel?
I assume this is addressed to me, since I posted code.
I think you are combining two replies to you. I didn't suggest defining multiple components. I suggest:
1. Defining a single class that extends JComponent or JPanel (not much difference between them),
and whose paintComponent method draws all those squares.
2. This component will have a "model" which is the data behind that graphical rendering.
3. Given an (x,y) coordinate, the component should be able to ask the model about the data there. ToolTip, anyone?
Now I'm not saying that the multiple-components-in-a-panel approach is
to be preferred over this. It's just that in the past, I've found this approach
to be simpler.
Cheers for all the help. I am quite confused as to how i am going to pull this all together, i usually visualise in my head how im going to implement Java but in this case i am totally lost, possibably because i am just too inexperienced. I can usually just pick up a concept with an explination of how to implement it but I am really struggling, as i said because i think i am too inexperienced.
Is there anyway you can suggest that i can get my head round this?
DrLaszloJamf : ur code gives out compilation error on that String.format(), not too sure what should it be since I've not used the that method before.
java_newbe : I don't know if this might be what ur looking for, I think what others meant was something like this>>
instead of drawing/painting the squares into the JPanel, use a JLabel or something else to represent each of the squares and add them into the JPanel.
set the layout of the JPanel to null.(absolute positioning)
add the each of the JLabels to the JPanel and use setBounds(int offsetX, int offsetY, int sqLength, int sqLength) on the JLabel to position ur "squares"
use setBackground(Color) + setOpaque(true) of the JLabel to color it.
then setToolTipText(String) for each of the JLabel's own text.
Z.Ka at 2007-7-9 22:27:31 >

Thankyou All very much....I finally saw it and this is how i implemented it:
g1.drawString("."+tooltext, 20+xbounds, 1+ybounds);
//######################Version 2 additions#############################
paneltest = new JPanel()
{
//implements the Multi-line tooltip
public JToolTip createToolTip()
{
return new JMultiLineToolTip();
}
};
addComponent(this, paneltest, 20+xbounds,3+ybounds,20,20);
paneltest.setToolTipText(tooltext+"You are currently monitoring "+logMASTER +" hosts\n"+log1+" are healthy\n"+log2);
/*paneltest.addActionListener(new ActionListener(){
public void actionPerformed1(ActionEvent e)
{
System.out.println(e);
}
});*/
//######################################################################
g1.setColor(c);
g1.drawRect(20+xbounds, 3+ybounds, 20, 20);
g1.fillRect(20+xbounds, 3+ybounds, 20, 20);
g1.setColor(c2);
g1.drawLine(30+xbounds, 23+ybounds, 30+xbounds, 32+ybounds);
g1.drawLine(30+xbounds, 32+ybounds, 1+xbounds, 32+ybounds);
Basically doing what you all suggested, the JPanel is drawn to the exact same co-ordinates as the graphic and i get all the functionality i need including the ability to 'click on' the square!
Fantastic. Thankyou again!
> DrLaszloJamf : ur code gives out compilation error on that String.format(),
By "ur" do you mean "your"? I'm not hep to the lingo kids use today.
Anyhowdy, you are using an old version of Java, that's why your compiler
didn't recognize String.format, but I'm sure your could code around that.
> > DrLaszloJamf : ur code gives out compilation error> on that String.format(), > > By "ur" do you mean "your"? I'm not hep to the lingo> kids use today.You guys from Whitehorse are so square.
I finally got around to writing a little demo, but first a few words of explanation.
1. PaintedShape is the item type to be drawn on the panel. PaintedShape has
a render() method to draw itself and a getToolTipText(pt) method that either
returns a non-null tool tip text (in this demo, its w x h dimension) or null if a
tool tip shouldn't be displayed given that mouse location.
2. ShapeContainer is a JPanel with a list of painted shapes. It renders them
in its paintComponent method, and its getToolTipText method delegates
to the painted shapes to find the text.
3. Finally, I stuck in a sample main and a gui builder to put a few shapes
out there for the demo.
4. Have fun!
import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.util.*;
import javax.swing.*;
class PaintedShape {
private Paint paint;
private Shape shape;
public PaintedShape(Paint paint, Shape shape) {
this.paint = paint;
this.shape = shape;
}
public void render(Graphics2D g2) {
g2.setPaint(paint);
g2.fill(shape);
}
public String getToolTipText(Point pt) {
if (shape.contains(pt)) {
Rectangle bounds = shape.getBounds();
return String.format("[%d x %d]", bounds.width, bounds.height);
} else
return null;
}
}
public class ShapeContainer extends JPanel {
private static final long serialVersionUID = 0;
private java.util.List<PaintedShape> shapes = new ArrayList<PaintedShape>();
public ShapeContainer() {
setToolTipText("");
}
public void add(PaintedShape shape) {
shapes.add(shape);
repaint();
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
for(PaintedShape shape : shapes)
shape.render(g2);
}
public String getToolTipText(MouseEvent event) {
Point pt = event.getPoint();
for(ListIterator<PaintedShape> i = shapes.listIterator(shapes.size()); i.hasPrevious(); ) {
PaintedShape shape = i.previous();
String text = shape.getToolTipText(pt);
if (text != null)
return text;
}
return null;
}
public static void main(String[] args) {
EventQueue.invokeLater(new GuiBuilder());
}
static class GuiBuilder implements Runnable {
public void run() {
ShapeContainer comp = new ShapeContainer();
Paint paint1 = new GradientPaint(0,0, Color.WHITE, 80, 60, Color.BLACK);
comp.add(new PaintedShape(paint1, new Rectangle(10,10, 80, 60)));
comp.add(new PaintedShape(Color.GREEN, new Ellipse2D.Float(60,40, 90, 70)));
Paint paint2 = new GradientPaint(0,0, Color.BLUE, 170, 160, Color.WHITE);
comp.add(new PaintedShape(paint2, new RoundRectangle2D.Float(20, 80, 120, 75, 30, 30)));
JFrame f = new JFrame("ShapeContainer");
f.getContentPane().add(comp);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(600,400);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
}
> You guys from Whitehorse are so square.And here I thought the Canada Winter Games made it cool: http://www.cbc.ca/photogallery/sports/316/
What is interesting is that WH has no bldgs. over four stories tall.
> What is interesting is that WH has no bldgs. over four stories tall.WH is heavily influenced by Christopher Alexander's Pattern Language.Tall building violate human scale.
> > What is interesting is that WH has no bldgs. over
> four stories tall.
>
> WH is heavily influenced by Christopher Alexander's
> Pattern Language.
> Tall building violate human scale.
I was assuming that there was some sort of plate activity as there is in nearby Alaska- the four story rule was put in place to mitigate damage during earthquakes.
I don't know. I thought the restriction was to preserve the character of the city.I know the city council has tried to raise the restriction up to 8 floors or something like that.
The city council wanted to raise the limit to 8 in order to support the burgeoning chat papri industry. More rooms = more chat, you know.
Best mango lassis, north of 60!