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.
Related
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();
So I want to add elements or items to a canvas through a GraphicsContext.
For example, to add a Rectangle, I don't want to use fillRect(...), I want to create a Rectangle rect = new Rectangle(...) and add it to my GraphicsContext,
So I can perform changes on that rect.
Something like this :
Rectangle rect = new Rectangle();
rect.setHeight(100);
rect.setWidth(100);
rect.setFill(Color.BLACK);
DragResizeMod.makeResizable(rect, null);
then added it to
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.add(rect); //somehow
There is a solution which is to use a Pane instead of Canvas but I don't think it the best way, since a GraphicsContext run on a single thread.
Thanks in advance.
Adding Rectangles to a properly configured Pane is the way to go. I don't understand what your problem with this approach is. This is the way JavaFX works and you will probably not be able to change this.
I am adding a frame to an image in JavaFX by first adding the frame to the canvas and then the image,
so that it overlaps and the image seems to have a frame.
For some reason my image gets distorted, it scales poorly and makes everything in it look "fat".
If I try to show the image in an ImageView (variable named "image" in the code) it looks normal,
so I tried to get the values (width and height) from the normal looking ImageView, yet still no luck:
Image i = new Image(path.toUri().toString());
image.setImage(i);
canvas.setWidth(image.getFitWidth() + 20);
canvas.setHeight(image.getFitHeight() + 20);
GraphicsContext gc1 = canvas.getGraphicsContext2D();
gc1.drawImage(rimage, 0, 0, image.getFitWidth() + 20, image.getFitHeight() + 20);
GraphicsContext gc = canvas.getGraphicsContext2D();
image.preserveRatioProperty();
gc.drawImage(i, 10, 10, image.getFitWidth(), image.getFitHeight());
Original image:
Framed and distorted (the head looks rounder):
I haven't tested this myself, but theres a few things I noticed about your code.
First, the line
image.preserveRatioProperty();
doesn't actually change any state for the ImageView, all it does is tell you whether or not the ImageView is set to preserve ratios.
what you probably want instead is:
image.setPreserveRatio(true);
which I believe will probably do what you want.
If it doesn't it might be because the image has already been loaded, so if this still doesn't work, try putting image.setPreserveRatio(true); before image.setImage(i);
Isn't the window just too wide for your image? Try to crop the image using another drawImage where you can define which part of the image you want to use. Or change the window size. Or use a width and height to draw with that is relative to the one in the image.
I'm trying to change the transparency of an image over time, and I'm doing this with the method drawImage() from java.awt.Graphics. I know there's a lot of different answers online about how to do this, but I can't find a one that is simple enough for me to understand and implement.
Let's just say I have a BufferedImage image, and I want to draw this image with a 50% opacity. How would I initialize image and what would I do to adjust the alpha level of the image when I draw it. It would be great if I could use the method drawImage() and do something with that to change the transparency of the image, but it's probably not that simple.
Never tried it, but I think the basic code would be:
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
g2d.setComposite(ac);
g2d.drawImage(...);
Using image filter.
float[] scales = { 1f, 1f, 1f, 0.1f };
float[] offsets = new float[4];
RescaleOp rop = new RescaleOp(scales, offsets, null);
g2d.drawImage(buffimg, rop, 0, 0);
4th element in scales array is transparency, this value goes between 0 - 1
Answer by camickr will make the entire component apply the alpha including all inner components. But that will be much faster.
Warning: Use Image Filters with Care
ref: http://www.informit.com/articles/article.aspx?p=1013851&seqNum=2
I am using GC (org.eclipse.swt.graphics.GC) to combine some pictures into one image (using drawImage). The problem is that, by default GC has got white background. Is it possible to set background to transparent? Or any other solution to cut part from one picture and paste into second?
Simply, GC is a pen, pen can't control canvas's transparency. It just can only draws something on canvas. So, GC can't manipulate image itself, just GC can draw something on Image.
However, You can directly control transparency data with ImageData API.
You should have to know what there is no advanced drawing API except setPixel(x, y, pixel), setAlpha(x, y, alpha) on ImageData.
You could use a Canvas with no background
Canvas canvas = new Canvas(parent, SWT.NO_REDRAW_RESIZE | SWT.NO_BACKGROUND);
And then you could (like in this example) make one(or more) colors of the image transparent.
ImageData ideaData = new ImageData(getClass().getResourceAsStream("Idea.jpg"));
int whitePixel = ideaData.palette.getPixel(new RGB(255,255,255));
ideaData.transparentPixel = whitePixel;
Image transparentIdeaImage = new Image(display,ideaData);