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.
Related
How can I draw an object without a class (which extends JFrame)? I found getGraphics method but it doesnt draw the object.
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(600, 400);
JPanel panel = new JPanel();
frame.add(panel);
Graphics g = panel.getGraphics();
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
}
If you want to change the way your component is being drawn (you are adding rectangles), you need to redefine paintComponent() in that component. In your code, you are using getGraphics().
You shouldn't call getGraphics() on a component. Any painting you do (to the Graphics returned) will be temporary and will be lost the next time Swing determines a component needs to be repainted.
Instead, you should override the paintComponent(Graphics) method (of the JComponent or JPanel), and do the painting in this method, using the Graphics object received as argument.
Check this link for further reading.
Below is your code, corrected.
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(600, 400);
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
};
frame.add(panel);
// Graphics g = panel.getGraphics();
// g.setColor(Color.BLUE);
// g.fillRect(0, 0, 100, 100);
frame.validate(); // because you added panel after setVisible was called
frame.repaint(); // because you added panel after setVisible was called
}
}
Another version, does the exact same thing, but may be clearer to you:
import javax.swing.*;
import java.awt.*;
public class Main {
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setSize(600, 400);
JPanel panel = new MyRectangleJPanel(); // changed this line
frame.add(panel);
// Graphics g = panel.getGraphics();
// g.setColor(Color.BLUE);
// g.fillRect(0, 0, 100, 100);
frame.validate(); // because you added panel after setVisible was called
frame.repaint(); // because you added panel after setVisible was called
}
}
/* A JPanel that overrides the paintComponent() method and draws a rectangle */
class MyRectangleJPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(Color.BLUE);
g.fillRect(0, 0, 100, 100);
}
}
You have to override paintComponent method in JPanel class. So you should create a class which extends JPanel and override paintComponent method in subclass
java.awt.image.BufferedImage
Why not just use an instance of java.awt.image.BufferedImage? e.g.
BufferedImage output = new BufferedImage(600, 400, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = output.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, output.getWidth(), output.getHeight());
g2.setColor(Color.BLUE);
g2.fillRect(0, 0, 100, 100);
JOptionPane.showMessageDialog(null, new ImageIcon(output));
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);
}
}
How to make JPanel to be transparent in this example? The gradient background is not visible:
package test;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.BoxLayout;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JWindow;
public class PaintJPanelOnJWindow extends JWindow {
public PaintJPanelOnJWindow() {
JPanel panel = new JPanel();
panel.setPreferredSize(new Dimension(350, 120));
panel.setMinimumSize(new Dimension(350, 120));
panel.setMaximumSize(new Dimension(350, 120));
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
panel.setOpaque(false);
JLabel someText = new JLabel("I'm not transparent and my JPanel too :(");
someText.setOpaque(false);
panel.add(someText);
add(panel);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
#Override
public void paint(Graphics g) {
Graphics2D g2d = (Graphics2D) g.create();
try {
int w = getWidth(), h = getHeight();
g2d.setPaint(new GradientPaint(0, 0, Color.RED, 0, h, Color.WHITE));
g2d.fillRect(0, 0, w, h);
} finally {
g2d.dispose();
}
super.paint(g);
}
}
The immediate problem is that
super.paint(g);
is being called after the custom painting code in the paint method which will cause any previous painting to be lost. Calling panel.setOpaque(false) has no effect what is done in the paint method. Calling setOpaque for any of the components in the question is unnecessary - by default the backgrounds are displayed when custom painting is correctly implemented.
This should be done by overriding the paintComponent method. This means creating a new JPanel and placing the custom painting functionality there rather than in a top level container such as a JWindow.
Example:
public class PaintJPanelApp {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame("Gradient App");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);
frame.setLocationRelativeTo(null);
JLabel someText = new JLabel("I AM transparent and my JPanel too :)");
GradientPanel gradientPanel = new GradientPanel();
gradientPanel.add(someText);
frame.add(gradientPanel);
frame.pack();
frame.setVisible(true);
}
});
}
static class GradientPanel extends JPanel {
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int w = getWidth();
int h = getHeight();
Graphics2D g2d = (Graphics2D) g;
g2d.setPaint(new GradientPaint(0, 0, Color.RED, 0, h, Color.WHITE));
g2d.fillRect(0, 0, w, h);
}
}
}
From JavaDocs:
create(): Creates a new Graphics object that is a copy of this Graphics object.
Which means that the Graphics object g2d is not referring to the JWindow Graphics object, it is referring to a copy of the JWindow Graphics object.
You need to change
Graphics2D g2d = (Graphics2D) g.create(); //creates a copy, wrong object
To
Graphics2D g2d = (Graphics2D) g; //refers to the right Graphics object
UPDATE
However, this is not the right way to do it. You should override JPanel's paintComponent method instead of breaking the window's paint process. First, remove the paint() method override from your class. Then, initialize the JPanel as follows:
JPanel panel = new JPanel() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
int w = getWidth(), h = getHeight();
g2d.setPaint(new GradientPaint(0, 0, Color.RED, 0, h, Color.WHITE));
g2d.fillRect(0, 0, w, h);
}
};
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.
I have a view object that is a jPanel and holds other jPanels which in turn hold jLabels. I'm wanting to paint a gradient overlay on the object to give it a nice sleek look rather than the boring plain look.
My attempt thus far is:
public class InfoDisplay extends javax.swing.JPanel {
#Override
public void paintComponent(Graphics g) {
UIDefaults uid = UIManager.getDefaults();
Graphics2D g2d = (Graphics2D)g;
int w = getWidth();
int h = getHeight();
Color lightBlue = new Color(41, 117, 200);
Color darkBlue = new Color(2, 47, 106);
if (!isOpaque()) {
super.paintComponent( g );
return;
}
GradientPaint gp = new GradientPaint(0, 0, lightBlue, 0, h, darkBlue );
g2d.setPaint(gp);
g2d.fillRect( 0, 0, w, h );
setOpaque( false );
super.paintComponent( g );
setOpaque( true );
}
}
This doesn't seem to change the objects background at all. I'm fairly new to messing with things that aren't related to the Gui defaults.
I used the Gui builder in Netbeans to create the object, so initComponents() is also in the class, but I posted only the source that is relevant to the question.
Perhaps someone can point me in the right direction?
If you want a background JPanel to use a gradient paint, then just use it. Don't do all that funny stuff in your code with setOpaque and super.paintComponent. e.g.,
import java.awt.Color;
import java.awt.Dimension;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import javax.swing.*;
#SuppressWarnings("serial")
public class GradientPaintPanel extends JPanel {
private static final Color LIGHT_BLUE = new Color(41, 117, 200);
private static final Color DARK_BLUE = new Color(2, 47, 106);
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
GradientPaint gradPaint = new GradientPaint(0, 0, LIGHT_BLUE, 0, getHeight(), DARK_BLUE);
g2.setPaint(gradPaint);
g2.fillRect(0, 0, getWidth(), getHeight());
}
public GradientPaintPanel() {
}
private static void createAndShowUI() {
GradientPaintPanel gradPaintPanel = new GradientPaintPanel();
gradPaintPanel.setPreferredSize(new Dimension(400, 300));
JFrame frame = new JFrame("GradientPaintEg");
frame.getContentPane().add(gradPaintPanel);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
java.awt.EventQueue.invokeLater(new Runnable() {
public void run() {
createAndShowUI();
}
});
}
}