Border with rounded corners - java

Here i have small piece of code for getting rectangular box using AWT.But i want that border should be rounded corner.Can you please suggest me?
int width = 150;
int height = 50;
BufferedImage bufferedImage = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = bufferedImage.createGraphics();
Font font = new Font("Georgia", Font.BOLD, 18);
g2d.setFont(font);
RenderingHints rh = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
rh.put(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHints(rh);
GradientPaint gp = new GradientPaint(0, 0,
Color.decode("#24777D"), 0, height / 2, Color.decode("#008080"), true);
g2d.setPaint(gp);
g2d.fillRect(0, 0, width, height);
g2d.setColor(new Color(255, 255, 255));
g2d.dispose();

Use drawRoundRect() method of Graphics2D class to paint border in addition to fillRoundRect() method.Follow API documentation.Here is a sample code for a try.
JFrame f = new JFrame();
f.setLayout(null);
f.setDefaultCloseOperation(3);
f.setSize(500, 500);
f.setLocationRelativeTo(null);
JPanel p = new JPanel() {
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int width = getWidth();
int height = getHeight();
Graphics2D graphics = (Graphics2D) g;
graphics.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
//Draws the rounded opaque panel with borders.
graphics.setColor(getBackground());
//paint background
graphics.fillRoundRect(0, 0, width, height, 17, 17);
graphics.setColor(getForeground());
//paint border
graphics.drawRoundRect(0, 0, width, height, 17, 17);
}
};
p.setBounds(20,20,150,50);
p.setOpaque(false);
f.getContentPane().setBackground(Color.BLUE);
f.add(p);
f.setVisible(true);

Related

Java Graphics2D drawImage() and clip(): how to apply antialiasing?

