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.
Related
I have used the LinearGradientPaint class to draw a rectangle dynamically filled with user-defined colors. This happens by overriding the paintComponent method.
Here is how it looks like:
.
You can see the small thumbs/ handle on top. The user can move these around, delete them, and add new ones. They can also change the color. As a result the user can completely customize how the gradient looks like. This works just fine so far, no issue.
What I need now, and I tried searching for this info, is to get RGB-values anywhere on this gradient.
I only know the x-amount of colors that LinearGradientPaint uses to generate the gradient. I know at what point (fraction) these colors are located (the number below the gradient box, corresponding with the 'thumbs' on top.
Is there anyway to get the colors in between the RGB-values which are used to generate the gradient? In my example above I mean the darkened red or green areas.
If this really is a linear gradient between new Color(r1,g1,b1) and new Color(r2,g2,b2), then the colour at x, where 0 <= x <= 1 is
new Color((int)(r1*(1-x)+r2*x),(int)(g1*(1-x)+g2*x),(int)(b1*(1-x)+b2*x));
Of course, I have no idea whether this is the formula that is actually used inside LinearGradientPaint - but it ought to be something equivalent to this.
A way you might be able to do this, is to create a 1 pixel high BufferedImage of the same width of your component, render the gradient to it and simple use something like BufferedImage#getRGB.
This will return a int packed color value, which you can then use Color(int) to return a Color object, which makes it easier to extract the color components of the pixel.
Of course, this would all be easier if you used the BufferedImage as your primary output as well, then you would only have to create it once and because you'd be updating the image so it could be rendered to the screen, it would also be up-to-date
I have started a Java Paint program that seems to be working fine... There is just one problem. In my program I have it set up so that it repaint()'s ovals using MouseListener methods and overrides paintComponent(Graphics g). The problem is when I move my mouse to fast it begins to separate my ovals instead of making one smooth line when the mouse is dragged. Is there a way to fix this.
P.S. Keep in mind that I much rather use the fillOval method not the drawLine, because I still would like to set the stroke.
Thanks in advance
See Custom Painting Approaches for the two common ways to do painting. The example draws a Rectangle without problems as the mouse moves.
You can still set a stroke to use to draw a line between two points. You should store the previous mouse position and interpolate between the last position and the current position to create a Line2D shape. Then create a stroke that has the desired width of your oval, and apply that stroke to Graphics context, then draw the line. This link has more information about strokes and shapes.
If you really want to continue drawing ovals, you could interpolate along the line between the start/end points and draw multiple ovals in a loop.
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 want to create a number of straight lines connecting small circle shapes. then I want to change the color and width of the lines from within my program. I was thinking of using Canvas to do this but there does not seem to be a way to access individual shapes drawn on canvas to change their attributes after they are drawn. What would be an easy way to implement this?
First of all, what version of Java and which UI toolkit? AWT's Canvas is very dumb, it will not even "remember" what you have painted; when you minimize and restore the window, it will send a paint() event because it wants to be repainted.
The easiest way (if you are using AWT and stuck to Canvas) is to have a List of your shapes (either one list for all or one for circles and one for lines, or whatever you like) and make your paint method draw all of them. Then update the objects in your list. When you are done updating, call repaint() on your canvas and it will call paint() for you again.
You don't paint shapes onto a Canvas if you're using Graphics and Graphics2D functions like drawRect, drawPolygon, drawOval, etc. Once they're drawn, they don't exist as shapes anymore. You just have an image with filled-in pixels.
As mihi said, you may have to keep track of the shapes you're trying to draw, then regenerate your image if it changes. Perhaps you could also "unpaint" a shape you're trying to change by painting over it in the background color and repainting the changed shape.
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?)