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());
}
Related
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 :)
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'm not that familiar with Java and I'm a little clueless about my current problem.
I'm trying to draw an Image within a separate class of my Main JFrame, but it
always draw just a little piece of the picture (maybe 10x10px).
(A test with a Label worked)
Maybe I didn't used the g.drawImage method correct, or the JPanel don't have enough space??
MainWindow:
public class Deconvolutioner extends JFrame {
Draw z;
Picturearea picturearea;
class Draw extends JPanel {
public void paint(Graphics g) {
}
}
public Deconvolutioner() {
setTitle("Deconvolutioner");
setLocation(30,1);
setSize(1300,735);
super.setFont(new Font("Arial",Font.BOLD,11));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
FlowLayout flow = new FlowLayout(FlowLayout.CENTER);
this.setLayout(flow);
picturearea = new Picturearea();
this.add(picturearea);
add(z = new Draw());
setVisible(true);
}
class Open implements ActionListener {
public void actionPerformed(ActionEvent e) {
JFileChooser fileOpen = new JFileChooser();
FileFilter filter = new FileNameExtensionFilter("png & jpg files", "png",
"jpg");
fileOpen.addChoosableFileFilter(filter);
int returnVal = fileOpen.showDialog(null, "Open file");
if (returnVal == JFileChooser.APPROVE_OPTION) {
try {
String path = fileOpen.getSelectedFile().getPath();
URL url = new File(path).toURI().toURL();
BufferedImage img = ImageIO.read(url);
picturearea.setPicture(img);
} catch (IOException ex) {
System.err.println("Some IOException accured (set the right path?): ");
System.err.println(ex.getMessage());
}
} else {
}
repaint();
}
}
And the separate class:
public class Picturearea extends JPanel {
public BufferedImage image;
Draw z;
public Picturearea() {
add(z = new Draw());
setVisible(true);
}
class Draw extends JPanel {
#Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
}
public void setPicture(BufferedImage picture) {
try {
image = picture;
} catch (Exception e) {
System.err.println("Some IOException accured (did you set the right path?): ");
System.err.println(e.getMessage());
}
repaint();
}
}
I'm grateful for every help.
thanks for your time.
You are using FlowLayout for JFrame's contentPane's layout. FlowLayout obeys component's preferredSize. Try setting preferredSize of your pictureArea by pictureArea.setPreferredSize(Dimension) or overriding getPreferredSize(Dimension) function in PictureArea class.
you are using paint(Graphics g) for custom painting:
#Override
public void paint(Graphics g) {
g.drawImage(image, 0, 0, this);
}
Do not override paint() for custom painting override paintComponent(Graphics g) instead. And You may need to scale your image to fit in the size of the JPanel. you can use g.drawImage(x, y, width, height, observer) function if you need to scale your image.
#Override
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(image, 0, 0, this);
}
I'm trying to draw over an image (with the mouse) in a JPanel, this is working, but when I try to take an screenshot of the panel and generate an image of this, I only can see the image background without drawn with the mouse.
This is my code to generate the background Panel.java
#Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(this.createImage("/imagenes/cuerpoHumano.png").getImage(), 0, 0, null);
}
This is my code to draw as a pencil over the image: Panel.java
private void formMouseDragged(java.awt.event.MouseEvent evt) {
x = evt.getX();
y = evt.getY();
this.getGraphics().setColor(Color.RED);
this.getGraphics().fillOval(x, y, 4, 4);
}
This is the code to generate an screenshot
Dimension size = panel.getSize();
BufferedImage image = (BufferedImage) panel.createImage(size.width, size.height);
Graphics g = image.getGraphics();
panel.paint(g);
g.dispose();
try {
String fileName = UUID.randomUUID().toString().substring(0, 18);
ImageIO.write(image, "jpg", new File(path, fileName + ".jpg"));
} catch (IOException e) {
e.printStackTrace();
}
When you are taking the screenshot, the paintComponent() method is called. This means it will only paint you the image. You have to store the mouse move inside some model and paint the contents of the model in the paintComponent() method. This method is triggered by calling repaint() on the panel during the mouse move.
I think this is code that works .
public class PanelImagenCuerpoHumano extends JPanel {
private int x = -1;
private int y = -1;
private Image image = null;
private ArrayList<Point> puntos = new ArrayList<Point>();
public PanelImagenCuerpoHumano() {
image = new ImageIcon(getClass()
.getResource("/imagenes/cuerpoHumano.png")).getImage();
this.addMouseMotionListener(new MouseMotionListener() {
#Override
public void mouseDragged(MouseEvent e) {
x = e.getX();
y = e.getY();
puntos.add(new Point(x, y));
repaint();
}
#Override
public void mouseMoved(MouseEvent e) {
}
});
}
#Override
protected void paintComponent(Graphics g) {
g.drawImage(image, 0, 0, null);
for (Point p : puntos) {
g.setColor(Color.red);
g.fillOval(p.x, p.y, 3, 3);
}
}
}
So in the game I'm working on, I have a marble follow the mouse, but when it does this the screen flickers.
The background includes two jpegs and 9 rectangles. How would I go about double buffering this? Here is the code for the main window.
/**
* Write a description of class Window here.
*
* #author (your name)
* #version (a version number or a date)
*/
public class Window extends JApplet implements MouseMotionListener
{
private BufferedImage image;
private BufferedImage side;
private int mouseX;
private int mouseY;
public Window(){
try {
image = ImageIO.read(new File("Backgrounds/violet.jpg"));
side = ImageIO.read(new File("Backgrounds/side margin.jpg"));
} catch (IOException ex) { }
}
private void delay(int delay)
{
try {
Thread.sleep(delay);
} catch (InterruptedException e) {}
}
public void init()
{
this.addMouseMotionListener(this);
}
public void paint (Graphics page)
{
page.drawImage(image, 0, 0, null);
page.setColor(Color.blue);
page.fillRect(0, 0, 160, 160);
page.setColor(Color.black);
page.fillRect(15, 15, 130, 130);
page.setColor(Color.green);
page.fillRect(340, 0, 160, 160);
page.setColor(Color.black);
page.fillRect(355, 15, 130, 130);
page.setColor(Color.yellow);
page.fillRect(0, 340, 160, 160);
page.setColor(Color.black);
page.fillRect(15, 355, 130, 130);
page.setColor(Color.red);
page.fillRect(340, 340, 160, 160);
page.setColor(Color.black);
page.fillRect(355, 355, 130, 130);
page.drawImage(side, 500, 0, null);
page.drawString(Score.getScore(), 560, 110);
//conveyors
page.setColor(Color.gray);
page.fillRect(235, 0, 30, 160);
//marble
delay(100);
page.fillOval(mouseX, mouseY , 40, 40);
}
public void mouseMoved(MouseEvent e)
{
mouseX = e.getX();
mouseY = e.getY();
repaint();
}
public void mouseDragged(MouseEvent e)
{
}
}
Double buffering is conceptually pretty simple, instead of drawing your objects one by one, you draw them on an image and then tell the renderer to draw that entire image. This eliminates the flickering.
Here's an example of how you might do this (source)
class DoubleBufferedCanvas extends Canvas {
public void update(Graphics g) {
Graphics offgc;
Image offscreen = null;
Dimension d = size();
// create the offscreen buffer and associated Graphics
offscreen = createImage(d.width, d.height);
offgc = offscreen.getGraphics();
// clear the exposed area
offgc.setColor(getBackground());
offgc.fillRect(0, 0, d.width, d.height);
offgc.setColor(getForeground());
// do normal redraw
paint(offgc);
// transfer offscreen to window
g.drawImage(offscreen, 0, 0, this);
}
}
Nowdays, you don't have to implement this yourself, you can use the BufferStrategy and releated classes. See lakam99's answer for an example of that .
Swing supports double buffering automatically, so you don't need to code anything.
Just call setDoubleBuffered(true) on your top-level component (typically a JPanel) and it should all work.
See: setDoubleBuffered
Another solution is to use a library that will double buffer for you. Since you are using Java2D I am assuming you want to keep everything pretty lightweight and lower level. I think Slick2D does a great job of providing simple, 2d drawing and input functions without getting in your way. It feels like a more elegant version of Java2D, but is written on OpenGL. Once you make a few applications with pure Java, I think moving to Slick2D is a GREAT idea. This is not a direct solution to your issue, but since it has already been solved I thought Id offer some advice that will make your Java game development life easier. Check it out if you get a chance http://slick.cokeandcode.com/
I think your problem is not double buffering. You must add super.paint(page); at the first line of your paint method.