The BufferedImage drawn by the drawImage and clip method of Java Graphics2D have jagged edges, how to apply antialiasing?
The code:
BufferedImage img = ImageIO.read(new File("D:\\Pictures\\U\\U\\3306231465660486.jpg"));
JFrame frame = new JFrame();
frame.add(new JPanel() {
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30), getWidth() / 2.0, getHeight() / 2.0);
g2d.drawImage(img, 0, 0, this);
g2d.clip(new Rectangle(-110, 110, 80, 110));
g2d.fill(new Rectangle(-100, 100, 100, 100));
}
});
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
One solution is to blur the border of the image once you load it. You should also use the RenderingHints.KEY_RENDERING with RenderingHints.VALUE_RENDER_QUALITY.
This is the final result:
The full code is available below. Note that is uses a blur method described by Marco13 in this answer: https://stackoverflow.com/a/22744303/4289700.
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.MultipleGradientPaint;
import java.awt.RadialGradientPaint;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.geom.Point2D;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
public class Main {
private static BufferedImage blurImageBorder(BufferedImage input, double border) {
int w = input.getWidth();
int h = input.getHeight();
BufferedImage output = new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);
Graphics2D g = output.createGraphics();
g.drawImage(input, 0, 0, null);
g.setComposite(AlphaComposite.DstOut);
Color c0 = new Color(0x000000FF);
// Left
g.setPaint(new GradientPaint(new Point2D.Double(0, border), c0, new Point2D.Double(border, border), c0));
g.fill(new Rectangle2D.Double(0, border, border, h- border - border));
// Right
g.setPaint(new GradientPaint(new Point2D.Double(w - border, border), c0, new Point2D.Double(w, border), c0));
g.fill(new Rectangle2D.Double(w- border, border, border, h- border - border));
// Top
g.setPaint(new GradientPaint(new Point2D.Double(border, 0), c0, new Point2D.Double(border, border), c0));
g.fill(new Rectangle2D.Double(border, 0, w - border - border, border));
// Bottom
g.setPaint(new GradientPaint(new Point2D.Double(border, h - border), c0, new Point2D.Double(border, h), c0));
g.fill(new Rectangle2D.Double(border, h - border, w - border - border, border));
final float[] floatArray = new float[]{ 0, 1 };
final Color[] colorArray = new Color[]{ c0, c0 };
// Top Left
g.setPaint(new RadialGradientPaint(new Rectangle2D.Double(0, 0, border + border, border + border),
floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
g.fill(new Rectangle2D.Double(0, 0, border, border));
// Top Right
g.setPaint(new RadialGradientPaint(
new Rectangle2D.Double(w - border - border, 0, border + border, border + border),
floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
g.fill(new Rectangle2D.Double(w - border, 0, border, border));
// Bottom Left
g.setPaint(new RadialGradientPaint(
new Rectangle2D.Double(0, h - border - border, border + border, border + border),
floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
g.fill(new Rectangle2D.Double(0, h - border, border, border));
// Bottom Right
g.setPaint(new RadialGradientPaint(
new Rectangle2D.Double(w - border - border, h - border - border, border + border, border + border),
floatArray, colorArray, MultipleGradientPaint.CycleMethod.NO_CYCLE));
g.fill(new Rectangle2D.Double(w - border, h - border, border, border));
g.dispose();
return output;
}
public static void main(String[] args) throws IOException {
BufferedImage raw = ImageIO.read(new File("/path/to/picture.jpg"));
BufferedImage img = blurImageBorder(raw, 1);
JFrame frame = new JFrame();
frame.add(new JPanel() {
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30), getWidth() / 2.0, getHeight() / 2.0);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.drawImage(img, 0, 0, this);
g2d.fill(new Rectangle(-100, 100, 100, 100));
}
});
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
For the image, it is sufficient to paint the image into another image that is 2 pixels larger, and then draw the resulting image with bilinear interpolation. So you can just pass your image through a method like this one:
private static BufferedImage addBorder(BufferedImage image)
{
BufferedImage result = new BufferedImage(
image.getWidth() + 2, image.getHeight() + 2,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(image, 1, 1, null);
g.dispose();
return result;
}
The result will be this:
Here is the MCVE, including the line that sets the ..._INTERPOLATION_BILINEAR rendering hint:
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ImageBorderAntialiasing
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui()
{
//BufferedImage img = loadUnchecked("7bI1Y.jpg");
BufferedImage img = addBorder(loadUnchecked("7bI1Y.jpg"));
JFrame frame = new JFrame();
frame.add(new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30),
getWidth() / 2.0, getHeight() / 2.0);
g2d.drawImage(img, 0, 0, this);
g2d.fill(new Rectangle(-100, 100, 100, 100));
}
});
frame.setSize(600, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static BufferedImage addBorder(BufferedImage image)
{
BufferedImage result = new BufferedImage(
image.getWidth() + 2, image.getHeight() + 2,
BufferedImage.TYPE_INT_ARGB);
Graphics2D g = result.createGraphics();
g.drawImage(image, 1, 1, null);
g.dispose();
return result;
}
private static BufferedImage loadUnchecked(String fileName)
{
try
{
return ImageIO.read(new File(fileName));
}
catch (IOException e)
{
e.printStackTrace();
return null;
}
}
}
After this was answered, the question was updated to also ask about the clip method
Antialiasing the result of a clip operation may be more difficult. The clip operation is very hard "by nature" (and I assume that it eventually will be handled by something like a Stencil Buffer in hardware).
One approach to solve this could be do do the clipping manually. So instead of doing
g2d.clip(new Rectangle(-110, 110, 80, 110));
g2d.fill(new Rectangle(-100, 100, 100, 100));
you could do something like
Shape clip = new Rectangle(-110, 110, 80, 110);
Shape rectangleA = new Rectangle(-100, 100, 100, 100);
g2d.fill(clip(clip, rectangleA));
where the clip method is implemented to to manually compute the intersection of the shapes.
Note: Computing the intersection of two shapes can be rather expensive. If this becomes an issue, one might have to revise the approach. But on another note: I've heavily been doing Swing programming for ~20 years now, and cannot remember to ever have used the Graphics2D#clip method at all....
The difference between using Graphics2D#clip and the manual clipping is shown here:
and a closeup:
And there is the code:
(It does no longer contain the image part, because the problems are fairly unrelated...)
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridLayout;
import java.awt.Rectangle;
import java.awt.RenderingHints;
import java.awt.Shape;
import java.awt.geom.Area;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class ClippedDrawingAntialiasing
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(() -> createAndShowGui());
}
private static void createAndShowGui()
{
JFrame frame = new JFrame();
frame.getContentPane().setLayout(new GridLayout(1,2));
frame.getContentPane().add(new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30),
getWidth() / 2.0, getHeight() / 2.0);
g2d.clip(new Rectangle(-110, 110, 80, 110));
g2d.fill(new Rectangle(-100, 100, 100, 100));
g2d.setColor(Color.BLUE);
g2d.fill(new Rectangle(-60, 120, 60, 170));
}
});
frame.getContentPane().add(new JPanel()
{
#Override
protected void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setColor(Color.RED);
g2d.drawLine(10, 10, 300, 100);
g2d.translate(50, 200);
g2d.rotate(Math.toRadians(30),
getWidth() / 2.0, getHeight() / 2.0);
Clipper clipper =
new Clipper(new Rectangle(-110, 110, 80, 110));
g2d.fill(clipper.clip(new Rectangle(-100, 100, 100, 100)));
g2d.setColor(Color.BLUE);
g2d.fill(clipper.clip(new Rectangle(-60, 120, 60, 170)));
}
});
frame.setSize(1200, 600);
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
private static class Clipper
{
private final Shape shape;
Clipper(Shape shape)
{
this.shape = shape;
}
Shape clip(Shape other)
{
Area a = new Area(shape);
a.intersect(new Area(other));
return a;
}
}
}

