Coloring the area under curve using java - java

Can anyone tell me how to color the area under a curve? I have drawn a curve using Graphics2d, but don't know how to color its area.
Thanks in Advance

"Under a curve" is a bit vague.
If you can draw a curve, then you can fill a curve. When the curve is filled, the endpoints will be connected to make a closed shape.
You can create a GeneralPath that allows you to draw anything, like a shape that has a curve and contains the bottom part of the view area.
I have provided an example of both.
package draw;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.GeneralPath;
import java.awt.geom.QuadCurve2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
class MyCanvas extends JComponent {
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
QuadCurve2D q = new QuadCurve2D.Float();
q.setCurve(10, 30, 10, 200, 100, 100);
g2.draw(q);
g2.fill(q);
GeneralPath closedCurve = new GeneralPath();
QuadCurve2D q2 = new QuadCurve2D.Float();
q2.setCurve(0, 200, 150, 150, 300, 200);
closedCurve.moveTo(0, 300);
closedCurve.lineTo(0, 200);
closedCurve.append(q2, true);
closedCurve.lineTo(300, 300);
closedCurve.closePath();
g2.draw(closedCurve);
g2.fill(closedCurve);
}
}
public class DrawArc {
public static void main(String[] a) {
JFrame window = new JFrame();
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
window.setBounds(30, 30, 300, 320);
window.getContentPane().add(new MyCanvas());
window.setVisible(true);
}
}

Related

how to rotate a circle around it's axis i9n java2D

So i just learnt about affine transformation in java 2D and how each transformation behaves.So what i tried as a side project was to create a circle rotating around it's axis program,i tried translating first to the (0,0) then rotating by a degree then translating back to initial position,did that through 360 iterations with 1 degree increment but the circle still rotates out of that center points(although it goes back to its original point at last iteration).
here's what have done so far:
public void paint(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
//Use of antialiasing to have nicer lines.
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
//The lines should have a thickness of 3.0 instead of 1.0.
BasicStroke bs = new BasicStroke(3.0f);
g2d.setStroke(bs);
//The GeneralPath to decribe the car.
//GeneralPath gp = new GeneralPath();
//Start at the lower front of the car.
g2d.setPaint(new Color(110, 100, 0));
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
//Draw the car.
//g2d.fillOval(215, 135, 50, 50);
Shape s = new Ellipse2D.Double(160,160,40,40);
sustain(1000);
for(int i=0;i<360;i++) {
AffineTransform rotation = new AffineTransform();
rotation.setToRotation(Math.PI/180+i);
AffineTransform translate = new AffineTransform();
translate.setToTranslation(-160, -160);
AffineTransform translate2 = new AffineTransform();
translate2.setToTranslation(160, 160);
rotation.concatenate(translate);
translate2.concatenate(rotation);
clearWindow(g2d);
g2d.setPaint(new Color(110, 100, 0));
g2d.fill(translate2.createTransformedShape(s));
}
I've spent some time re-reading your question and looking over you code and I'm still unclear on
What it is you want to do and
What your problem is
But when has that ever stopped me from having a play 😉
Okay, so this has two circles (same shape) circling around a central point (translated) point.
Something to keep in mind is, transforms are accumulative, so you can see, between the second and third circle, I reset the transform (dispose of the graphics and take another snapshot) so my poor challenged brain doesn't get completely screwed up
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int angle = 0;
public TestPane() {
Timer timer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
angle += 1;
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 120);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
//Use of antialiasing to have nicer lines.
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawLine(getWidth() / 2, 0, getWidth() / 2, getHeight());
g2d.drawLine(0, getHeight() / 2, getWidth(), getHeight() / 2);
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
Shape s = new Ellipse2D.Double(0, 0, 40, 40);
g2d.transform(AffineTransform.getTranslateInstance(40, 40));
g2d.setPaint(Color.RED);
g2d.draw(s);
g2d.transform(AffineTransform.getTranslateInstance(-30, -30));
g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle), 50, 50));
g2d.setPaint(new Color(110, 100, 0));
g2d.drawRect(0, 0, 40, 40);
g2d.draw(s);
g2d.dispose();
g2d = (Graphics2D) g.create();
g2d.transform(AffineTransform.getTranslateInstance(40, 40));
g2d.transform(AffineTransform.getTranslateInstance(-20, -20));
g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle / 2), 40, 40));
g2d.setPaint(Color.BLUE);
g2d.drawRect(0, 0, 40, 40);
g2d.draw(s);
}
}
}
I need it to rotate around its axis(have a circular motion in respect to its own center with out changing positions)
Okay, still not clear. If you want to rotate the object around it's centre point, but have it moving at the same time, then the order in which you apply your transformations is important.
For example, I'd translate it's position first, then rotate it, as it's easier to rotate about it's centre point without needing to calculate additional offsets
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.geom.Path2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.Timer;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private int angle = 0;
private Path2D path;
public TestPane() {
path = new Path2D.Double();
path.moveTo(20, 20);
path.lineTo(0, 20);
path.append(new Ellipse2D.Double(0, 0, 40, 40), false);
Timer timer = new Timer(5, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
angle += 1;
repaint();
}
});
timer.start();
}
#Override
public Dimension getPreferredSize() {
return new Dimension(120, 120);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
//Use of antialiasing to have nicer lines.
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.transform(AffineTransform.getTranslateInstance(40, 40));
g2d.transform(AffineTransform.getRotateInstance(Math.toRadians(angle), 20, 20));
g2d.setPaint(Color.RED);
g2d.draw(path);
g2d.dispose();
}
}
}
And as an addition, you could also have a look at How to rotate an object around another moving object in java?

