I'm making a map editor for my 2d tile based RPG game, and I'm running into a roadblock. The problem is actually how to draw the grid lines efficiently for large maps like, say 300x300 tiles. I mean the actual grid LINES, not the map tiles.

Originally I called redrew the entire grid line by line every time you moved the mouse or clicked(since it allows you to drag and also highlights the tile you are hovering over). This was horrible for large maps and was VERY slow. So my solution was to create a bufferedImage for the grid of a specified size right when a new empty map was created, and redraw that image every time paint was called. This worked well, except that for anything above 200x200ish java would run out of heap space in creating that bufferedImage. I can't really have a preloaded image because the user should be able to specify a new map to be any size. Also, I like the grid to be drawn over the tiles, otherwise the tiles cover up the lines and it looks messier. That means the grid has to be drawn again every time tiles are added right?

Is there another way to draw a very large grid that will repaint each time you move the mouse? The program Tiled can easily create maps of 1000x1000 or more, how is it done?? Thanks

Gridlines are going to have to be redrawn every time you move your mouse or do anything else. It's a fact of life.

The only way you can cut down on the amount of redrawing is to only redraw the lines that will appear on the screen. You can: Figure out the corners of your currently displayed map and only redraw the lines there. This shouldn't be too hard to actually manage to do.

Or, you can: Figure out where your mouse moved through (Where it messed up your art) and attempt to redraw only the damaged section. This is not really trvial though, so...

Another thing I should mention is that the whole JPanel is inside a JScrollPane which allows it to fit any map size. I'm not sure but I think it calls repaint() every time you try to scroll, because it lags a lot when scrolling even when I don't make ANY calls to repaint() myself, however if I comment out the grid drawing in paintComponent(), there is no lag in scrolling.

Do you know if there is a feature in JScrollPane that will make it repaint only the visible area? Shouldn't it already do this?

Also it wouldn't be hard to have it so that every time a tile is added the 4 grid lines around it would be redrawn, but every time paintComponent is called it clears the existing picture, so everything has to be redrawn every time either way.

EDIT: JScrollPane calls MY paintComponent() method every time you scroll. I tested with a print statement. Does that mean I have to manually get the coordinates of the scrolling viewPort and adjust my paint method to that?

From what I understand (And I hope someone who knows for sure can back me up/correct me) the paint methods that swing us only actually paint what needs to be repainted (IE- Sent to whatever Graphics module handles the drawing of pixels to the screen). However, everything in the paint method will still get executed.

If you rewrote a paint method, or anything like that, everything there will still get executed (Which if you're telling it to draw 2000 lines every time you scroll on top of telling it to paint all of your images will still be a large amount of repainting.)

Sorry, none that I know of (Beyond what I said before about limiting how many things you tell to get drawn by checking the view port of your scroll pane). Swing isn't really made for things like that, heh.

Drawing several horizontal and vertical lines should be pretty fast... And you shouldn't run out of memory if you're trying to use a single 200x200 image. It sounds like your code is buggy or not optimal.

My tiles have 36 width so a 300x300 map is actually a 10800x10800 image. Well the OutOfMemory exception occurs when I try to create a BufferedImage to draw the lines on, not during the use of it, since apparently java can store that much in dynamic memory.

For example if I create a completely empty class and put this code in it, I get the same OutOfMemory exception.

BUT...I just discovered...the only reason it's so slow is because I'm using dotted lines. davedes you are right drawing lines is fast and i can make maps of 1000x1000 no problem with normal lines but if I make the lines dotted it lags at 50x50...

Anybody know a better way to draw dotted lines??? I really like my dotted lines

Well, if you're using plain old g.drawLine, then yes. You can do it manually There's an example here. You'll end up drawing a million lines of 1px each, but it'll work. The example is for a dashed line, but you can just make the line length 1 and the gap 1, and there you go.See how that goes performance-wise.

I don't really see an easy way of doing it. There's no implementation other than the stroke. Stroke might even already be doing the exact same thing as the example does. CBA to look at BasicStroke javadoc, but maybe you should.

java-gaming.org is not responsible for the content posted by its members, including references to external websites,
and other references that may or may not have a relation with our primarily
gaming and game production oriented community.
inquiries and complaints can be sent via email to the info‑account of the
company managing the website of java‑gaming.org