Reputation: 449
So I've got JPanel inside JScrollPane. Is there any possible way to display only visible area on JPanel? Right now my piece of code looks like that:
public void paintComponent(Graphics g)
{
super.paintComponent(g);
for(int i = 0; i < m_xTiles; i++)
{
for(int j = 0; j < m_yTiles; j++)
{
m_mapTiles.get(i).get(j).DrawImage(g);
}
}
}
It's not something that I want because it's display everything and when I want to make a very big map the movment are very slow. I want to get visible rectangle on screan - positions of four pixels and then I will calculate to my own x and y :)
Upvotes: 1
Views: 769
Reputation: 298143
Normally the graphic system cares about clipping operations outside the visible bounds so these operation become no-ops and are not expensive. So in most cases you don’t need to deal with these information as the graphics operations are the expensive part when painting.
However, sometimes you may encounter the situation that the operations you perform before the calls on the Graphics
object become expensive, i.e. if you have a really large but only partially visible component (as you described). In this situation it might be useful to access the clipping information to perform manually skipping, especially if you are tiling your area, thus calculating which items to process is rather easy:
public void paintComponent(Graphics g) {
super.paintComponent(g);
// I assert equal tiling of the actual size here, otherwise you may define
// the tile sizes as constants and calculate preferredSize as tileWidth*m_xTiles
// and tileHeight*m_yTiles, respectively
final int tileWidth=getWidth()/m_xTiles;
final int tileHeight=getHeight()/m_yTiles;
Rectangle clip = g.getClipBounds();
int firstX, lastX, firstY, lastY;
if(clip == null) {
firstX=0; lastX=m_xTiles-1;
firstY=0; lastY=m_yTiles-1;
}
else {
firstX=clip.x/tileWidth; lastX=(clip.x+clip.width)/tileWidth;
firstY=clip.y/tileHeight; lastY=(clip.y+clip.height)/tileHeight;
}
// note that the loop condition is <= now to handle partially visible tiles
for(int i = firstX; i <= lastX; i++)
{
for(int j = firstY; j <= lastY; j++)
{
m_mapTiles.get(i).get(j).DrawImage(g);
}
}
}
Upvotes: 2