How can I draw a filled rectangle in JFreeChart? - java

I'm making a little application using Swing and JFreeChart. I have to display an XYLineChart, and I want to draw some filled rectangles over it. I've used the XYShapeAnnotation to draw the rectangles, and I've tried to fill them with Graphics2D, but it doesn't work. I get the rectangle displayed over the chart, but not filled. The code looks like this:
Shape rectangle = new Rectangle2D.Double(0, 0, 7, 1);
g2.fill(rectangle);
XYShapeAnnotation shapeAnnotation = new XYShapeAnnotation(rectangle, new BasicStroke(2.f), Color.BLACK);
shapeAnnotation.setToolTipText("1");
plot.addAnnotation(shapeAnnotation);
I think the problem is that the filled rectangle position is not relative to the chart, but I don't really know how to fix this. I've also wanted to know if it's possible to display the lines in the chart over the rectangles, because I don't find any way to do it.

Use the XYShapeAnnotation constructor that allows you to specify both outlinePaint and fillPaint. You probably want something like this:
XYShapeAnnotation shapeAnnotation = new XYShapeAnnotation(
rectangle, new BasicStroke(2.f), Color.BLACK, Color.BLACK);
As a concrete example based on this answer, the following change produces the result shown:
renderer.addAnnotation(new XYShapeAnnotation(ellipse, stroke, color, color));
To display the lines in the chart over the rectangles, specify the background layer for the annotation, as shown here.
renderer.addAnnotation(new XYShapeAnnotation(
ellipse, stroke, color, color), Layer.BACKGROUND);

Related

Android different multiple color in textview based on background [duplicate]

I am writing a custom progress bar. I would like to create an effect similar to
where the "50%" text color changes dynamically to white while the black bar progresses right. Is that possible using "simple" solutions? I looked up PorterDuff, ColorFilters, xFermodes, nothing seems to work. Any ideas? ATM my code looks sth like this:
Rect r = new Rect(1, 1, m_width-1, m_height-1);
canvas.drawRect(r, pWhiteFill);
r = new Rect(1, 1, progressWidth, m_height-1);
canvas.drawRect(r, pBlackFill);
canvas.drawText(String.valueOf(progress)+"%", m_width/2, m_height/2, pBlackTxtM);
Is there a way to modify pBlackTxtM paint to change color based on whats drawn below it 'on the canvas'?
Even if the question is quite old I'd like to share the solution to this.
You can't do this using an "inverting" Paint, but you can achieve it using clipping.
The idea is to draw the text twice, once in black and once in white color, while setting the clipping region to match respective part of the bar.
Here is some code to outline the idea:
// store the state of the canvas, so we can restore any previous clipping
canvas.save();
// note that it's a bad idea to create the Rect during the drawing operation, better do that only once in advance
// also note that it might be sufficient and faster to draw only the white part of the bar
Rect r = new Rect(1, 1, m_width-1, m_height-1);
canvas.drawRect(r, pWhiteFill);
// this Rect should be created when the progress is set, not on every drawing operation
Rect r_black = new Rect(1, 1, progressWidth, m_height-1);
canvas.drawRect(r_black, pBlackFill);
// set the clipping region to the black part of the bar and draw the text using white ink
String text = String.valueOf(progress)+"%";
canvas.cliprect(r_black);
canvas.drawText(text, m_width/2, m_height/2, pWhiteTxtM);
// draw the same text again using black ink, setting the clipping region to the complementary part of the bar
canvas.clipRect(r, Region.Op.XOR);
canvas.drawText(text, m_width/2, m_height/2, pBlackTxtM);
canvas.restore();

OpenGL 2D Stencil

I'm working on a scroll-box in minecraft.
The scroll-box has one problem, some controls will render outside of the box, so i decided to look up if it's possible to prevent that.
I found stencils, but it doesn't work out, maybe i did something wrong?
GL11.glEnable(GL11.GL_BLEND);
GL11.glEnable(GL11.GL_STENCIL_TEST);
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glDisable(GL11.GL_DEPTH_TEST);
GL11.glClearStencil(0);
GL11.glClear(GL11.GL_STENCIL_BUFFER_BIT);
GL11.glStencilFunc(GL11.GL_ALWAYS, 1, 1);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_REPLACE);
and this is the line of rendering the scroll-box background:
Vector4d color = new Vector4d(140, 140, 140, 255);
RenderHelper2D.drawGradientRect(1, 1, this.width-1, this.height-1, color, color);
http://i.imgur.com/Ycg7AKo.png (It's the black outlined gray pattern)
GL11.glBlendFunc(GL11.GL_ONE_MINUS_DST_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glStencilFunc(GL11.GL_EQUAL, 1, 1);
GL11.glStencilOp(GL11.GL_KEEP, GL11.GL_KEEP, GL11.GL_KEEP );
render all objectives inside the scroll-box (the buttons). Which shouldn't be shown outside of the box.
gui.drawForeground(renderer);
and reset everything
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glColorMask(true, true, true, true);
GL11.glDisable(GL11.GL_STENCIL_TEST);
I think you are looking for glScissor
It lets you basically assign a rectangular cropping window on your screen, and whatever you draw, nothing will ever be drawn outside of this rectangle.
Don't forget to call glEnable(GL_SCISSOR_TEST) before and glDisable(GL_SCISSOR_TEST) after you draw your scroll box. It won't work without the enable, and it won't stop without the disable ;)
Keep in mind that the values supplied to glScissor are integers for the origin and the width and height of the desired cropping window, the origin being defined as the lower left. Thus,
glEnable(GL_SCISSOR_TEST)
glScissor(0,0,100,100)
:: DRAW YOUR CONTROLS HERE ::
glDisable(GL_SCISSOR_TEST)
will create a 100x100 cropping window in the lower left corner of your screen.
You can use stencilbuffers if you want, but those are for more complicated tasks. Since UI usually works with rectangles, glScissor is perfect for it.

can i draw a gradient background for a figureCanvas in Java

I'd like to draw a gradient background for a FigureCanvas. Unfortunately the code which works for Composites or similars does not work for my FigureCanvas. Where it makes a perfect gradient background on my Composite it simply puts one color as background of my FigureCanvas.
Here is a snippetof how it works with all my other Controls.
Rectangle rect = parent.getClientArea();
Image newImage = new Image(parent.getDisplay(), 1, Math.max(1,
rect.height));
GC gc = new GC(newImage);
gc.setForeground(composite.getDisplay().getSystemColor(SWT.COLOR_WHITE));
gc.setBackground(composite.getDisplay().getSystemColor(SWT.COLOR_BLUE));
gc.fillGradientRectangle(0, 0, 1, rect.height, true);
gc.dispose();
composite.setBackgroundImage(newImage);
Am i missing something here? Or is it simply not possible without overwriting or extending something (if so what?)? I also tried using the same backgroundImage as another Composite has it, where it works fine.
Thank you for answers!
turns out the problem was not the FigureCanvas itself but GEF which overwrote it somewhere else.

Java Swing: How to fill a shape with a single image

I know that one can use g2d.setPaint(new TexturePaint(img,rect)) in order to fill a shape with an Image, but the problem is that the shape is tessellated with the image instead of rescaling the single image to the bounding box of the shape in order to fill the whole area.
The latter is what I want to achieve.
For example, if I have an image of 20x20 and I want to fill an Ellipse2D of width = 200 and height = 300, I would like to fill that Ellipse2D with a rescaled version of 200x300 of the image instead of tessellating it with the 20x20 image.
Is there a way to achieve this and hopefully in an efficient way?
Try this:
g2d.setPaint(new TexturePaint(img.getScaledInstance(200, 300, 0),rect));
I never tried this out before but it seems like it should work.

How to fill a freedrawn shape with colour

Im making a program using Java for android.
I'm drawing alot of rectangles on a bitmap using 4 lines connecting. ATM the lines are black and the background is white, i want to fill these "boxes" with colour and i cant figure out how to do it.
to change from drawing 4 lines into making a box from the start is not an option, i have to draw lines that form a box.
im thinking of something that takes an argument of x,y in the middle of the "box" and then filling it with pixles until it hits the edge of the box but i cant get it to work.
it needs to be reapeteble too, i have alot of boxes to fill.
im using android 2.1 with API 7
You can quite simply do this with a Path. It works as you're talking about -- move from point to point "drawing lines" -- but when you're done you can fill it.
Paint paint = new Paint();
paint.setStyle(Style.FILL);
// set other paint parameters, like color...
...
Path path = new Path();
path.moveTo(startX, startY);
path.lineTo(startX, startY + 50);
path.lineTo(startX+50, startY + 50);
path.lineTo(startX+50, startY);
canvas.drawPath(path, paint);
Use Paths. You can create your lines in a path, and then when you draw the path on the canvas, it will filled with the paint. You can also add a stroke to the path to add a border to the shape.

Categories

Resources