How to smooth out corners in rounded rectangle, Swing?

I'm getting extremely pixilated corners when i try to make a rounded rectangle. Is there any way to smooth them out?
Here's an image (Notice the corners):
Here is the code for the Button that I subclass and override the paint method (The one with the pixilated corner):
public class ControlButton extends JButton {
public final static Color BUTTON_TOP_GRADIENT = new Color(176, 176, 176);
public final static Color BUTTON_BOTTOM_GRADIENT = new Color(156, 156, 156);
public ControlButton(String text) {
setText(text);
}
public ControlButton() {
}
#Override
protected void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D)g.create();
g2.setPaint(new GradientPaint(
new Point(0, 0),
BUTTON_TOP_GRADIENT,
new Point(0, getHeight()),
BUTTON_BOTTOM_GRADIENT));
g2.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20);
g2.dispose();
}
}
Try this:
RenderingHints qualityHints = new RenderingHints(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON );
qualityHints.put(
RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY );
g2.setRenderingHints( qualityHints );
Take a look at the documentation:
http://docs.oracle.com/javase/tutorial/2d/advanced/quality.html
Code:
import javax.swing.*;
import java.awt.*;
public class ControlButton extends JButton {
public final static Color BUTTON_TOP_GRADIENT = new Color(176, 176, 176);
public final static Color BUTTON_BOTTOM_GRADIENT = new Color(156, 156, 156);
public ControlButton(String text) {
setText(text);
}
public ControlButton() {
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g.create();
RenderingHints qualityHints =
new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
qualityHints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHints(qualityHints);
g2.setPaint(new GradientPaint(new Point(0, 0), BUTTON_TOP_GRADIENT, new Point(0, getHeight()),
BUTTON_BOTTOM_GRADIENT));
g2.fillRoundRect(0, 0, getWidth(), getHeight(), 20, 20);
g2.dispose();
}
public static void main(String args[]) {
JFrame frame = new JFrame("test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(new ControlButton("Hello, World"));
frame.pack();
frame.setVisible(true);
}
}
I did this:
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
I feel it gave me smoother edges than Dave Jarvis' method but I could be wrong.

Java How to add String below an image and resizing it?

I am trying to add a title string below a png image. The problem is that there is no space for the text and I have to add some white space. Im not sure how to do this. This is what I have done so far:
BufferedImage image = ImageIO.read(new File("output.png"));
Graphics g = image.getGraphics();
g.setFont(g.getFont().deriveFont(30f));
g.setColor(Color.BLACK);
g.drawString("Hello World!", 100, 350);
g.dispose();
ImageIO.write(image, "png", new File("test.png"));
Why not simply add the spacing you need to the new BufferedImages height?
Here is an example I made:
The real magic happens here:
private BufferedImage drawTextOnImage(String text, BufferedImage image, int space) {
BufferedImage bi = new BufferedImage(image.getWidth(), image.getHeight() + space, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
g2d.drawImage(image, 0, 0, null);
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("Calibri", Font.BOLD, 20));
FontMetrics fm = g2d.getFontMetrics();
int textWidth = fm.stringWidth(text);
//center text at bottom of image in the new space
g2d.drawString(text, (bi.getWidth() / 2) - textWidth / 2, bi.getHeight());
g2d.dispose();
return bi;
}
The above method will allow you to pass in text, a reference to the image and the amount of spacing you want to add. It will than draw the string to the image within the specified space.
The image is resized before passing it to the above method (drawTextOnImage(..)) via:
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
Test.java:
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Test {
public Test() {
createAndShowGui();
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
#Override
public void run() {
new Test();
}
});
}
private void createAndShowGui() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
BufferedImage bi = null;
try {
bi = ImageIO.read(new URL("http://cs.anu.edu.au/student/comp6700/icons/DukeWithHelmet.png"));
} catch (IOException ex) {
ex.printStackTrace();
}
BufferedImage resizedImage = resize(bi, 200, 200);
final BufferedImage textRenderedImage = drawTextOnImage("Hello", resizedImage, 15);
JPanel p = new JPanel() {
#Override
protected void paintComponent(Graphics grphcs) {
super.paintComponent(grphcs);
Graphics2D g2d = (Graphics2D) grphcs;
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2d.drawImage(textRenderedImage, 0, 0, null);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(textRenderedImage.getWidth(), textRenderedImage.getHeight());
}
};
frame.add(p);
frame.pack();
frame.setVisible(true);
}
private BufferedImage drawTextOnImage(String text, BufferedImage image, int space) {
BufferedImage bi = new BufferedImage(image.getWidth(), image.getHeight() + space, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON));
g2d.drawImage(image, 0, 0, null);
g2d.setColor(Color.BLACK);
g2d.setFont(new Font("Calibri", Font.BOLD, 20));
FontMetrics fm = g2d.getFontMetrics();
int textWidth = fm.stringWidth(text);
//center text at bottom of image in the new space
g2d.drawString(text, (bi.getWidth() / 2) - textWidth / 2, bi.getHeight());
g2d.dispose();
return bi;
}
public static BufferedImage resize(BufferedImage image, int width, int height) {
BufferedImage bi = new BufferedImage(width, height, BufferedImage.TRANSLUCENT);
Graphics2D g2d = (Graphics2D) bi.createGraphics();
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON));
g2d.addRenderingHints(new RenderingHints(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY));
g2d.drawImage(image, 0, 0, width, height, null);
g2d.dispose();
return bi;
}
}
To add white space to the bottom of a BufferedImage, you have to create a new BufferedImage and copy the image.
The 30 on the 3rd line is 30 pixels of white space. Substitute any number you wish to get the amount of white space you want.
BufferedImage image = ImageIO.read(new File("output.png"));
BufferedImage newImage = new BufferedImage(image.getWidth(),
image.getHeight() + 30, BufferedImage.TYPE_INT_ARGB);
Graphics g1 = image.getGraphics();
Graphics g2 = newImage.getGraphics();
g2.setColor(Color.WHITE);
g2.fillRect(0, 0, newImage.getWidth(), newImage.getHeight());
g2.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);