Partial transparency in JPanel

I have a frame with image inside and I want to choose part of that image with my own component (extending JComponent). Now it looks like that:
But I want it to look something like that:
How can I achieve this?
It really depends on how you are drawing your component. If you are using a Graphics, you can cast it to a Graphics2D and then you can either setPaint, or setComposite to get a transparency effect.
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
/**
* Created by odinsbane on 8/3/15.
*/
public class TransparentOverlay {
public static void main(String[] args){
JFrame frame = new JFrame("painting example");
JPanel panel = new JPanel(){
#Override
public void paintComponent(Graphics g){
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(Color.WHITE);
g2d.fill(new Rectangle(0, 0, 600, 600));
g2d.setPaint(Color.BLACK);
g2d.fillOval(0, 0, 600, 600);
g2d.setPaint(new Color(0f, 0f, 0.7f, 0.5f));
g2d.fillRect(400, 400, 200, 200);
g2d.setPaint(Color.GREEN);
g2d.setComposite(
AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.8f
)
);
g2d.fillRect(0,0,200, 200);
g2d.setPaint(Color.RED);
g2d.fillRect(400, 0, 200, 200);
}
};
frame.setContentPane(panel);
frame.setSize(600, 600);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
}
With a set composite, all of your drawing afterwards will have the same composite, until you change it again.

Messed up BufferedImage fonts on OS X

For some reason, a string drawn to a BufferedImage appears differently to one drawn straight to a JComponent.
Here's an example. The top string is drawn directly, while the bottom is drawn using a buffer.
What is going on here?
import javax.swing.*;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.util.Map;
public class Main {
static class Canvas extends JComponent
{
#Override
public void paintComponent(Graphics g)
{
g.setColor(Color.WHITE);
g.fillRect(0, 0, this.getWidth(), this.getHeight());
g.setColor(Color.BLACK);
g.drawString("OMFG look at this 'S'", 10, 20);
BufferedImage bi = new BufferedImage(150,50,BufferedImage.TYPE_INT_RGB);
Graphics2D imageG = bi.createGraphics();
imageG.setColor(Color.WHITE);
imageG.fillRect(0, 0, 150, 50);
imageG.setColor(Color.BLACK);
imageG.setFont(g.getFont());
imageG.drawString("OMFG look at this 'S'", 10, 10);
g.drawImage(bi, 0, 30, this);
}
}
public static void main(String[] args) {
JFrame jf = new JFrame();
jf.setMinimumSize(new Dimension(150, 80));
jf.add(new Canvas());
jf.setVisible(true);
}
}

Java bug? Why draws rectangle instead of ellipse?

The code below draws rectangle and 2 ellipses.
While should draw 3 ellipses.
My OS is Windows 7 prof 64 bit
My Java is 1.6 x86 also 1.7 x64 tested.
Why?
package tests;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import net.miginfocom.swing.MigLayout;
public class AntialiacingScaleTester {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JPanel circlePanel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
g2d.setStroke(new BasicStroke(1));
//g2d.drawOval(0, 0, 200, 200);
g2d.draw(new Ellipse2D.Double(0, 0, 200, 200));
AffineTransform old = g2d.getTransform();
g2d.setColor(Color.GREEN);
g2d.scale(1000, 1000);
g2d.setStroke(new BasicStroke(0.001f));
g2d.draw(new Ellipse2D.Double(0, 0, 0.225, 0.225));
g2d.setColor(Color.BLUE);
g2d.scale(10, 10);
g2d.setStroke(new BasicStroke(0.001f));
g2d.draw(new Ellipse2D.Double(0, 0, 0.025, 0.025));
g2d.setTransform(old);
}
};
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//frame.setLayout(new MigLayout("fill"));
//frame.add(circlePanel, "w 300, h 300, grow");
//frame.add(circlePanel);
frame.setLayout(null);
circlePanel.setBounds(new Rectangle(0, 0, 300, 300));
frame.add(circlePanel);
frame.setBounds(0, 0, 350, 300);
//frame.pack();
frame.setVisible(true);
}
});
}
}
I copy/pasted your code and it drew the 2 ellipses you wrote about, the only change I made was to replace your MigLayout by null, set the frame and panel dimensions by hand and remove the frame.pack() invocation:
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
JPanel circlePanel = new JPanel() {
#Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(1));
//g2d.drawOval(0, 0, 200, 200);
g2d.draw(new Ellipse2D.Double(0, 0, 200, 200));
AffineTransform old = g2d.getTransform();
g2d.scale(10000, 10000);
g2d.setStroke(new BasicStroke(0.001f));
g2d.draw(new Ellipse2D.Double(0, 0, 0.025, 0.025));
g2d.setTransform(old);
}
};
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
circlePanel.setBounds(new Rectangle(0, 0, 300, 300));
frame.add(circlePanel);
frame.setBounds(0, 0, 350, 300);
//frame.pack();
frame.setVisible(true);
}
}
Update:
Could reproduce the problem using the Oracle JDK (java version "1.8.0-ea") instead of the OpenJDK. Got the diamond shape, as pointed out in another answers, the scale factor is the root cause of the shape degenaration, don't know if that should be the appropiate behaviour though, so, there must be a bug in one these JRE's.
The following test program works fine for both JRE's:
import java.awt.BasicStroke;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Test {
/**
* #param args
*/
public static void main(String[] args) {
JPanel circlePanel = new JPanel() {
#Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setStroke(new BasicStroke(1));
//g2d.drawOval(0, 0, 200, 200);
g2d.draw(new Ellipse2D.Double(0, 0, 200, 200));
AffineTransform old = g2d.getTransform();
g2d.scale(10, 10);
g2d.setStroke(new BasicStroke(1.0f));
g2d.draw(new Ellipse2D.Double(0, 0, 25.0, 25.0));
g2d.setTransform(old);
}
};
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(null);
circlePanel.setBounds(new Rectangle(0, 0, 300, 300));
frame.add(circlePanel);
frame.setBounds(0, 0, 350, 300);
//frame.pack();
frame.setVisible(true);
}
}
Replicated on Java 7, Windows 7 in Eclipse, removing the Layout Manager.
My feeling is that it's due to the combination of the high scaling and inaccuracies at small floating point values, reducing the number of points generated.
If you substitute values you find between 0.0363 and 0.0362 the rendering API breaks. It no longer generates an Arc, but instead a square.
The work-around is to stop combining the huge scaling with tiny sized objects. Scale down and increase the size.

