Page 1 of 2 12 LastLast
Results 1 to 20 of 21
  1. #1
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default Having difficulty adding graphics to a JPanel

    I'm adding graphics to a GUI I'm working on, and I decided to start with a simple test by putting a png image on the top-left corner of the JPanel gamedisplay. However, the image doesn't appear. Since this is just a basic test, everythin is done in the constructor. Here's the relevant code:

    Java Code:
            BufferedImage img = null;
            try {
                File f = new File("c:\\techdemogfx\\dartred.png");
                img = ImageIO.read(f);
                System.out.println(img);
    
            } catch (IOException e) {
            }
    
    ...
    
        initComponents();
    
    ...
    
            Graphics g = gamedisplay.getGraphics();
            g.drawImage(img, 0, 0, null);
    I know the png was retrieved properly from the print test, but for some reason it just isn't being drawn to the panel. Suggestions?

  2. #2
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,387
    Rep Power
    25

    Default

    Best practice is to draw on panels from the override of their paintComponent() method.
    Your code appears to be outside of that method. Try moving it inside and using the Graphics object passed to the method.

  3. #3
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    Sorry, but I'm not quite sure what you mean. I see that the JPanel class has a paintComponent() method, but I don't really see any way of changing it. Aside from that, wouldn't putting my graphics drawing code in a method that only takes a Graphics make it do the same thing every time?

  4. #4
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,387
    Rep Power
    25

    Default

    The way I described is a pretty common method. Do a search on this forum for paintComponent( and you'll see plenty of examples.
    I don't really see any way of changing it.
    You override it and insert your code inside it.
    You write logic that uses data from outside the method to control what is drawn.

  5. #5
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    Quote Originally Posted by DrKilljoy View Post
    Sorry, but I'm not quite sure what you mean. I see that the JPanel class has a paintComponent() method, but I don't really see any way of changing it. Aside from that, wouldn't putting my graphics drawing code in a method that only takes a Graphics make it do the same thing every time?
    If you use getGraphics to get the Graphics object, the Graphics object won't persist and you'll either see the graphics only temporarily or not at all -- as you're finding out. To get a stable Graphics object for drawing, you need to do as Norm suggests: override paintComponent and use the Graphics object passed to that method to do your drawing in that method. More importantly, you're going to have to unlearn some assumptions that you're holding by reading a tutorial or two on graphics coding as it is done differently from what you're used to. The sun tutorials are a good place to start.

  6. #6
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    All right, thanks, I've just about got it working. Java tutorials were actually the first things I checked out, but there was no mention of paintComponent() in them. Searching the forums and seeing an example of how it was done helped immensely, though. Just one last question: Some graphics will overlap others, so I need to set a transparent color. What's the best way to go about doing this?

  7. #7
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,387
    Rep Power
    25

    Default

    Are the overlaps something that could be controlled by changing the width or height of the items being drawn to prevent overlaps. Or by changing which is drawn first.

    Otherwise there are way to change the pixels in an image.
    I've seen recent posts on changing pixels. Try a search on pixel for code samples.

  8. #8
    al_Marshy_1981 is offline Senior Member
    Join Date
    Feb 2010
    Location
    Waterford, Ireland
    Posts
    748
    Rep Power
    5

    Default

    Images should definetely overlap depending on which is drawn first and the coordinates of where they are drawn

  9. #9
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    There's absolutely no way to avoid overlap. Because it's a grid-based game, there are going to be terrain tiles, and units which will be placed on top of those tiles. Is there an easy way to just tell Java not to draw the parts of an image that have a certain color?

  10. #10
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,387
    Rep Power
    25

    Default

    Not sure I follow. Are you saying that if two images are drawn in the same area, that you want one part of one image to be on top of another image and another part of that image to be underneath the other image. The images are blended together.

  11. #11
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    Actually, maybe it's easier if I just use an image with an example of what I want:


    The problem is, trying to do this normally causes Java to draw the spaceship with a white background included, obscuring the terrain tile. I want it to draw all of the parts of the spaceship image except the white space.

  12. #12
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,387
    Rep Power
    25

    Default

    Are the "white space" pixels transparent? Can you use a photo editor to make them transparent?
    I have no idea what the Graphic drawImage() method does with transparent pixels. Have you tried it?

  13. #13
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,316
    Blog Entries
    1
    Rep Power
    26

    Default

    You can't use an image with a white background for this but rather one with a transparent background (which do exist).

    One book I highly recommend that you get is "Filthy Rich Clients" by Haase and Guy

    For example, here is code that shows two public domain images, one with a white background and one with a transparent background:
    Java Code:
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.IOException;
    import java.net.MalformedURLException;
    import java.net.URL;
    import javax.imageio.ImageIO;
    import javax.swing.*;
    
    public class TransparentDemo {
    
       private static final String IMAGE_1 = "http://duke.kenai.com/" + "iconSized/duke.gif";
       private static final String IMAGE_2 = "http://duke.kenai.com/" + "iconSized/jws-dukeonly.gif";
    
       private static void createAndShowUI() {
          JPanel panel = new JPanel(new GridLayout(1, 0));
          panel.setPreferredSize(new Dimension(600, 300));
    
          try {
             BufferedImage image1 = ImageIO.read(new URL(IMAGE_1));
             BufferedImage image2 = ImageIO.read(new URL(IMAGE_2));
             panel.add(new TdGui(image1));
             panel.add(new TdGui(image2));
    
             JFrame frame = new JFrame("TransparentDemo");
             frame.getContentPane().add(panel);
             frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
             frame.pack();
             frame.setLocationRelativeTo(null);
             frame.setVisible(true);
          } catch (MalformedURLException e) {
             e.printStackTrace();
          } catch (IOException e) {
             e.printStackTrace();
          }
       }
    
       public static void main(String[] args) {
          java.awt.EventQueue.invokeLater(new Runnable() {
             public void run() {
                createAndShowUI();
             }
          });
       }
    }
    
    class TdGui extends JPanel {
       private static final Color COLOR_2 = Color.pink;
       private static final Color COLOR_1 = new Color(160, 160, 255);
    
       public TdGui(Image img) {
          ImageIcon icon = new ImageIcon(img);
          JLabel label = new JLabel(icon);
          setLayout(new GridBagLayout());
          add(label);
       }
    
       @Override
       protected void paintComponent(Graphics g) {
          super.paintComponent(g);
          Graphics2D g2 = (Graphics2D) g;
          Paint paint = new GradientPaint(0, 0, COLOR_1, 50, 50, COLOR_2, true);
          g2.setPaint(paint);
          g2.fillRect(0, 0, getWidth(), getHeight());
       }
    }
    Last edited by Fubarable; 07-18-2010 at 06:44 PM.

  14. #14
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,229
    Rep Power
    19

    Default

    Or if for any reason you can't edit the image files to replace the background color with transparency, you can use a custom RGBImageFilter to convert any one color to transparent. Sample code here:
    How to make a color transparent in a BufferedImage and save as PNG - Stack Overflow

    db

  15. #15
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    Thanks to everybody who's replied!

    Fubarable - the book you recommended looks pretty useful, and I think it could clear up a lot of the difficulties I'm having. I'm unfortunately unemployed now, but once i have some money I'll have to see about buying it.

    Darryl Burke - Thanks for the find! This is definitely the best approach for me to use. I do, however, have just one question. The provided method is used to transform gray to transparency, while I need to transform white to transparency. The obvious line to edit to do this is:

    Java Code:
    return (rgb << 8) & 0xFF000000;
    which contains mostly things I haven't encountered before. These look like binary operators, and reading about them gave me a basic idea of what they do, but I can't really see how they relate to which color is changed.

    I realize I may be in a bit over my head with this, but once this section is figured out, I'll be able to easily handle the rest of the program.

  16. #16
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,387
    Rep Power
    25

    Default

    (rgb << 8) & 0xFF000000
    If the int contains 4 bytes: ARGB, the shift left would toss the A and put the R in the leftmost byte. Then the & would set the rightmost 3 bytes to 0 leaving what was the R byte in the leftmost byte (the A position).
    No idea why the code would want to move the R byte to the A byte

  17. #17
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    Success! I've got transparent images now!

    Thanks, guys. You've really helped me get this project off the ground!

  18. #18
    DrKilljoy is offline Member
    Join Date
    Jun 2010
    Posts
    28
    Rep Power
    0

    Default

    Damn! Ran into one last problem! I'd really appreciate it if I could get this last bit of help...

    I did a test involving moving the cursor around the map, to make sure the map would show the cursor moving. I thought the best way to do this would be, in the paintComponent(); method, making a thread containing a continuous loop that draws graphics depending on the contents of a string, then kicking off the thread with the .start command. The problem is that nothing inside the thread gets drawn! Line printing tests tell me the code is getting read and executed, but the images don't appear. If this seems like an odd way of doing things, this is because I had first tried, in order:

    -Just putting a collection of if statements in paintComponent(), which draw different things depending on the value of a string (Only the initial map gets drawn)
    -Making a graphics object as a global variable, then using the contents of paintComponent() to copy its graphics object to the global variable, then having other methods do the drawing with said global variable (Nothing gets drawn)
    -Trying the while loop without the thread (Infinite loop. Dumb, I know, but I was getting frustrated by this point)

    I can't think of what else to do. What is causing this method to execute, and how can I get it to do what I want it to, when I want it?

  19. #19
    Norm's Avatar
    Norm is offline Moderator
    Join Date
    Jun 2008
    Location
    SW Missouri
    Posts
    17,387
    Rep Power
    25

    Default

    You need to tell the Swing EDT/GUI control thread to call you paintComponent() method when you want something new drawn. That's done by calling the repaint() method.

    Compute some new coordinates to drawn and then call repaint(). Some time later paintComponent() will be called to draw those new things.

  20. #20
    DarrylBurke's Avatar
    DarrylBurke is offline Member
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,229
    Rep Power
    19

    Default

    I thought the best way to do this would be, in the paintComponent(); method, making a thread containing a continuous loop that draws graphics depending on the contents of a string, then kicking off the thread with the .start command.
    Terrible idea. For one, you have no control over how many times and how often paintComponent will be called, so you could end up with many many threads in just a short time. For another, all painting should always be done on the EDT.

    I recommend that you go through the Sun Swing tutorials on Concurrency in Swing and Performing Custom Painting.

    db

Page 1 of 2 12 LastLast

Similar Threads

  1. Jpanel and displaying graphics
    By jdsflash in forum New To Java
    Replies: 6
    Last Post: 11-21-2009, 01:14 AM
  2. Clear Graphics Objects from Jpanel
    By DavidG24 in forum AWT / Swing
    Replies: 2
    Last Post: 05-20-2009, 09:34 PM
  3. Newbie need help on JPanel graphics
    By junpogi in forum AWT / Swing
    Replies: 7
    Last Post: 10-21-2008, 07:44 AM
  4. adding a jpanel in the middle of the script
    By 2o2 in forum AWT / Swing
    Replies: 11
    Last Post: 10-12-2008, 05:50 PM
  5. Adding graphics to array
    By romina in forum Java 2D
    Replies: 1
    Last Post: 08-01-2007, 01:45 AM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •