I have this class, Carta, that I use to draw a card. The paint method works well on itself:
#Override
public void paintComponent(Graphics g) {
Graphics2D g2d = (Graphics2D) g;
RoundRectangle2D rect2 = new RoundRectangle2D.Double(posicio.x + CARD_WIDTH + 20,
(posicio.y * CARD_HEIGHT) + 10,
CARD_WIDTH,
CARD_HEIGHT,
CORNER_ANGLE,
CORNER_ANGLE);
g2d.setColor(Color.WHITE);
g2d.fill(rect2);
g2d.setColor(Color.black);
g2d.draw(rect2);
BufferedImage imatge = null;
if (caraAmunt) {
try {
imatge = ImageIO.read(new File(cami));
} catch (IOException ex) {
Logger.getLogger(Carta.class.getName()).log(Level.SEVERE, null, ex);
}
} else {
try {
imatge = ImageIO.read(new File(camiDefecte));
} catch (IOException ex) {
Logger.getLogger(Carta.class.getName()).log(Level.SEVERE, null, ex);
}
}
g.drawImage(imatge.getScaledInstance(CARD_WIDTH, CARD_HEIGHT, Image.SCALE_SMOOTH),
posicio.x + CARD_WIDTH + 20,
(posicio.y * CARD_HEIGHT) + 10,
null);
}
The problem I have is when trying to get to paint it on a JPanel. This is part of a larger GUI that contains a JPanel with a deck of these Cards. When I add them to the JPanel I see nothing on screen. I am instantiating a JFrame in which I have the JPanel to which I add every Card. How can I paint them inside this JPanel, say JPanel foo?
Example code
Carta foo = new Carta(SPADES, ACE, new Point(0, 0), true);
this.add(foo);
I have already solved the problem. I was painting inside the class and that did not make sense. Thanks for the replies :)
Related
I am trying to draw charts in a tab of a JTabbedPane. Each tab contains a JPanel but my code drawing charts to tab which is opened in front of me, not to constant tab.
public class Grafik extends JPanel {
public Grafik(){
try {
//this block for opening ready chart images to using in panel.
Arayuz.imageGrafikSicaklik = ImageIO.read(new FileImageInputStream(new File("Sıcaklık.png")));
Arayuz.imageGrafikBasinc = ImageIO.read(new FileImageInputStream(new File("Basınç.png")));
Arayuz.imageGrafikHiz = ImageIO.read(new FileImageInputStream(new File("Hız.png")));
Arayuz.imageGrafikYukseklik = ImageIO.read(new FileImageInputStream(new File("Yükseklik.png")));
} catch (IOException e) {
e.printStackTrace();
}
}
#Override
public void paint(Graphics g) {
super.paint(g);
g.setColor(Color.WHITE);
g.drawImage(Arayuz.imageGrafikSicaklik, 36, 16, Arayuz.imageGrafikSicaklik.getWidth(), Arayuz.imageGrafikSicaklik.getHeight(), this);
g.drawImage(Arayuz.imageGrafikBasinc, 736, 16, Arayuz.imageGrafikBasinc.getWidth(), Arayuz.imageGrafikBasinc.getHeight(), this);
g.drawImage(Arayuz.imageGrafikHiz, 36, 398, Arayuz.imageGrafikHiz.getWidth(), Arayuz.imageGrafikHiz.getHeight(), this);
g.drawImage(Arayuz.imageGrafikYukseklik, 740, 398, Arayuz.imageGrafikYukseklik.getWidth(), (Arayuz.imageGrafikYukseklik.getHeight()*1009)/1000, this);
//Arayuz.ggg = Arayuz.grafikPaneli.getGraphics();
}
public void grafikCizimSıcaklık(JPanel grafikpaneli, int startX, double instantHeat){
Graphics cizici = grafikpaneli.getGraphics();
cizici.drawLine(startX,(int) (280 - (instantHeat / 3) * 20), startX + 3, (int) (280 - (instantHeat / 3) * 20));
}
First of all while I am watching chart's Tab, everything is correct for now.
When I switch to another tab, charts will be deleted and starting to draw in that tab and that is my problem.
The first chart deleted and charts are continue in another tab which is i am watching.
I hope that I can explain my problem correctly. Thanks for everything from now.
You could use a JLabel and put the image, otherwise you should put the background image by overwriting the paintcomponent().
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
You class should extends JPanel and you need an Image:
private BufferedImage image;
try {
image = ImageIO.read(new File("HERE ADD YOUR IMG PATH));
} catch (IOException ex) {
logger.error("errorImgPath" + ex.toString());
}
I am designing a cookie clicker like game. I have a class that extends JPanel and in the constructor I load some images into an Image object. But when I go to paint them in paintComponent the console start spewing NullPointerExceptions for a few seconds then stops and the window loads properly. My only guess is that the images are taking time to load and that paintComponent is trying to paint them before they have loaded entirely. Any help is appreciated. Thanks.
public PanelClass() {
frame.setSize(screenSize);
frame.add(this);
frame.setUndecorated(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
addMouseListener(this);
addMouseMotionListener(this);
buttonGraphics.start();
try {
background = ImageIO.read(new File("res/img/Background.png")).getScaledInstance(getWidth(), getHeight(), Image.SCALE_SMOOTH);
steamLogo[0] = ImageIO.read(new File("res/img/SteamLogo.png")).getScaledInstance(getWidth()/5, getWidth()/5, Image.SCALE_SMOOTH);
for (int i = 1; i < steamLogo.length; i++) {
steamLogo[i] = steamLogo[0].getScaledInstance(steamLogo[0].getWidth(null)-(i*2), steamLogo[0].getWidth(null)-(i*2), Image.SCALE_SMOOTH);
}
} catch (IOException e) {
e.printStackTrace();
}
logoHitbox = new Ellipse2D.Double((getWidth()/2)-(steamLogo[0].getWidth(null)/2), (getHeight()/2)-(steamLogo[0].getHeight(null)/2), getWidth()/5, getWidth()/5);
}
public void paintComponent(Graphics g) {
g.drawImage(background, 0, 0, null);
g.drawImage(steamLogo[curLogo], (getWidth()/2)-(steamLogo[curLogo].getWidth(null)/2), (getHeight()/2)-(steamLogo[curLogo].getHeight(null)/2), null);
if(clicked > 1) {
g.setColor(new Color(0,0,0,155-(clicked*7)));
g.fillOval((getWidth()/2)-(steamLogo[curLogo].getWidth(null)/2), (getHeight()/2)-(steamLogo[curLogo].getHeight(null)/2), (int)steamLogo[curLogo].getWidth(null), (int)steamLogo[curLogo].getHeight(null));
}
}
I am trying to scale an image with AffineTransform. However, the image does not appear correctly when the Frame appears initially.
But after the frame is resized, the image shows perfectly.
Here is the code.
public class MainFrame extends javax.swing.JFrame {
Line line;
BufferedImage bi;
public MainFrame() {
initComponents();
try {
bi = ImageIO.read(new File("map.png"));
} catch (Exception ex) {
ex.printStackTrace();
}
}
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
AffineTransform old = g2.getTransform();
g2.scale(0.25, 0.25);
g2.drawImage(bi, 0, 0, null);
g2.setTransform(old);
}
...
}
Hello I'm getting an error drawing an image onto my frame. I'm not sure what's going wrong here.
Im getting the following error here.
Java: 77: cannot find symbol
symbol: variable image
location: class DrawComponent
g.drawImage(image, 0, 0, null);
class DrawComponent extends JComponent {
public void paintComponent(Graphics g) {
Graphics2D g2 = (Graphics2D) g;
// draw a circle with the same center
double centerX = 250;
double centerY = 180;
double radius = 20;
Ellipse2D circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX + radius, centerY + radius);
g2.setPaint(Color.RED);
g2.fill(circle);
g2.draw(circle);
String filename = "SydneyOperaHouse.jpeg";
try{
Image image = ImageIO.read(new File(filename));
}catch(IOException ex){
// Handle Exeption
}
g.drawImage(image, 0, 0, null);
}
}
Any help would be great :)
A few points.
To address the problem of the attribute scope. The image attribute should be handed to (or loaded in) the constructor and stored as a class attribute that is visible to the paint method. Never try load images (or do other potentially long running tasks) in this method.
An image for BG will typically be an embedded resource by the time of deployment, so access it by URL.
A JComponent is an ImageObserver so g.drawImage(image, 0, 0, null); should be
g.drawImage(image, 0, 0, this);
I suspect the image drawing at 0x0 should precede (be done before) drawing the red ellipse, or it will draw over the top of it.
Here is an example based on an image of Sydney (no, not the bloody opera house - fussy, fussy..).
import java.awt.*;
import java.awt.geom.Ellipse2D;
import javax.swing.*;
import javax.imageio.ImageIO;
import java.net.URL;
public class DrawComponent extends JComponent {
private Image image;
DrawComponent(Image image) {
this.image = image;
Dimension d = new Dimension(image.getWidth(this),image.getHeight(this));
this.setPreferredSize(d);
}
public void paintComponent(Graphics g) {
// always call super first, to get borders etc.
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
// paint the BG
g.drawImage(image, 0, 0, this);
// draw a circle with the same center
double centerX = 250;
double centerY = 180;
double radius = 20;
Ellipse2D circle = new Ellipse2D.Double();
circle.setFrameFromCenter(centerX, centerY, centerX + radius, centerY + radius);
g2.setPaint(Color.RED);
g2.fill(circle);
g2.draw(circle);
}
public static void main(String[] args) throws Exception {
String s = "http://pscode.org/media/citymorn1.jpg";
final Image image = ImageIO.read(new URL(s));
Runnable r = new Runnable() {
#Override
public void run() {
JComponent gui = new DrawComponent(image);
JOptionPane.showMessageDialog(null, gui);
}
};
SwingUtilities.invokeLater(r);
}
}
You simply declare your image variable in the try block... It is not visible outside it.
try{
Image image = ImageIO.read(new File(filename));
}catch(IOException ex){
// Handle Exeption
}
g.drawImage(image, 0, 0, null);
The scope of the variable image is wrong. Note that you are declaring the variable inside the try-block. The variable doesn't exist outside of the { ... } of the try-block.
Declare the variable outside the try-block:
Image image = null;
try {
image = ImageIO.read(new File(filename));
} catch(IOException ex) {
// Handle Exeption
}
if (image != null) {
g.drawImage(image, 0, 0, null);
}
By the way, you should not be doing I/O inside the paintComponent method. It's better to load the image somewhere else (when the application starts up, for example), store it in a member variable, and use it inside the paintComponent method.
When you load the image in the paintComponent method, it's going to load it every time the component needs to be painted. This will make your application slow.
What would you expect here in the case of an exception ?
String filename = "SydneyOperaHouse.jpeg";
try{
Image image = ImageIO.read(new File(filename));
}catch(IOException ex){
// Handle Exeption
}
g.drawImage(image, 0, 0, null);
You should declare/initalise and draw within the try{} block.
Ive got a JFrame and set the LayoutManager to BorderLayout and then proceeded to add my JLabel with an image. However when i resize the frame the JLabel doesnt resize. I have not added any components to North, S, E and so on. I was hoping to simply have the image inside the label fill up the entire frame leaving my menu in tact of course.
Forgive me if this seems arrogant, but I have nothing else to go on.
I did a quick sample
See the red line around the image, that's the JLabel's border. As you can see, the label is been re-sized to fill the entire area.
This is the code I used to produce the sample
public class LayoutFrame extends JFrame {
public LayoutFrame() throws HeadlessException {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
Image image = null;
URL url = getClass().getResource("/layout/issue78.jpg");
try {
image = ImageIO.read(url);
} catch (IOException ex) {
ex.printStackTrace();
}
JLabel label = new JLabel(new ImageIcon(image));
label.setHorizontalAlignment(JLabel.CENTER);
label.setVerticalAlignment(JLabel.CENTER);
label.setBorder(new LineBorder(Color.RED, 4));
setLayout(new BorderLayout());
add(label);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException ex) {
} catch (InstantiationException ex) {
} catch (IllegalAccessException ex) {
} catch (UnsupportedLookAndFeelException ex) {
}
LayoutFrame frame = new LayoutFrame();
frame.setSize(200, 200);
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
Obviously, you'll need to supply your own image ;).
Don't forget, the label WON'T scale the content for you, if that's your goal, you'll need to implement your own component to achieve this.
If you're still having problems, I would suggest (in the absence of further evidence) that your label may not be in the container you think it is or the containers layout manager is not what you think it is.
UPDATE
I don't know why you're having issues with components going missing or issues with you menu. Are mixing heavy and light weight components??
Sample with menu bar
After reading your question a little closer, I've devised a simple resizing image pane sample. For speed, I've relied on my libraries, but it should be reasonably easy to implementation your own code in place of my calls
public class ImagePane extends JPanel {
protected static final Object RESIZE_LOCK = new Object();
private BufferedImage image;
private BufferedImage scaledImage;
private Timer resizeTimer;
public ImagePane() {
URL url = getClass().getResource("/layout/issue78.jpg");
try {
image = ImageIO.read(url);
} catch (IOException ex) {
ex.printStackTrace();
}
resizeTimer = new Timer(250, new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
// Simple thread factory to start a slightly lower
// priority thread.
CoreThreadFactory.getUIInstance().execute(new ResizeTask());
}
});
resizeTimer.setCoalesce(true);
resizeTimer.setRepeats(false);
}
#Override
public void setBounds(int x, int y, int width, int height) {
super.setBounds(x, y, width, height);
resizeTimer.restart();
}
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
if (scaledImage != null) {
// This simply returns a rectangle that takes into consideration
//the containers insets
Rectangle safeBounds = UIUtilities.getSafeBounds(this);
System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth());
int x = ((safeBounds.width - scaledImage.getWidth()) / 2) + safeBounds.x;
int y = ((safeBounds.height - scaledImage.getHeight()) / 2) + safeBounds.y;
g2d.drawImage(scaledImage, x, y, this);
}
}
protected class ResizeTask implements Runnable {
#Override
public void run() {
synchronized (RESIZE_LOCK) {
if (image != null) {
int width = getWidth();
int height = getHeight();
System.out.println("width = " + width);
System.out.println("height = " + height);
// A simple divide and conquer resize implementation
// this will scale the image so that it will fit within
// the supplied bounds
scaledImage = ImageUtilities.getScaledInstanceToFit(image, new Dimension(width, height), ImageUtilities.RenderQuality.High);
System.out.println("scaledImage = " + scaledImage.getWidth() + "x" + scaledImage.getWidth());
repaint(); // this is one of the few thread safe calls
}
}
}
}
}
Best option is to sub class ImageIcon and override its paintIcon method to simply paint the image using the Graphics.paint( x, y, width, height ...).