Results 1 to 20 of 21
- 07-15-2010, 11:36 PM #1
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
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);
- 07-15-2010, 11:57 PM #2
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.
- 07-16-2010, 03:42 AM #3
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
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?
- 07-16-2010, 03:46 AM #4
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 write logic that uses data from outside the method to control what is drawn.
-
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.
- 07-17-2010, 04:14 AM #6
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
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?
- 07-17-2010, 04:23 AM #7
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.
- 07-17-2010, 04:31 AM #8
Senior Member
- Join Date
- Feb 2010
- Location
- Waterford, Ireland
- Posts
- 748
- Rep Power
- 11
Images should definetely overlap depending on which is drawn first and the coordinates of where they are drawn
- 07-18-2010, 04:06 AM #9
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
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?
- 07-18-2010, 04:22 AM #10
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.
- 07-18-2010, 05:27 PM #11
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
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.
- 07-18-2010, 06:04 PM #12
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?
-
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 07:44 PM.
- 07-18-2010, 07:52 PM #14
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
- 07-19-2010, 05:39 AM #15
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
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;
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.
- 07-19-2010, 02:29 PM #16
(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
- 07-19-2010, 07:29 PM #17
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
Success! I've got transparent images now!
Thanks, guys. You've really helped me get this project off the ground!
- 07-20-2010, 06:12 AM #18
Member
- Join Date
- Jun 2010
- Posts
- 28
- Rep Power
- 0
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?
- 07-20-2010, 01:34 PM #19
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.
- 07-20-2010, 08:26 PM #20I 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.
I recommend that you go through the Sun Swing tutorials on Concurrency in Swing and Performing Custom Painting.
db
Similar Threads
-
Jpanel and displaying graphics
By jdsflash in forum New To JavaReplies: 6Last Post: 11-21-2009, 02:14 AM -
Clear Graphics Objects from Jpanel
By DavidG24 in forum AWT / SwingReplies: 2Last Post: 05-20-2009, 10:34 PM -
Newbie need help on JPanel graphics
By junpogi in forum AWT / SwingReplies: 7Last Post: 10-21-2008, 08:44 AM -
adding a jpanel in the middle of the script
By 2o2 in forum AWT / SwingReplies: 11Last Post: 10-12-2008, 06:50 PM -
Adding graphics to array
By romina in forum Java 2DReplies: 1Last Post: 08-01-2007, 02:45 AM
Bookmarks