I have been banging my head since morning on a a Jlabel issue; I would like to have an round image instead of the normal rectangular image for a label as shown in the image below.
I have tried overriding paintComponent in the label but the image would not display at all. I have not found a very concrete answer on previous SO posts. Your help is welcome. Thanks in advance.
My code is as below:
jLabelPic = new javax.swing.JLabel(){
BufferedImage image= null;
private Ellipse2D.Double border = new Ellipse2D.Double();
private int width=140, height=140;
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
try {
image= ImageIO.read(getClass().getResource("/resources/image.jpg"));
} catch (IOException ex) {
ex.printStackTrace();
}
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setPaint(Color.RED);
g2d.fillRect(0, 0, width, height);
border.setFrame(0, 0, width, height);
g2d.setClip(border);
g2d.drawImage(image, 0, 0, width, height, this);
}
};
Related
I'm writing paint on screen program using Java Swing. It working on ubuntu linux. But windows shows black screen instead of transparent panel. I included similar example code. What is wrong in my code?
import javax.swing.*;
import java.awt.*;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
public class Example {
public static final Color COLOR_TRANSPARENT = new Color(0,0,0,0);
public Example() {
Canvas drawArea = new Canvas();
drawArea.setBackground(COLOR_TRANSPARENT);
drawArea.setOpaque(true);
JWindow drawingFrame = new JWindow();
drawingFrame.setBackground(COLOR_TRANSPARENT);
drawingFrame.setContentPane(drawArea);
drawingFrame.pack();
drawingFrame.setSize(640, 460);
drawingFrame.setVisible(true);
drawingFrame.setLocationRelativeTo(null);
drawingFrame.setAlwaysOnTop(true);
}
public static void main(String[] args){
SwingUtilities.invokeLater(Example::new);
}
class Canvas extends JPanel{
private Image image;
private Graphics2D g2;
public Canvas() {
super();
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
int x = e.getX();
int y = e.getY();
g2.setPaint(Color.RED);
g2.fillOval(x-10, y-10, 20, 20);
repaint(x-10, y-10, 20, 20);
}
});
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (image == null){
image = createImage(getWidth(), getHeight());
g2 = (Graphics2D) image.getGraphics();
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setBackground(COLOR_TRANSPARENT);
clear();
}
Graphics2D g2 = (Graphics2D) g;
g2.drawImage(image, 0,0, null);
}
public void clear(){
System.out.println("clearing canvas ");
g2.setComposite(AlphaComposite.Clear);
g2.setBackground(COLOR_TRANSPARENT);
g2.setColor(COLOR_TRANSPARENT);
g2.fillRect(0, 0, getWidth(), getHeight());
g2.clearRect(0, 0, getWidth(), getHeight());
g2.setPaint(Color.RED);
g2.setComposite(AlphaComposite.SrcOver);
repaint();
}
}
}
Here is screenshot what I wanted.
Example code updated. Now code should work without any other additional code.
For windows I made a couple of changes:
image = createImage(getWidth(), getHeight());
image = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
I used a BufferedImage to you can set the alpha values of the image to be transparent.
//public static final Color COLOR_TRANSPARENT = new Color(0,0,0,0);
public static final Color COLOR_TRANSPARENT = new Color(0,0,0,1);
I made the alpha value non-zero, because a value of zero means the Java application won't receive the MouseEvent because it is passed to the application under the window.
This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 6 years ago.
I've been trying to make a shop for my game.
This has been unsuccessful.
I've tried drawComponent, didn't work.
No errors, code executed, but didn't work.
Now i'm trying to do:
private void render() {
Graphics2D g = (Graphics2D) graphics.getGraphics();
/////////////////////
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
/////////////////////
g.dispose();
Graphics2D g2d = (Graphics2D) getGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
}
Now i get a NullPointerException on g2d.
I've tried everything.
`Exception in thread "game" java.lang.NullPointerException
at com.johnythecarrot.game.Shop$DrawPane.access$2(Shop.java:123)
at com.johnythecarrot.game.Shop.render(Shop.java:154)
at com.johnythecarrot.game.Game.render(Game.java:75)
at com.johnythecarrot.game.Game.run(Game.java:112)
at java.lang.Thread.run(Unknown Source)`
My goals are to be able to have clickable buttons.
It DID work. But i had to restart almost everytime. Because mostly of the time to code wasn't even executed. So i tried to fix it. Now it's all messed up.
This is the code to it.
(DoubleInt is a part of my library it's nothing more than just x and y. )
public class Shop {
public BuildWindow window;
public static JWindow w;
private int WIDTH = 860, HEIGHT = 440;
private BufferedImage graphics = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
public DrawPane drawPane;
public Shop() {
//window = new BuildWindow().setSize(new DoubleInt(100, 100)).at(wi, he).setTitle("Shop").setOpacity(1).setDragable(false).showEmpty(true);
w = new JWindow();
w.setOpacity(1);
w.setSize(WIDTH, HEIGHT);
w.setLocation(800, 800);
w.setVisible(false);
w.setAlwaysOnTop(true);
//graphics = new BufferedImage(WIDTH, HEIGHT, BufferedImage.TYPE_INT_RGB);
}
private void createShop() {
/***Graphics2D g = (Graphics2D) graphics.getGraphics();
g.setColor(Color.blue);
g.drawString("hey", WIDTH-50, HEIGHT-50);
g.fillRect(0, 0, WIDTH, HEIGHT);*/
}
public class DrawPane extends JPanel {
int width = WIDTH;
int height = HEIGHT;
private ArrayList<Shape> buttons;
private Shape btn1 = new Rectangle2D.Double(20, 60, width/2, height-20);
private Shape btnClose = new Rectangle2D.Double(width-25, 5, 20, 20);
Point wCoords;
Point mCoords;
public DrawPane() {
buttons = new ArrayList<>();
buttons.add(btn1);
buttons.add(btnClose);
addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
super.mouseClicked(e);
for(Shape s : buttons) {
if(s.contains(e.getPoint())) {
System.out.println("Clicked " + s.getBounds());
if(s == btnClose) {
w.dispose();
}
}
}
}
#Override
public void mousePressed(MouseEvent e) {
mCoords = e.getPoint();
}
#Override
public void mouseReleased(MouseEvent arg0) {
mCoords = null;
}
});
addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
wCoords = e.getLocationOnScreen();
w.setLocation(wCoords.x - mCoords.x, wCoords.y - mCoords.y);
}
});
}
void repaintThis() {
repaint();
}
BufferedImage img = loadImageFrom.LoadImageFrom(Shop.class, "bar.png");
Graphics gb;
/**
* super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.red);
//g.fillRect(0, 0, width, 50);
g.drawImage(img, 0, 0, width, 50, null);
g.setColor(Color.WHITE);
g.drawString("SHOP", 15, 30);
g.drawString("X", width-20, 20);
for(Shape b : buttons) {
g2d.draw(b);
}
System.out.println("Built");
gb = g;
*/
private void render() {
Graphics2D g = (Graphics2D) graphics.getGraphics();
/////////////////////
g.drawImage(img, 0, 0, WIDTH, HEIGHT, null);
/////////////////////
g.dispose();
Graphics2D g2d = (Graphics2D) getGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
}
public void Build() {
Graphics g = gb;
Graphics2D g2d = (Graphics2D) g;
g.setColor(Color.red);
//g.fillRect(0, 0, width, 50);
g.drawImage(img, 0, 0, width, 50, null);
g.setColor(Color.WHITE);
g.drawString("SHOP", 15, 30);
g.drawString("X", width-20, 20);
for(Shape b : buttons) {
g2d.draw(b);
}
System.out.println("Built");
}
}
public void render(Graphics2D g) {
drawPane.render();
}
public void addDrawPane() {
drawPane = new DrawPane();
w.add(drawPane);
}
}
If you need access to more code, just ask me.
You should override the paintComponent method like this:
public class DrawPane extends JPanel {
// all your variables and other things
#Override
paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
// Your code goes here, use the g2d
}
}
then if you need to repaint your component, simply call repaint() on it.
I want to set the transparent text color of JTextField, means the color of the text on JTextField should be same as that of JFrame on which JTextField is added. Please tell how can I do this?
This is possibly a massive overkill, but as I understand the question, essentially, what this does is makes the text "transparent" or appear "cut out" of the text field...
public class CutoutTextField extends JTextField {
public CutoutTextField() {
init();
}
public CutoutTextField(String text) {
super(text);
init();
}
public CutoutTextField(int columns) {
super(columns);
init();
}
public CutoutTextField(String text, int columns) {
super(text, columns);
init();
}
public CutoutTextField(Document doc, String text, int columns) {
super(doc, text, columns);
init();
}
protected void init() {
setOpaque(false);
}
#Override
protected void paintComponent(Graphics g) {
TextUI ui = getUI();
// This is JUST the text
BufferedImage img = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
Graphics2D ig = img.createGraphics();
applyQualityRenderingHints(ig);
ui.paint(ig, this);
ig.dispose();
// This is the background of the field...
BufferedImage bg = new BufferedImage(getWidth(), getHeight(), BufferedImage.TYPE_INT_ARGB);
ig = bg.createGraphics();
applyQualityRenderingHints(ig);
ig.setColor(getBackground());
ig.fillRect(0, 0, getWidth(), getHeight());
ig.dispose();
BufferedImage masked = ImageUtilities.applyMask(img, bg, AlphaComposite.XOR);
int y = (getHeight() - masked.getHeight()) / 2;
g.drawImage(masked, 0, y, this);
}
public BufferedImage applyMask(BufferedImage sourceImage, BufferedImage maskImage, int method) {
BufferedImage maskedImage = null;
if (sourceImage != null) {
int width = maskImage.getWidth(null);
int height = maskImage.getHeight(null);
maskedImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D mg = maskedImage.createGraphics();
applyQualityRenderingHints(mg);
int x = (width - sourceImage.getWidth(null)) / 2;
int y = (height - sourceImage.getHeight(null)) / 2;
mg.drawImage(sourceImage, x, y, null);
mg.setComposite(AlphaComposite.getInstance(method));
mg.drawImage(maskImage, 0, 0, null);
mg.dispose();
}
return maskedImage;
}
public 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);
}
}
Understand, this is a massive hack!
What this basically does, is paints the text from field to a BufferedImage, it then generates a separate BufferedImage filled with the background color of the field and then XOR's the two images together, effectively cutting the text out of the background. It then simply paints the resulting BufferedImage.
Some will note that I've not called super.paintComponent, this is done deliberately as I don't want the field to paint the background AND text but want to take control over the process.
It's possible, because the field is transparent, that I could call super.paintComponent, but I'd be painting to one of the BufferedImages any way...
I want to set the background of the JDesktopPane (I add this JDesktopPane directly from the palette into the JFrame)
I try to override the method public void paintComponent (Graphics g) but it's not working
Here is the code:
JDesktop p = new JDesktop();
ImageIcon icon = new ImageIcon("images/Nénuphars6892.jpg");
final Image img = icon.getImage();
img.getScaledInstance(159, 207, Image.SCALE_SMOOTH);
p.principal = new JDesktopPane() {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
g2d.drawImage(img, 0, 0, getSize().width, getSize().height, this);
}
};
p.setVisible(true);
I resolve this problem by adding that on the creation of the JDesktopPane choosing customize code (variable principal) :
principal = new javax.swing.JDesktopPane()
{
ImageIcon icon = new ImageIcon("images/blue_digital_waves_abstract.jpg");
Image image = icon.getImage();
Image newimage = image.getScaledInstance(1500, 1000, Image.SCALE_SMOOTH);
#Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(newimage, 0, 0, this);
}
}
;
JDesktopPane desktopPane = new JDesktopPane() {
private final ImageIcon image = new ImageIcon("sample.jpg");;
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
int x = (desktopPane.getWidth() - image.getIconWidth()) / 2;
int y = (desktopPane.getHeight() - image.getIconHeight()) / 2;
g.drawImage(image.getImage(), x, y, this);
}
};
My small Java program is trying to darken a png image. It's working fine on my Mac but when I try to run it on a Windows PC with java 1.7_07 installed but it doesn't show anything at all except an empty JPanel, the image is completely disappeared.
Here is the code:
class MapCanvas extends JPanel {
private Color color;
RescaleOp op;
BufferedImage sourceImage, bi;
public MapCanvas() {
try {
sourceImage = ImageIO.read(new File(MAP_FILENAME));
bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
op = new RescaleOp(.8f, 0, null);
bi = op.filter(bi, null);
Graphics2D g = bi.createGraphics();
g.drawImage(sourceImage, 0, 0, 500, 382, null);
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
// set size for the panel
Dimension size = new Dimension(500, 382);
this.setBackground(new Color(34, 102, 187));
setPreferredSize(size);
setSize(size);
setLayout(null);
}
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.drawImage(bi, op, 0, 0);
}
}
Anyone know why I'm getting this? Many thanks.
I don't seem to have any issues, BUT, several things jump out at me about this example...
Firstly, I don't see why you've done this...
try {
sourceImage = ImageIO.read(new File("C:/Users/shane/Dropbox/issue453.jpg"));
bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
op = new RescaleOp(.1f, 0, null);
bi = op.filter(bi, null);
Graphics2D g = bi.createGraphics();
g.drawImage(sourceImage, 0, 0, 500, 382, null);
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
Then done this...
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.drawImage(bi, op, 0, 0);
}
You're basically double apply the RescaleOp.
It could simply just apply the RescaleOp directly to the sourceImage...
public void paintComponent(Graphics g) {
super.paintComponent(g);
g2d = (Graphics2D) g;
g2d.drawImage(sourceImage, op, 0, 0);
}
Unless you're concerned about performance, in which case you should simple draw the bi without any BufferedImageOp
g2d.drawImage(bi, 0, 0, this);
Secondly, your example won't compile because you've not defined g2d in your paintComponent method. This is either an oversight (which is fine) OR you are caching the Graphics object, which is not fine.
Graphics objects are stateless, they do not persist between repaints, you should NEVER cache them or rely on getGraphics.
Thank you for pointing out my mistakes. There is some missing code in my question (the Graphics2D g2d - it's just an unassigned variable) so it doesn't compile. Sorry about that.
This is how I fixed it:
`sourceImage = ImageIO.read(new File(MAP_FILENAME));
bi = new BufferedImage(sourceImage.getWidth(), sourceImage.getHeight(), BufferedImage.TYPE_INT_ARGB);
float[] scales = { .5f, .5f, .5f, 1f };
float[] offsets = new float[4];
op = new RescaleOp(scales, offsets, null);
Graphics2D g1 = bi.createGraphics();
g1.drawImage(sourceImage, 0, 0, 500, 382, null);
g1.dispose();
op.filter(sourceImage, bi);`
I just use the same value for RGB in the scales array (that's how it supposed to be) then draw the filtered image.
`g2d.drawImage(bi, 0, 0, 500, 382, null);`
Cheers