How to draw a JPanel as a Nimbus JButton?

In Nimbus look and feel JButtons have a very tidy and accurate look, with rounded border and nice background.
I'd like to render a JPanel with the very same look (obviously it won't have pressed state etc).
What are my options?
The easiest way to get "Button look" on a JPanel is probably by extending the JPanel and override paintComponent.
Here is the Nimbus JButton look:
And here is my implementation of a similar look on a JPanel (I added an empty border around for showing this example, and the corners are not translucent):
Here is my code (using gradients):
public class ColorDemo extends JPanel {
private final int gradientSize = 18;
private final Color lighterColor = new Color(250, 250, 250);
private final Color darkerColor = new Color(225, 225, 230);
private final Color edgeColor = new Color(140, 145, 145);
private final Stroke edgeStroke = new BasicStroke(1);
private final GradientPaint upperGradient = new GradientPaint(
0, 0, lighterColor,
0, gradientSize, darkerColor);
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
GradientPaint lowerGradient = new GradientPaint(
0, getHeight()-gradientSize-1, darkerColor,
0, getHeight(), lighterColor);
g2.setPaint(upperGradient);
g2.fillRect(0, 0, getWidth()-1 , gradientSize);
g2.setPaint(darkerColor);
g2.fillRect(0, gradientSize, getWidth()-1, getHeight()-gradientSize-1);
g2.setPaint(lowerGradient);
g2.fillRect(0, getHeight()-gradientSize, getWidth()-1, getHeight()-1);
g2.setStroke(edgeStroke);
g2.setPaint(edgeColor);
g2.drawRoundRect(0, 0, getWidth()-1, getHeight()-1,
gradientSize/2, gradientSize/2);
}
}
UPDATE
Here is an improved paintComponent method by AgostinoX that solved the corner issue in my code.
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALI‌​AS_ON);
float gradientPerc = (float)gradientSize/getHeight();
LinearGradientPaint lgp = new LinearGradientPaint(0,0,0,getHeight()-1,
new float[] {0, gradientPerc, 1-gradientPerc, 1f},
new Color[] {lighterColor, darkerColor, darkerColor, lighterColor});
g2.setPaint(lgp);
g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1,
gradientSize, gradientSize);
g2.setColor(edgeColor);
g2.setStroke(edgeStroke);
g.drawRoundRect(0, 0, getWidth()-1, getHeight()-1,
gradientSize, gradientSize);
}
See also my answer to How to hide the arrow buttons in a JScrollBar on how you can customize the look and feel for Nimbus. And see the Nimbus defaults for colors and painters.