jpanel overlap other components

I have serious problem when I add JPanel to Oracle Forms Container (based-on AWT Container).
I add JPanel first, after that I add some VTextFields (Oracle Forms text field).
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
import oracle.ewt.scrolling.scrollBox.ScrollBox;
import oracle.forms.ui.DrawnPanel;
import oracle.forms.ui.FScrollBox;
import oracle.forms.ui.VTextField;
public class OverlapTest {
int w = 800;
int h= 700;
public OverlapTest() {
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(w, h);
DrawnPanel main = new DrawnPanel();
main.setLayout(null);
main.setBounds(0, 0, w, h);
main.setVisible(true);
VTextField t1 = new VTextField();
t1.setBounds(100, 100, 130, 22);
VTextField t2 = new VTextField();
t2.setBounds(100, 150, 130, 22);
VTextField t3 = new VTextField();
t3.setBounds(100, 200, 130, 22);
final JPanel draw = new JPanel(){
#Override
public void paint(Graphics g) {
super.paint(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.fillRect(0, 100, 130, 200);
g2.dispose();
}
#Override
public void update(Graphics g) {
paint(g);
}
};
draw.setOpaque(false);
draw.setBounds(0, 0, w, h);
main.add(draw);
main.add(t1);
main.add(t2);
main.add(t3);
ScrollBox sBox = new ScrollBox(main);
sBox.setBounds(0, 0, w, h);
sBox.setVScrollInsets(1, 100);
oracle.forms.ui.FScrollBox fBox = new FScrollBox(sBox, 0, 0);
fBox.setVisible(true);
fBox.setBounds(0, 0, w - 50, h - 50);
main.setComponentZOrder(draw, 3);
main.setComponentZOrder(t1, 0);
main.setComponentZOrder(t2, 1);
main.setComponentZOrder(t3, 2);
f.add(fBox);
f.setVisible(true);
}
public static void main(String[] args) {
OverlapTest test = new OverlapTest();
}
}
As you see, I add the JPanel first, after that I setComponentZorder, that is because my requirement and in my real application I cannot add JPanel at the end of all component, so I did it follow that way.
But currently I have one problem, all other component overlap the JPanel but the background of JPanel (the red rectangle) always hide other components like that.
This is the image:
I don't know, but when I use JTextField, everything is OK.
I'm using components of Oracle Forms in frmall.jar
You can download frmall.jar from http://www.megafileupload.com/en/file/329640/frmall-jar.html
Do you have any solution to make the red rectangle is overlapped by other components?
Sorry for my terible English.
Thanks in Advance.
now I try to replace Jpanel by Forms DrawnPanel, but it still have the problem:
FormCanvas form = new FormCanvas(){
#Override
public void paint(Graphics g, Dimension paramDimension,
Rectangle paramRectangle) {
// TODO Auto-generated method stub
super.paint(g, paramDimension, paramRectangle);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(Color.red);
g2.fillRect(0, 100, 200, 200);
g2.dispose();
}
};
DrawnPanel draw = new DrawnPanel();
draw.setPainter(form);
draw.setVisible(true);
So now, every my components are Forms Component, but I still get this problem
The first advice I would offer is don't mix Swing & AWT components. Try updating the 'Oracle forms' jar to a Swing version, or failing that, use only AWT components in your code.

Categories

Resources