my java application contains a JPanel on which I draw certain shapes. Now I would like to label these shapes with some kind of tooltips.
Therefore I tried to create my own "Tooltips" by using the drawString, setBackground, setColor method.:
public void drawToolTip(Graphics2D graphics, String text, Point2D position) {
graphics.setBackground(Color.RED);
graphics.setColor(Color.GREEN);
graphics.drawString(text, (float) position.getX(), (float) position.getY());
}
Unfortunately the setBackground method does not seem to work. The text background remains transparent although I set it to red. setColor and drawString just work fine.
My questions are:
What could be the reason that the setBackground method does not work?
Is there a possibility to draw a boarder arround the text without drawRect?
If I want to use "drawRect" method as a substitude to draw the text background and border: How can I make it automatically fit to the written text? Or in other words how can I get the dimensions of a specific text?
Regards Marc
Graphics2D.drawString() does not draw a background by default. You will have to do this yourself.
You can use drawRect() to draw a line border or fillRec() to draw a solid rectangle.
Oracle has a great tutorial on measuring String widths. Essentially, you need to create a java.awt.Font then get its FontMetrics and use that to calculate the width and height of your string.
A simple implementation would involve drawing onto the Graphics object of a JLabel's icon. And then simply adding the tool tip text to the Swing component.
For more information, see How to Use Tool Tips.
You can not change background color the way you expect using graphics.setBackground(..) call. Setting background color in the Graphics2D only affects the clearRect or fillRect kind of calls and not the background color of the Component.
For drawing a rectangle at a location you wish, with specific back ground, you will have to relay on following steps:
Define a rectangle - r
grpahics.setPaint() for background and
graphics.fill(r) graphcis.setPaint() for border and
graphics.draw(r) to draw border
now, comes the difficult part of drawing text in to the rectangle which involves computation of height etc. based on FontMetrics of the font you would set for drawing the text.
I googled and found an example for you here
Related
I am trying to implement the fade in/fade out animation in swing.
I am using a JPanel which does not have any components in it. It is completely drawn by paintComponent() method.
Now in one of the portion of this JPanel, I want to implement the fade in/fade-out animation. When I tried using AlphaComposite, the animation is being triggered for whole JPanel.
Can I limit this animation in a small clipped region in that panel?
Graphics2D g2d = (Graphics2D) g;
g2d.setComposite(AlphaComposite.getInstance(
AlphaComposite.XOR, alpha));
Have you tried using an Graphics object (like rectangle, circle etc..) for your fade in/out? That way it won't be triggered for the complete panel.
Good luck!
Perhaps, but that may be more difficult to achieve than what it's worth. Create a JComponent of the size you want to animate (or fade), add it to your JPanel, and have repaint() called on your smaller component during animation instead of the larger JPanel.
You can use setClip() before painting to restrict the fading area.
Suppose you want a small fading rectangle. Using Area class create 2 Shapes. Intersection of original clip and fading rect and subtraction (subtract the fading rectangle from the original clip).
Call super.paintComponent() twice with 2 different clips. For the second paint you can set your alpha filter.
In a component I must display several lines of colored pixels. Each pixel of the line is given a color. What kind of component is suitable to build the line or what kind of component is suitable to hold pixels?
Just extend JComponent and paint the lines/pixels in the paintComponent() method.
To me the best (but maybe not easiest) way would be implementing a custom Paint class that allows for setting colour regions - a bit like the GradientPaint classes but more flexible.
Then you would call Graphics2D.setPaint(myPaint) just before you draw the line.
The Paint implementation could offer a method setColorForRegion(double start, double end, Color color) with start and end taking values between 0.0 and 1.0 to mark a region on the line.
Might be a bit complicated to implement the Paint class, but the benefit is, that you can resize the lines and draw them in any direction while preserving the color pattern.
We have an old (more than 10yrs old) Java Swing applicatin which draws lots of circles and connections (lines) between those circles on a JCanvas (a subclass of JComponent) based on lab data.
Because the data becames bigger and bigger, we cannot display the entire drawing now. We have put the JCavans into a JScrollPane but it is not convenience to scroll the drawing.
Can we add zoom in zoom out for it? if yes, how? I know we can zoom image but the drawing on Canvas is an image?
thanks,
EDIT:
we draw those circles and line with Graphics within paintComponent(Graphics g) method.
You could apply a scaling Transform to the Graphics2D object passed to the paintComponent method. You can learn how to use it in the Java 2D programming trail.
Without knowing anything about your application it's hard to provide useful advice (adding a code snippet or better yet a cutdown example app would be helpful to show how things are being drawn), but I'll give it a shot:
Why don't you multiply the x,y and width,height values by a scaling factor before you draw each circle/line? I assume that somewhere your canvas is using a Graphics object to draw each shape?
Is they a way of adding a watermark to a JTextArea?
I suspect that you'd need to subclass JTextArea and override the paintComponent() method, drawing your background image first and calling super.paintComponent() to render the text:
public void paintComponent (Graphics g) {
g.drawImage(watermark, 0, 0, this);
super.paintComponent(g);
}
edit: as pointed out by camickr, a JTextArea is opaque, so your subclass will need to change this by calling setOpaque(false).
I doubt the suggestion given above will work. A JTextArea is opaque, so the text will paint over top of the image. So at the very least you will need to make the text area non-opague and you will then need to play with the background colors of the viewport and/or scrollpane.
If you want a reusable solution try creating an ImageBorder. The order of painting is:
a) paintComponent
b) paintBorder
c) paintChildren
So if you add the border to the text area it will paint on top of the text in a fixed location.
Or if you add the border to the viewport it will paint below the text is a floating location.
You may also consider using JXLayer which can create quite complex visual effects
I have to create a special TextFieldUI that draws an image as the background. That image contains some alpha components. However, whenever a character is written in that text field, first it redraws the background and then draws the character. This is fine when the background contains no alpha components, but after a few characters have been typed, the alpha areas sum up to become black.
The only way I can see around this is in the paintBackground method of TextfieldUI (which I'm overriding), I have to first sample the color of the background at that location, paint the entire graphics component that color, and then paint my background.
Does anyone know how to sample the color of a pixel when all I have access to is the Graphics object?
Is there a better way to draw a custom image as the textfield background other than overriding paintBackground in TextfieldUI?
Thanks
I haven't tried it before, but Swing is built on top of AWT, and the Robot class had a way of sampling specific pixels in the AWT
Well, I don't know what your custom code looks like in the paintBackground method, but I would make sure you fill in the text field background before you draw the image.
I'll let you decide if its "better" or not, but you can use the Background Panel which allows you to add an image to a panel. Then you add the text field to the panel (the text field is automatically made non-opaque so the image shows through). Then you add the panel to the GUI.
If that doesn't work then it would be nice to have a demo of your code so we can see whats actually happening.
When you override paintBackground, you're calling the superclass version first, right? It already lays down a background-color rectangle that would give your image a fresh-start.
Rather than 'sampling' the background color, it's probably already correct (the superclass paintBackground code gets it from the parent component if not locally set). If that default is not correct, set it in initial interface construction. (Your field isn't being overlaid on other complicated arbitrary interface of unknown solid colors, is it?)