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();
}
});
}
}
Related
I am a beginner on the Intellij Idea GUI Form. And I don't know how to set a gradient background to the form. Can someone help me? Thanks.
My layout
This is my current layout. Instead of blue, I would like to use a gradient background, how can I do that?
Make the background of JFrame transparent first.
frame.setBackground(new Color(0,0,0,0));
Create a gradient paint, and fill the panel.
JPanel panel = new javax.swing.JPanel() {
protected void paintComponent(Graphics g) {
Paint p = new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0), getWidth(), getHeight(), new Color(R, G, B, 255), true);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
}
}
Assign the panel as a content pane to the frame.
frame.setContentPane(panel);
Example
See the example below of a window with gradient-based translucency.
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.Paint;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UnsupportedLookAndFeelException;
public class Tester {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException, UnsupportedLookAndFeelException {
JFrame.setDefaultLookAndFeelDecorated(true);
// Create the GUI on the event-dispatching thread
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
createWindow();
}
});
}
private static void createWindow() {
JFrame frame = new JFrame("Translucent Window");
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE
);
createUI(frame);
frame.setVisible(true);
}
private static void createUI(JFrame frame){
frame.setLayout(new GridBagLayout());
frame.setSize(200, 200);
frame.setLocationRelativeTo(null);
frame.setBackground(new Color(0,0,0,0));
JPanel panel = new javax.swing.JPanel() {
protected void paintComponent(Graphics g) {
if (g instanceof Graphics2D) {
final int R = 100;
final int G = 100;
final int B = 100;
Paint p = new GradientPaint(0.0f, 0.0f, new Color(R, G, B, 0),
getWidth(), getHeight(), new Color(R, G, B, 255), true);
Graphics2D g2d = (Graphics2D)g;
g2d.setPaint(p);
g2d.fillRect(0, 0, getWidth(), getHeight());
} else {
super.paintComponent(g);
}
}
};
panel.setLayout(new GridBagLayout());
panel.add(new JButton("Hello World"));
frame.setContentPane(panel);
}
}
I'm trying to create a drawing on BufferedImage and then copy in onto JPanel.
When I draw directly on JPanel quality of the picture is v.good but when using intermediate BufferedImage quality / resolution is visibly reduced.
I've checked that with zoom option from OSX's Accessibility panel.
I'm developing on MacBook Pro Retina.
Is there some sort of automated scaling happening?
What am I doing wrong with BufferedImage?
Here's the code demonstrating the problem
package com.sample.gui;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class QualityProblem {
private static final double DOT_SIZE = 4;
public static void main(String[] args) {
JFrame frame = new JFrame("ChartPanel demo");
frame.setBackground(Color.WHITE);
// JPanel draw = new DrawingOK();
JPanel draw = new DrawingUgly();
draw.setBackground(Color.BLACK);
frame.getContentPane().add(draw, BorderLayout.CENTER);
frame.setSize(new Dimension(1200, 900));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static class DrawingOK extends JPanel {
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2draw = (Graphics2D) g.create();
try {
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Ellipse2D.Double e = new Ellipse2D.Double(50, 50, DOT_SIZE, DOT_SIZE);
g2draw.setColor(Color.YELLOW);
g2draw.fill(e);
} finally {
g2draw.dispose();
}
}
}
private static class DrawingUgly extends JPanel {
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = getParent().getSize();
BufferedImage image = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_RGB);
Graphics2D ig = image.createGraphics();
ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ig.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
ig.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Graphics2D g2draw = (Graphics2D) g.create();
try {
Ellipse2D.Double e = new Ellipse2D.Double(50, 50, DOT_SIZE, DOT_SIZE);
ig.setColor(Color.YELLOW);
ig.fill(e);
g2draw.drawImage(image, 0, 0, null);
} finally {
ig.dispose();
g2draw.dispose();
}
}
}
}
Edited:
Added images with 4 pixel dot and 50D both zoomed in.
Ugly one comes from BufferedImage copied onto screen's Graphics
I fixed up your drawing code.
Here's the ugly GUI.
I moved the sizing of the panel to the panel constructor. Setting the frame size includes the borders. Setting the panel size gives you the drawing area you want.
I moved the black background painting to the paintComponent method. You might as well do all the painting in one place.
I cleaned up your drawing code. You don't need to make a copy of the paintComponent graphics instance to get Graphics2D.
I made the circle bigger so you could see the sharpness. I moved the origin to the center of the circle, and turned the DOT_SIZE into a radius.
Here's the code.
package com.ggl.testing;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class QualityProblem implements Runnable {
private static final double DOT_SIZE = 50D;
public static void main(String[] args) {
SwingUtilities.invokeLater(new QualityProblem());
}
#Override
public void run() {
JFrame frame = new JFrame("ChartPanel demo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setBackground(Color.WHITE);
// JPanel draw = new DrawingOK();
JPanel draw = new DrawingUgly();
frame.getContentPane().add(draw, BorderLayout.CENTER);
frame.pack();
frame.setVisible(true);
}
private class DrawingOK extends JPanel {
private static final long serialVersionUID = 1L;
public DrawingOK() {
this.setPreferredSize(new Dimension(600, 400));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2draw = (Graphics2D) g;
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
g2draw.setColor(Color.BLACK);
g2draw.fillRect(0, 0, getWidth(), getHeight());
Ellipse2D.Double e = new Ellipse2D.Double(300D - DOT_SIZE,
200D - DOT_SIZE, DOT_SIZE + DOT_SIZE, DOT_SIZE + DOT_SIZE);
g2draw.setColor(Color.YELLOW);
g2draw.fill(e);
}
}
private class DrawingUgly extends JPanel {
private static final long serialVersionUID = 1L;
public DrawingUgly() {
this.setPreferredSize(new Dimension(600, 400));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
BufferedImage image = new BufferedImage(getWidth(), getHeight(),
BufferedImage.TYPE_INT_RGB);
Graphics2D ig = image.createGraphics();
ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
ig.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
ig.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
ig.setColor(Color.BLACK);
ig.fillRect(0, 0, getWidth(), getHeight());
Ellipse2D.Double e = new Ellipse2D.Double(300D - DOT_SIZE,
200D - DOT_SIZE, DOT_SIZE + DOT_SIZE, DOT_SIZE + DOT_SIZE);
ig.setColor(Color.YELLOW);
ig.fill(e);
ig.dispose();
g.drawImage(image, 0, 0, this);
}
}
}
This is simply because in one case, you're drawing on a hardware-supported surface that says it's 640x480 but rendering is done at 2x (or whatever scaling factor of your display) resolution. In the case of BufferedImage you're drawing onto a literal 640x480 pixel buffer. Obviously, that will look worse.
I think that the image and panel are using different rendering hints on OS X for hints you've not explicitly set. Copy/paste the textual output of this code back into the question.
import java.awt.*;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class QualityProblem {
private static final double DOT_SIZE = 40;
public static void main(String[] args) {
JFrame frame = new JFrame("ChartPanel demo");
frame.setLayout(new GridLayout(0, 1));
frame.getContentPane().add(new DrawingUgly());
frame.getContentPane().add(new DrawingOK());
frame.setSize(new Dimension(400, 300));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
}
private static class DrawingOK extends JPanel {
private static final long serialVersionUID = 1L;
DrawingOK() {
setBackground(Color.GREEN);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2draw = (Graphics2D) g.create();
System.out.println("Panel Rendering Hints:");
printRenderingHints(g2draw);
try {
g2draw.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2draw.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2draw.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Ellipse2D.Double e = new Ellipse2D.Double(50, 50, DOT_SIZE, DOT_SIZE);
g2draw.setColor(Color.YELLOW);
g2draw.fill(e);
} finally {
g2draw.dispose();
}
}
}
private static class DrawingUgly extends JPanel {
private static final long serialVersionUID = 1L;
DrawingUgly() {
setBackground(Color.RED);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Dimension size = getParent().getSize();
BufferedImage image = new BufferedImage(size.width, size.height, BufferedImage.TYPE_INT_ARGB);
Graphics2D ig = image.createGraphics();
System.out.println("Image Rendering Hints:");
printRenderingHints(ig);
ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ig.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
ig.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
Graphics2D g2draw = (Graphics2D) g.create();
try {
Ellipse2D.Double e = new Ellipse2D.Double(50, 50, DOT_SIZE, DOT_SIZE);
ig.setColor(Color.YELLOW);
ig.fill(e);
g2draw.drawImage(image, 0, 0, null);
} finally {
ig.dispose();
g2draw.dispose();
}
}
}
private static void printRenderingHints(Graphics2D g) {
RenderingHints renderingHints = g.getRenderingHints();
RenderingHints.Key[] renderHintsKeys = {
RenderingHints.KEY_ALPHA_INTERPOLATION,
RenderingHints.KEY_ANTIALIASING,
RenderingHints.KEY_COLOR_RENDERING,
RenderingHints.KEY_DITHERING,
RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.KEY_INTERPOLATION,
RenderingHints.KEY_RENDERING,
RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.KEY_TEXT_LCD_CONTRAST
};
for (RenderingHints.Key key : renderHintsKeys) {
Object o = renderingHints.get(key);
String value = o==null ? "null" : o.toString();
System.out.println(key + " \t" + value);
}
}
}
Note that on Windows it produces an identical list of values.
HaraldK in one comments below question gave really good advice. BufferedImage size needs to be multiplied by 2, Graphics2D for that image must be set with scale 2 and target Graphics2D (of the screen device) needs to be scaled with 0.5.
With those settings both circles look exactly the same when zoomed in.
Bellow complete, modified DrawingUgly class.
private static class DrawingUgly extends JPanel {
private static final long serialVersionUID = 1L;
public DrawingUgly() {
this.setPreferredSize(new Dimension(600, 25));
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2draw = (Graphics2D) g.create();
double scale = 2;
BufferedImage image = new BufferedImage((int) (getWidth() * scale), (int) (getHeight() * scale), BufferedImage.TYPE_INT_RGB);
Graphics2D ig = image.createGraphics();
ig.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
ig.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
ig.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
ig.scale(scale, scale);
ig.setColor(Color.BLACK);
ig.fillRect(0, 0, getWidth(), getHeight());
Ellipse2D.Double e = new Ellipse2D.Double(10, 10, DOT_SIZE, DOT_SIZE);
ig.setColor(Color.YELLOW);
ig.fill(e);
ig.dispose();
g2draw.scale(1.0d / scale, 1.0d / scale);
g2draw.drawImage(image, 0, 0, this);
}
}
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 want to set up a mathematical (where y grows up not down) coordinate space from (-1, -1) to (+1, +1) and have it fit in the window regardless of the window size.
I am using an anonymous JComponent subclass in Java SE 7 and casting the incoming Graphics in paintComponent to Graphics2D and then drawing on the Graphics2D
But the Graphics2D is set to a computer coordinate space that changes with the size of the window. How to get it to rescale according to window size and have Y go upwards? The following program should show a dark square in upper right quadrant.
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class G {
public static void main (String [] args) {
JFrame frame = new JFrame(G.class.getCanonicalName());
frame.setUndecorated(true);
JComponent component = new JComponent() {
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent (Graphics g) {
super.paintComponent(g);
paint2D((Graphics2D)g);
}
protected void paint2D (Graphics2D g2) {
g2.draw(new Rectangle2D.Double(0.1, 0.1, 0.9, 0.9));
}
};
frame.add(component);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
Setup the coordinate system how you want, using transform() and translate(). So:
you want the origin to be at (0, height); bottom left.
then you want to flip the Y axis.
Example code:
AffineTransform tform = AffineTransform.getTranslateInstance( 0, height);
tform.scale( 1, -1);
g2.setTransform( tform);
[My edited version]:
public static void main (String [] args) {
JFrame frame = new JFrame( G2dTransform_Question.class.getCanonicalName());
JComponent component = new JComponent() {
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent (Graphics g) {
super.paintComponent(g);
paint2D((Graphics2D)g);
}
protected void paint2D (Graphics2D g2) {
AffineTransform tform = AffineTransform.getTranslateInstance( 0, getHeight());
tform.scale( getWidth(), -getHeight()); // NOTE -- to make 1.0 'full width'.
g2.setTransform( tform);
g2.setColor( Color.BLUE); // NOTE -- so we can *see* something.
g2.fill( new Rectangle2D.Double(0.1, 0.1, 0.8, 0.8)); // NOTE -- 'fill' works better than 'draw'.
}
};
frame.setLayout( new BorderLayout()); // NOTE -- make the component size to frame.
frame.add( component, BorderLayout.CENTER);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
[Hovercraft's version]: Thanks Hover!
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import javax.swing.JComponent;
import javax.swing.JFrame;
public class G {
public static final int PREF_W = 400;
public static final int PREF_H = PREF_W;
public static void main (String [] args) {
JFrame frame = new JFrame(G.class.getCanonicalName());
frame.setUndecorated(true);
JComponent component = new JComponent() {
private static final long serialVersionUID = 1L;
#Override
protected void paintComponent (Graphics g) {
super.paintComponent(g);
AffineTransform tform = AffineTransform.getTranslateInstance( 0, getHeight());
tform.scale( 1, -1);
Graphics2D g2 = (Graphics2D) g.create();
g2.setTransform( tform);
paint2D(g2);
g2.dispose();
}
protected void paint2D (Graphics2D g2) {
g2.draw(new Rectangle2D.Double(10, 10, 20, 30));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(PREF_W, PREF_H);
}
};
frame.add(component);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.pack();
frame.setVisible(true);
}
}
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.