I've got a problem with setting an OutlinePaint to a line from LineAndShapeRenderer in JFreeChart.
I've found this article http://www.jfree.org/phpBB2/viewtopic.php?f=3&t=28347&p=78648&hilit=outlines+2d+line#p78648 which describes my problem also.
David.Gilbert writes "You'll have to modify the LineAndShapeRenderer code, because right now it just draws a single line between the data points (using the seriesPaint)." This was in 2009 and I can't find any todays solutions.
Does anybody has an idea how to modify the LineAndShapeRenderer to set the Outline of the line.
Thank you guys.
You'll have to override the drawItem() method of LineAndShapeRenderer. In your implementation, you'll need to recapitulate the existing code, using the public accessors, as shown here for XYLineAndShapeRenderer. The existing implementation uses the graphics context's fill() method to render a shape and draw() to stoke its outline; each invocation can have a different paint setting. No similar dichotomy exists for draw(line), but you can get a comparable effect using a composite Stroke, as shown here.
I don't know how to set each paint.
Starting form this example, draw() a Line2D with one color and the default Stroke:
Line2D shape = new Line2D.Double(PAD, PAD, SIZE - PAD, SIZE - PAD);
g.setColor(Color.blue);
g.draw(shape);
And draw() the outline with another color and a CompositeStroke:
BasicStroke s1 = new BasicStroke(16f);
BasicStroke s2 = new BasicStroke(1f);
g.setStroke(new CompositeStroke(s1, s2));
g.setColor(Color.red);
g.draw(shape);
See also this related example.
Related
I cannot find any info on how to draw shapes on a graphic canvas, making sure what I draw is not the same color as the background
there are some solutions out there but they all use images drawing only with per pixel operations/loops or filters; I also tried different Composite operations, but none suit what I want
so lets say I do
g.setColor(color.white) // relevant in this case ? not sure
g.fillRect(...)
I want the rectangle to be in inverted colors of the background so it is always visible
sorry I cant provide more code, I really dont know how to achieve this
thanks
Your paint method could retrieve the current color, and search for its complementary color:
Color originalColor = g.getColor();
g.setColor(complementaryColor(originalColor));
g.fillRect(0, 0, 50, 50);
The complementaryColor method is inspired from this topic : Reverse opposing colors
Color complementaryColor(final Color bgColor) {
Color complement = new Color(255 - bgColor.getRed(),
255 - bgColor.getGreen(),
255 - bgColor.getBlue());
return complement;
}
I have a simple question to ask.
Is it possible to do an affine transform outside the paint/paintComponent context?
For instance, let's say i want to create a Shape made of a GeneralPath and then rotate it 45°.
Is it possible to create that object and then rotate it always in the class constructor instead of creating the object and then rotate it in the paint/paintComponent method?
Thank you very much.
UPDATE
Thank you very much for the info guys.
So today i have made a simple test as you suggested and it works.
This is with the Affine transform inside the paintComponent method, commented:
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D)g;
g2.setColor(new Color(230, 230, 230));
g2.fill(enne.getNuvola());//enne.getNuvola(): code from an omitted class. returns a Shape of a cloud
g2.setColor(new Color(20, 20, 20));
/*
AffineTransform t = AffineTransform.getTranslateInstance(400,400);
g2.transform(t);
*/
g2.fill(rock.getRocket());
}//paintComponent
and this is the affine transform inside the class constructor of a GeneralPath
public class Rocket {
GeneralPath rocket;
public Rocket(){
rocket = new GeneralPath();
rocket.moveTo(10,10);
rocket.lineTo(15,15);
rocket.lineTo(15,50);
rocket.lineTo(5,50);
rocket.lineTo(5,15);
rocket.lineTo(10,10);
rocket.closePath();
AffineTransform t = AffineTransform.getTranslateInstance(400,400);
rocket.transform(t);
}//Rocket Costruttore
public GeneralPath getRocket(){
return this.rocket;
}
}//Rocket
But now i have another question:
Do i have to protect the current state of the current trasform also in the Rocket class like it is suggested to do for the paintComponent method in the java transforming tutorial?
Use the getTransform method to get the current transform.
Use transform, translate, scale, shear, or rotate to concatenate a transform.
Perform the rendering.
Restore the original transform using the setTransform method.
Again, thank you very much for your answers
No, the transform should be reset only to restore the state of the Graphics object, because that Graphics object could be reused by the system for other drawings. If you do the transform without a Graphics object, you don't need to worry about that.
Note for the future that you should not ask new questions by editing old questions, because this is confusing. You should post a completely new question (possibly linking your old question).
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
I am doing a project in which I need to print the label/description of the line (drawn using graphics) with respect to orientation of the line.
Does anyone know how to do it?
Look to the Graphics2D methods such as rotate(), scale() & translate() - as well as the more general translate(AffineTransform) method.
See Transforming Shapes, Text, and Images in the Java tutorial for more details and working examples, especially of using an AffineTransform (which can concatenate scale, rotate, transform & shear operations).
You do not mention how you obtain the Graphics object. The Graphics object passed to Swing components in paintComponent(Graphics) will generally be a Graphics2D instance, and can be cast to one. To get a Graphics2D instance from a BufferedImage, call createGraphics().
Make a class called "Labelled line" and make it something like this
class LabeledLine {
private int x1, y1, x2, y2;
private String label;
public void drawOn(Graphics g) {
// need more features? thickness, etc? add it
g.drawLine(x1,y1,x2,y2);
// compute size of text, position of text, angle of text
// draw that text
}
}
A quick google for drawing angled text gave me a couple results, so that should be easy to do.
I am drawing a triangle on a Canvas, something like:
canvas.moveTo(0, 30);
canvas.lineTo(40, 0);
canvas.lineTo(40, 40);
canvas.lineTo(40, 40);
canvas.lineTo(0, 30);
And get proper triangle on my Canvas. But I need to curve the sides a little and fill that path with specific color. What is the easiest way to do this? Drawing arcs? But how to fill the object?
Thanks!
EDIT: I noticed you were using android's canvas, not HTML Canvas, sorry. The concept is exactly the same except you'll call quadTo() instead of quadraticCurveTo(), so my example should still get you going.
Also on android you use canvas.drawPath(path, paint) and pass in a paint that has its Paint.style set to FILL_AND_STROKE.
You will want to construct the path, fill() it, then stroke() it in order to get both a filled path with the stroke outline.
To get that particular shape, the easiest way is to draw two quadratic curves. A quadratic curve first needs a control point x,y then the end point x,y. The control point for both curves should be around the middle of your desired triangle. Here is an example:
ctx.fillStyle = "lightgray";
ctx.moveTo(0, 100);
ctx.quadraticCurveTo(50, 50, 50, 0);
ctx.quadraticCurveTo(50, 50, 100, 100);
ctx.lineTo(0, 100);
ctx.fill();
ctx.stroke();
Here is that example live for you.