I am trying to code a board game in Java.
I have the board which is an image and the pawns which are shapes (for example a rectangle). I want the board to be the background in the JFrame and the pawns to be over the board. I have tried multiple times but either the board covers the shape or only the shape appears. I could join the shape with the image..and create a new image but this is not what i want. Any ideas?
public class Board extends JPanel {
#Override
public void paintComponent(Graphics g) {
try {
BufferedImage img = ImageIO.read(new File("C:\\Users\\i\\Desktop\\j.png"));
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
}catch (IOException ex) {
Logger.getLogger(Board.class.getName()).log(Level.SEVERE, null, ex);
}
}
}
And my other class
public class GameGUI extends javax.swing.JFrame {
public GameGUI() {
Board b=new Board();
setContentPane(b);
setSize(600,600);
setTitle("gui");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
}
}
The class for the player
public class Player extends JPanel{
int xPos = 100, yPos = 100, vwidth = 100, vheight = 100;
Rectangle r = new Rectangle(xPos, yPos, vwidth, vheight);
public Player(){ .....}
#Override
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
super.paintComponent(g);
g.setColor(Color.black);
if (fill) {
g.fillRect((int) r.getX(), (int) r.getY(), (int) r.getWidth(), (int) r.getHeight());
}
g2.draw(r);
}
}
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.
I'm trying to get my Jframe to match my image dimensions exactly, so that when i attempt to get the Rectangle2D co-ordinates of an area via drawing a rectangle, it's give me the true co-ordinates of where it would appear on the actual image.
The objective with this solution is to convert a PDF to a image, identify a particular area using the visual mapper and then use PDFBox (PDFTextStripperbyArea) to extract against this area.
The co-ordinates being given by the below code is not extracting the required area's.
This is the code:
public class PDFVisualMapper extends JFrame {
BufferedImage image = null;
public static void main(String[] args) throws IOException {
new PDFVisualMapper();
}
public PDFVisualMapper() throws IOException {
this.setSize(1700, 2200);
this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
this.add(new PaintSurface(), BorderLayout.CENTER);
this.setVisible(true);
}
private class PaintSurface extends JComponent {
ArrayList<Shape> shapes = new ArrayList<Shape>();
Point startDrag, endDrag;
public PaintSurface() throws IOException {
image = ImageIO.read(new File("C:\\Users\\Rusty\\Desktop\\temp\\Test_PDF-1.png"));
if ( image != null ) {
Dimension size = new Dimension(image.getWidth(null), image.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setSize(size);
setLayout(null);
}
this.addMouseListener(new MouseAdapter() {
public void mousePressed(MouseEvent e) {
startDrag = new Point(e.getX(), e.getY());
endDrag = startDrag;
repaint();
}
public void mouseReleased(MouseEvent e) {
Shape r = makeRectangle(startDrag.x, startDrag.y, e.getX(), e.getY());
shapes.add(r);
startDrag = null;
endDrag = null;
repaint();
}
});
this.addMouseMotionListener(new MouseMotionAdapter() {
public void mouseDragged(MouseEvent e) {
endDrag = new Point(e.getX(), e.getY());
repaint();
}
});
}
private void paintBackground(Graphics2D g2) {
g2.setPaint(Color.LIGHT_GRAY);
for (int i = 0; i < getSize().width; i += 10) {
Shape line = new Line2D.Float(i, 0, i, getSize().height);
g2.draw(line);
}
for (int i = 0; i < getSize().height; i += 10) {
Shape line = new Line2D.Float(0, i, getSize().width, i);
g2.draw(line);
}
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
paintBackground(g2);
Color[] colors = { Color.YELLOW, Color.MAGENTA, Color.CYAN, Color.RED, Color.BLUE, Color.PINK };
int colorIndex = 0;
g2.drawImage(image, null, 0, 0);
g2.setStroke(new BasicStroke(2));
g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.50f));
for (Shape s : shapes) {
g2.setPaint(Color.BLACK);
g2.draw(s);
g2.setPaint(colors[(colorIndex++) % 6]);
g2.fill(s);
}
if (startDrag != null && endDrag != null) {
g2.setPaint(Color.LIGHT_GRAY);
Shape r = makeRectangle(startDrag.x, startDrag.y, endDrag.x, endDrag.y);
g2.draw(r);
System.out.println(r.getBounds2D());
}
}
}
private Rectangle2D.Float makeRectangle(int x1, int y1, int x2, int y2) {
return new Rectangle2D.Float(Math.min(x1, x2), Math.min(y1, y2), Math.abs(x1 - x2), Math.abs(y1 - y2));
}
}
Can anybody help?
This might be simpler: using a JLabel within the contentpane, using FlowLayout:
import java.awt.FlowLayout;
import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
public class WarpImage {
public static void main(String[] args) throws IOException {
displayImage();
}
private static void displayImage() throws IOException{
URL url = new URL("http://www.digitalphotoartistry.com/rose1.jpg");
BufferedImage image = ImageIO.read(url);
ImageIcon icon= new ImageIcon(image);
JFrame frame=new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new FlowLayout());
JLabel lbl= new JLabel();
lbl.setIcon(icon);
frame.add(lbl);
frame.pack();
//check size :
Rectangle bounds = lbl.getBounds();
System.out.println(bounds.getWidth() +"-"+ bounds.getHeight());
frame.setVisible(true);
}
}
I'm trying to get my Jframe to match my image dimensions exactly, so that when i attempt to get the Rectangle2D co-ordinates of an area via drawing a rectangle, it's give me the true co-ordinates of where it would appear on the actual image.
Then you paint the image yourself. Why? Because components like JLabel have their own internal layout mechanics which provide no way for you to determine the offset of the image within in, if the image is to large or to small for the component size.
Something like this, for example:
public class ImagePane extends JPanel {
private BufferedImage img;
public ImagePane(BufferedImage img) {
this.img = img;
}
#Override
public Dimension getPreferredSize() {
return img == null ? new Dimension(0, 0) : new Dimension(img.getWidth(), img.getHeight());
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
if (img != null) {
Graphics2D g2 = (Graphics2D) g.create();
g2.drawImage(img, 0, 0, this);
g2.dispose();
}
}
}
This places the image in the top left corner of the component, so if it's resized for some reason, the image will always be in the top left position. To be frank, it wouldn't be hard to generate an offset to allow the image to be centred, this could then be used by decedents of the component to calculate the offset required to adjust their own output as needed
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 am currently having lots of difficulty in one of my assignments. The task for this assignment is to create an aviation radar, VOR, with java's GUI features. When the user presses either the left/right arrow on their keyboard, the circular radar should rotate, and a needle in the middle of the radar should move left/right.
I am very close to finishing, but I am stuck on one part. I drew an image of the radar, and I attempted to draw a line on top of it. However, I was only successful when I was able to make all JPanels transparent. This causes a problem because it is difficult to see what I drew on top of it.
So, my question is, how would I draw it on top of the radar image without making everything transparent? Below is my code
public class finalVORGUI extends JPanel{
private JPanel rotationPanel;
private JPanel needle;
private JPanel attributes;
private int degrees;
private String CurrentRadial;
private int x;
private int y1;
private int y2;
final int WIDTH = 600;
final int HEIGHT = 600;
private ImageIcon radar = new ImageIcon("image/vor1.png");
/**
* The constructor for the class
* It's going to set the dimension of the program to 600x600, the
* background is going to be white (in order to blend in with the
* vor image), and it is going to add in the VOR radar and a radial
* indicator that will let the user know which radial he/she is on
*/
public finalVORGUI(){
JLayeredPane lp = new JLayeredPane();
lp.setPreferredSize(new Dimension(WIDTH, HEIGHT));
setBackground(Color.white);
lp.setLayout(null);
lp.setFocusable(true);
lp.addKeyListener(new KeyboardListener());
rotationPanel = new JPanel();
rotationPanel = new TurningCanvas();
needle = new JPanel();
needle = new DrawNeedle();
attributes = new JPanel();
attributes = new DrawAttributes();
lp.add(rotationPanel, Integer.valueOf(1));
lp.add(needle, Integer.valueOf(2));
lp.add(attributes, Integer.valueOf(3));
needle.setBounds(100,0, needle.getPreferredSize().width, needle.getPreferredSize().height);
rotationPanel.setBounds(100, 100, rotationPanel.getPreferredSize().width, rotationPanel.getPreferredSize().height);
attributes.setBounds(100, 100, rotationPanel.getPreferredSize().width, rotationPanel.getPreferredSize().height);
add(lp);
degrees = 360; //to edit: this is going to be the radial the radar is currently facing
x = 172; //x is the location of the needle
y1 = 155;
y2 = 330;
CurrentRadial = "Radial: " + degrees; //A string that is always going to be above the radar. it's going to let the user know the current radial
}
public void paintComponent(Graphics g){
super.paintComponent(g);
g.drawString(CurrentRadial, 250, 100);
}
public class DrawAttributes extends JPanel{
public DrawAttributes(){
setOpaque(false);
add(new Attributes());
}
public class Attributes extends JPanel{
int w = 500;
int h = 400;
public Attributes(){
setPreferredSize(new Dimension(w,h));
setBackground(Color.white);
}
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
g2.drawString("To",300,400);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.3f));
g2.setStroke(new BasicStroke(3));
super.paintComponent (g);
g2.dispose();
}
}
}
public class DrawNeedle extends JPanel{ //todo: make sure this works and adds correctly to the LayeredPane
public DrawNeedle(){
setOpaque(false);
add(new Needle());
}
public class Needle extends JPanel{
int w = 500;
int h = 400;
public Needle(){
setPreferredSize(new Dimension(w,h));
setBackground(Color.white);
}
private void doDrawing(Graphics g){
Graphics2D g4 = (Graphics2D) g;
g4.drawString("TO", 190, 200);
g4.drawString("FROM",190, 300);
}
public void paintComponent(Graphics g){
Graphics2D g2 = (Graphics2D) g;
RenderingHints hints = new RenderingHints(null);
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHints(hints);
g2.setComposite(AlphaComposite.getInstance(
AlphaComposite.SRC_OVER, 0.3f));
g2.setStroke(new BasicStroke(3));
doDrawing(g);
g2.drawLine(x,y1,x,y2);
super.paintComponent (g);
g2.dispose();
}
}
}
public class TurningCanvas extends JPanel{
public TurningCanvas(){
setOpaque(false);
add(new TurningImage());
}
public class TurningImage extends JPanel{
int w = radar.getIconWidth()- 20;
int h = radar.getIconHeight() -20;
public TurningImage(){
setPreferredSize(new Dimension(w,h));
setBackground(Color.white);
}
public void paintComponent(Graphics g){
super.paintComponent (g);
Graphics2D g2 = (Graphics2D) g;
RenderingHints hints = new RenderingHints(null);
hints.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
hints.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
hints.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g2.setRenderingHints(hints);
g2.rotate (Math.toRadians(degrees),w/2, h/2);
g2.drawImage(radar.getImage(), 0, 0, this);
//g2.drawLine(171,0,x,300);
g2.dispose();
}
}
}
/**
* This is the keyboard listener that this program will be using
* Depending on what the user wishes, or what type of keyboard they have,
* they will be able to find their desired radial by using the arrow keys
* or the "a" and "d" buttons. Left arrow to minus radial, right arrow to plus radial, etc etc...
*
*/
public class KeyboardListener implements KeyListener{
public void keyPressed (KeyEvent event) {
if(event.getKeyCode() == KeyEvent.VK_LEFT){
degrees--;
x--;
if(degrees <= 0){
degrees = 360;
}
if(x <= 89){
x = 89;
}
CurrentRadial = "Radial: " + degrees;
repaint();
}
if(event.getKeyCode() == KeyEvent.VK_RIGHT){
degrees++;
x++;
if(degrees >= 360){
degrees = 1;
}
if(x >= 250){
x = 250;
}
CurrentRadial = "Radial: " + degrees;
repaint();
}
}
public void keyTyped (KeyEvent event) {}
public void keyReleased (KeyEvent event) {}
}
/**
* The main method of this class
* This is going to make a new JFrame, which will hold the new
* VOR radar
* #param args
*/
public static void main(String[] args){
finalVORGUI test = new finalVORGUI();
JFrame frame = new JFrame("VOR Radar");
frame.setContentPane(test);
frame.pack();
frame.setVisible(true);
}
}
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);
}
};