I am trying to create a simple graphing program, and I want/need the origin to be at the bottom left corner, so I am using the following custom canvas:
public class GraphingCanvas extends Canvas {
public GraphingCanvas() {
}
public void paint(Graphics g) {
((Graphics2D) g).translate(this.getWidth(), this.getHeight());
g.translate(10, 10);
g.setColor(Color.BLACK);
g.drawLine(0, 0, 10, 10);
}
}
However, when I use this canvas, like so:
private void initialize() {
frame = new JFrame();
frame.setBounds(100, 100, 450, 300);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().setLayout(null);
GraphingCanvas canvas = new GraphingCanvas();
canvas.setBackground(Color.WHITE);
canvas.setBounds(10, 10, 414, 241);
frame.getContentPane().add(canvas);
}
The origin appears to remain at the default. Am I doing something wrong?
This may or may not do what you want, but basically I used scale(1, -1) to flip the orientation through the y-axis (and translated the context)
The magic basically happens in the paintComponent method using...
g2d.scale(1, -1);
g2d.translate(0, -getHeight());
Runnable example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Rectangle box = new Rectangle(10, 10, 20, 20);
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
draw(g2d, Color.RED, Color.MAGENTA);
g2d.dispose();
g2d = (Graphics2D) g.create();
g2d.scale(1, -1);
g2d.translate(0, -getHeight());
draw(g2d, Color.BLUE, Color.GREEN);
g2d.dispose();
}
protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {
g2d.setColor(boxColor);
g2d.fill(box);
g2d.setColor(lineColor);
g2d.drawLine(0, 0, getWidth(), getHeight());
}
}
}
Just to be sure, I created a simple method...
protected void draw(Graphics2D g2d, Color boxColor, Color lineColor) {
g2d.setColor(boxColor);
g2d.fill(box);
g2d.setColor(lineColor);
g2d.drawLine(0, 0, getWidth(), getHeight());
}
which is called with the "normal" orientation and then called again with the transformed orientation, so it's the same code been used to paint the output, the only thing that's changed is the orientation
Related
So I have some code to change the background color of a button, but when I use the code, it sets the background color and border color.
Is there a way to not make this happen?
Thanks!
Code:
public void highlight(ArrayList<JButton> buttons){
for (JButton j : buttons) {
j.setBorder(new JButton().getBorder());
j.setBackground(Color.GREEN);
j.setForeground(Color.WHITE);
j.setOpaque(true);
j.setBorderPainted(false);
j.setFocusPainted(false);
j.setBorderPainted(false);
}
}
Okay, so this is a hacked version and is based on the idea that you want to maintain the current "look and feel" of the button, but want to use a different fill color
This simply applies a "highlight" color over the button...
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsConfiguration;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.Insets;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import org.kaizen.core.ui.ImageUtilities;
public class Main {
public static void main(String[] args) {
new Main();
}
public Main() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
HighlightButton btn = new HighlightButton("Help");
btn.setMargin(new Insets(20, 20, 20, 20));
btn.setHighlight(new Color(255, 0, 0, 64));
add(btn);
btn = new HighlightButton("Help");
btn.setMargin(new Insets(20, 20, 20, 20));
btn.setHighlight(new Color(0, 255, 0, 64));
add(btn);
btn = new HighlightButton("Help");
btn.setMargin(new Insets(20, 20, 20, 20));
btn.setHighlight(new Color(0, 0, 255, 64));
add(btn);
btn = new HighlightButton("Help");
btn.setMargin(new Insets(20, 20, 20, 20));
add(btn);
}
}
public class HighlightButton extends JButton {
private Color highlight;
public HighlightButton() {
setOpaque(false);
}
public HighlightButton(String text) {
super(text);
setOpaque(false);
}
public void setHighlight(Color color) {
if (color != highlight) {
Color old = highlight;
this.highlight = color;
firePropertyChange("highlight", old, highlight);
repaint();
}
}
public Color getHighlight() {
return highlight;
}
#Override
protected void paintComponent(Graphics g) {
Color highlight = getHighlight();
if (highlight != null) {
BufferedImage img = createCompatibleImage(getWidth(), getHeight(), Transparency.TRANSLUCENT);
Graphics2D g2d = img.createGraphics();
super.paintComponent(g2d);
g2d.dispose();
BufferedImage mask = generateMask(img, getHighlight(), 1f);
g.drawImage(img, 0, 0, this);
g.drawImage(mask, 0, 0, this);
} else {
super.paintComponent(g);
}
}
}
public static BufferedImage createCompatibleImage(int width, int height, int transparency) {
BufferedImage image = getGraphicsConfiguration().createCompatibleImage(width, height, transparency);
image.coerceData(true);
return image;
}
public static GraphicsConfiguration getGraphicsConfiguration() {
return GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration();
}
public static BufferedImage generateMask(BufferedImage imgSource, Color color, float alpha) {
int imgWidth = imgSource.getWidth();
int imgHeight = imgSource.getHeight();
BufferedImage imgMask = createCompatibleImage(imgWidth, imgHeight, Transparency.TRANSLUCENT);
Graphics2D g2 = imgMask.createGraphics();
applyQualityRenderingHints(g2);
g2.drawImage(imgSource, 0, 0, null);
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_IN, alpha));
g2.setColor(color);
g2.fillRect(0, 0, imgSource.getWidth(), imgSource.getHeight());
g2.dispose();
return imgMask;
}
public static void applyQualityRenderingHints(Graphics2D g2d) {
g2d.setRenderingHint(RenderingHints.KEY_ALPHA_INTERPOLATION, RenderingHints.VALUE_ALPHA_INTERPOLATION_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(RenderingHints.KEY_COLOR_RENDERING, RenderingHints.VALUE_COLOR_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_DITHERING, RenderingHints.VALUE_DITHER_ENABLE);
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL, RenderingHints.VALUE_STROKE_PURE);
}
}
Basically, what this does, is paints a "masked" image, colored in the highlighted color OVER the top of the button. This is important to remember. The higher the alpha value of the color becomes, the less likely you are to see the text.
I've not tested this on windows, so I can't guarantee the results.
The content filling is performed by the look and feel delegate and generally ignores the color properties of the class (yeah, I know, awesome), so if you want to try and do something which was a little more robust, you'd need to define your own look and feel delegate and take over the painting process, no simple task.
Of course, you could just dispense with the content filling and borders used by the look and feel delegate and paint your own (overriding the paintComponent method), but this will not take advantage of the look and feel settings, so that's a balancing act you need to decide on
When I use the coordinates of (0,0) "Rectangle(0,0,100,100)" for the rectangle I get gradient. When I use:
GradientPaint gp = new GradientPaint(0, 0, c1, 0, 100, c2);
Rectangle reckt = new Rectangle(0,100,100,200);
the gradient disappears. What am I doing wrong?
public void draw( Graphics g ) {
Graphics2D g2d = (Graphics2D) g;
c1 = new Color(0, 0, 255);
c2 = new Color(0, 255, 255);
GradientPaint gp = new GradientPaint(0, 0, c1, 0, 100, c2);
g2d.setPaint(gp);
Rectangle reckt = new Rectangle(0,0,100,100);
g2d.fill(reckt);
}
The first two parameters define the x/y point at which the gradient starts and the fourth and fifth define the height and width. So basically, you're drawing your rectangle beyond the the gradient fill
You have two options, either change the x/y position if the GradientFill or use a AffineTransform and translate the Graphics context to where you want to paint and simply always paint at 0x0 for both
A AffineTransform allows you to translate (among other things) the Graphics top/left position, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Rectangle;
import java.awt.geom.AffineTransform;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestTranslate {
public static void main(String[] args) {
new TestTranslate();
}
public TestTranslate() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Color c1 = new Color(0, 0, 255);
Color c2 = new Color(0, 255, 255);
GradientPaint gp = new GradientPaint(0, 0, c1, 0, 100, c2);
for (int offset = 0; offset < getWidth(); offset += 50) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setPaint(gp);
g2d.setTransform(AffineTransform.getTranslateInstance(offset, offset));
g2d.fill(new Rectangle(0, 0, 100, 100));
g2d.dispose();
}
}
}
}
so I have been make a JFrame background transparent by setting the background alpha to 0, however if I run the program in linux the JFrame background is white why is this?
ok I found its got something to do with rendering graphics to the frame, this method is old I don't need it in the program anymore but i would still like to know why this happens (its just in Linux works find in windows)
here is a runnable example
import java.awt.*;
import java.awt.Color;
import javax.swing.*;
class Main extends JFrame{
private void init() {
this.setPreferredSize(new Dimension(1420, 820));
this.setUndecorated(true);
this.setResizable(false);
this.setDefaultCloseOperation(this.EXIT_ON_CLOSE);
this.setBackground(new Color(0, 255, 0, 0));
this.requestFocus();
this.setVisible(true);
this.validate();
this.pack();
Color color = UIManager.getColor("activeCaptionBorder");
this.getRootPane().setBorder(BorderFactory.createLineBorder(color, 1));
paintInfo();
}
private void paintInfo() {
Graphics g = this.getGraphics();
g.setColor(new Color(222, 222, 222, 4));
g.setFont(new Font("Arial Black", Font.BOLD, 15));
g.setColor(Color.BLACK);
g.drawString("test String ",this.getWidth()/2, this.getHeight()/2);
g.dispose();
}
public static void main(String[] args) {
JFrame.setDefaultLookAndFeelDecorated(true);
new Main().init();
}
}
Let's start with...
private void paintInfo() {
Graphics g = this.getGraphics();
g.setColor(new Color(222, 222, 222, 4));
g.setFont(new Font("Arial Black", Font.BOLD, 15));
g.setColor(Color.BLACK);
g.drawString("test String ",this.getWidth()/2, this.getHeight()/2);
g.dispose();
}
Isn't how painting is done in Swing and disposing of a Graphics context you didn't create will lead to manner of strange things...
Instead, create your frame, set up it's transparency and then add another component to it, which does the actual painting that you want, for example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.GridBagLayout;
import java.awt.LinearGradientPaint;
import java.awt.Point;
import java.awt.Rectangle;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
/**
*
* #author swhitehead
*/
public class JavaApplication233 {
/**
* #param args the command line arguments
*/
public static void main(String[] args) {
GraphicsEnvironment ge
= GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gd = ge.getDefaultScreenDevice();
//If translucent windows aren't supported, exit.
if (!gd.isWindowTranslucencySupported(GraphicsDevice.WindowTranslucency.PERPIXEL_TRANSLUCENT)) {
System.err.println("Per-pixel translucency is not supported");
System.exit(0);
} else {
new JavaApplication233();
}
}
public JavaApplication233() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setUndecorated(true);
frame.setBackground(new Color(0, 0, 0, 0));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setOpaque(false);
setLayout(new GridBagLayout());
add(new JLabel("I'm not wearing anything"));
// Color color = UIManager.getColor("activeCaptionBorder");
setBorder(BorderFactory.createLineBorder(Color.BLACK, 1));
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
LinearGradientPaint lgp = new LinearGradientPaint(
new Point(0, 0),
new Point(0, getHeight()),
new float[]{0f, 1f},
new Color[]{applyAlpha(Color.RED), applyAlpha(Color.YELLOW)}
);
g2d.setPaint(lgp);
g2d.fill(new Rectangle(0, 0, getWidth(), getHeight()));
g2d.dispose();
}
protected Color applyAlpha(Color color) {
return new Color(color.getRed(), color.getGreen(), color.getBlue(), 64);
}
}
}
I am using netbeans platform module to develop this desktop application. I am using drag and drop facility in netbeans in the developement.
I needed to create a toolbar which is having few buttons..I need to create a gradient color for these buttons.
I dragged and dropped JToolBar, over it I dragged and placed JButton objects.
In the properties of the button I have selected a color for which I want a shaded color. In the custom code I have modified.
jbutton = new javax.swing.Jbutton();
as below
jbutton = new javax.swing.JButton(){
#Override
protected void paintComponent(Graphics grphcs) {
Graphics2D g2d = (Graphics2D) grphcs;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
GradientPaint gp = new GradientPaint(0, 0,
getBackground().brighter().brighter().brighter(), 0, getHeight(),
getBackground().darker());
g2d.setPaint(gp);
g2d.fillRect(0, 0, getWidth(), getHeight());
super.paintComponent(grphcs);
}};
When I used the above code for a JPanel in my project it worked but it is not showing any effect when I used it for a button.
How to get a gradient color for a button placed in a toolbar?
The button has a contentAreaFilled attribute which determines if the look and feel should paint the content area of the button. When you call super.paintComponent, the look and feel delegate will paint over what you have done.
You can set this property to false and it should then work.
For example...
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.GradientPaint;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.RenderingHints;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class GradientButtons {
public static void main(String[] args) {
new GradientButtons();
}
public GradientButtons() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
frame.add(new RoundButton("Click me"));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class RoundButton extends JButton {
public RoundButton(String text) {
super(text);
setBorderPainted(false);
setContentAreaFilled(false);
setFocusPainted(false);
setOpaque(false);
}
#Override
public Dimension getPreferredSize() {
Dimension size = super.getPreferredSize();
int radius = Math.max(size.width, size.height);
size.width = radius;
size.height = radius;
return size;
}
#Override
protected void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
GradientPaint gp = new GradientPaint(0, 0,
Color.RED, 0, getHeight(),
Color.YELLOW);
g2d.setPaint(gp);
g2d.fillOval(0, 0, getWidth(), getHeight());
super.paintComponent(g);
}
}
}
You may want to check the ButtonModel's armed and/or pressed state so you can also change the way that the button is painted when clicked, as a suggestion...
I want to create a wall with a blue line outline and black filling. I have only a blue wall now and I tried a couple of the Graphics methods but wasn't working.
public void paint(Graphics g) {
g.setColor(Color.blue);
g.fillRect(x, y, size, size);
}
Use Graphics#drawRect to draw the outline: -
g.setColor(Color.black);
g.fillRect(x, y, size, size);
g.setColor(Color.blue);
g.drawRect(x, y, size, size);
First, override paintComponent, not paint. Second, there's no need to re-invent the wheel like that. Instead, use an existing Swing component (e.g. JPanel),
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
public class Main
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable(){
#Override
public void run() {
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
frame.add(getWallComponent());
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private static JPanel getWallComponent()
{
JPanel panel = new JPanel();
panel.setBackground(Color.black);
panel.setBorder(BorderFactory.createLineBorder(Color.blue, 5));
panel.setPreferredSize(new Dimension(200, 200)); // for demo purposes only
return panel;
}
}
Just paint another rectangle over the blue one, smaller than the blue one, like below
public void paint(Graphics g) {
g.setColor(Color.blue);
g.fillRect(x, y, size, size);
g.setColor(Color.black);
g.fillRect(x-width/2,y-width/x,size-width,size-with);
}
package painting;
import java.awt.*;
import javax.swing.*;
public class RectangleOutline extends JPanel {
int x = 100;
int y = 200;
public void paintComponent(Graphics g) {
super.paintComponent(g);
outline(g);
}
public void outline(Graphics g) {
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
g2.setColor(new Color(255, 0, 0));
g2.fillRect(x, y, 30, 30);
g2.setStroke(new BasicStroke(5));
g2.setColor(new Color(0, 0, 0));
g2.drawRect(x, y, 30, 30);
}
public static void main(String[] args){
JFrame f = new JFrame();
RectangleOutline graphics = new RectangleOutline();
f.add(graphics);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setVisible(true);
f.setSize(400, 400);
}
}