Use graphics2d object outside paintComponent method? - java

My code:
public class YesOrNo{
Graphics g;
public void createAndShowGui() {
JPanel x=new JPanel(){
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
}
}
}
public void drawARectangle(){
g.drawRect(10, 10, 50, 50);
}
}
I know I can call a method inside paintComponent and pass g to it as parameter, but can you do it without calling that method inside paintComponent?

Related

Is it possible to write paint on screen program in java/swing?

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.

How can I fix this NullPointerException when trying to render on a JPanel with Graphics2D? [duplicate]

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.

Graphics2D is returning "NULL" always

graphics2D is returning "NULL" always in below code. Due to that putPixel() method is not being called. I am calling PictureBox from form design.
public class PictureBox extends JPanel {
Graphics2D graphics2D;
static BufferedImage image;
int imageSize = 300;
public PictureBox(){
setDoubleBuffered(false);
this.setBorder(UIManager.getBorder("ComboBox.border"));
this.repaint();
}
public void paintComponent(Graphics g){
super.paintComponent(g);
if(image == null){
image = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_RGB);
graphics2D = (Graphics2D)image.createGraphics();
graphics2D.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
clear();
}
Graphics2D g2D = (Graphics2D) g;
g2D.drawImage(image, 0, 0, this);
repaint();
}
public final void putPixel(int x, int y, Color color) {
if(graphics2D != null){
graphics2D.setColor(color);
graphics2D.drawLine(x, y, x, y);
repaint();
}
}
public void clear() {
graphics2D.setPaint(Color.WHITE);
graphics2D.fillRect(0, 0, imageSize,imageSize);
repaint();
}
}
putPixel method is being called from main where i have (x,y) coordinate stored in Point2D array.
Since you have called putPixel from outside the class and you have not initialised the graphics2D and image in the constructor it may be that when you all calling putPixel method the class may not have been displayed. So you are getting graphics2D to be null as it initialises only when the paintComponent is called and it is called when this class gets displayed.
The solution could be that you shift the initialisation code for the image and graphics2D to the constructor so that you do not encounter null while calling putPixel.
NOTE
You have indiscriminately called the method repaint(). You should keep in mind that repaint() calls paint() method which in turn calls paintComponent() method. So if you call repaint() inside paintComponent() method, you run into the risk of creating an infinite loop. Here you have called it twice once in paintComponent and again in clear method which is called by paintComponent.

How to create a Graphics2D instance?

What's the easiest way in Java SE 7 to obtain an instance just to plot a few points for debugging? Desktop environment.
You could use a BufferedImage:
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
Graphics2D graphics2D = image.createGraphics();
The easiest and safest way is to use to cast the Graphics reference in paintComponent and cast it as needed. That way the Object is correctly initialized. This reference can be passed to other custom painting methods as required.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D)g;
...
}
You should probably just create a JPanel and paint on it.
public class MyPanel extends JPanel {
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
.... // my painting
}
}

Transparency in Java

I've been using the new com.sun.awt.AWTUtilities class and am intrigued. I got com.sun.awt.AWTUtilities/setWindowOpacity(java.awt.Window window, float f) to work perfectly, but am now wondering if there is any way to change the opacity of an individual component, such as a javax.swing.JInternalFrame or javax.swing.JButton.
Try this:
class TransparentButton extends JButton {
public TransparentButton(String text) {
super(text);
setOpaque(false);
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g.create();
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.5f));
super.paint(g2);
g2.dispose();
}
}

Categories