Drawing non-transparent content on transparent window

So I'm trying to draw a solid red oval on a transparent window. I later want to do something more complex with multiple shapes, so using setWindowShape isn't what I'm looking for. This is the code I'm using so far:
import java.awt.*;
import javax.swing.*;
public class JavaDock extends JFrame{
public JavaDock(){
super("This is a test");
setSize(400, 150);
setUndecorated(true);
getContentPane().setLayout(new FlowLayout());
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel = new JPanel()
{
public void paintComponent(Graphics g)
{
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.Clear);
g.setColor(Color.red);
//Draw an oval in the panel
g.fillOval(10, 10, getWidth() - 20, getHeight() - 20);
}
};
panel.setOpaque(false);
setGlassPane(panel);
getGlassPane().setVisible(true);
com.sun.awt.AWTUtilities.setWindowOpacity(this, 0.5f);
setVisible(true);
}
protected void paintComponent(Graphics g) {
}
public static void main(String[] args){
JavaDock jd = new JavaDock();
}
}
You are applying a global transparency to you window, so naturally everything in it will be at least as transparent as the global value. You probably want per-pixel translucency. Replace
com.sun.awt.AWTUtilities.setWindowOpacity(this, 0.5f);
with
com.sun.awt.AWTUtilities.setWindowOpaque(this, false);
This leaves just your oval visible and it will be completely opaque. More infos can be found in this Tutorial
Graphics2D g2d = (Graphics2D) g.create();
g2d.setComposite(AlphaComposite.Clear);
g.setColor(Color.red);
g.fillOval(10, 10, getWidth() - 20, getHeight() - 20);
Code doesn't look quite right. I would try:
Graphics2D g2d = (Graphics2D)g;
g2d.setComposite(AlphaComposite.Clear);
g2d.setColor(Color.red);
g2d.fillOval(10, 10, getWidth() - 20, getHeight() - 20);
or just use:
g.setColor(Color.red);
g.fillOval(10, 10, getWidth() - 20, getHeight() - 20);

Categories

Resources