I'm painting a grid on the JPanel and trying to scroll the grid with a JScrollPane. I have a feeling the scrollpane is getting the actual size of the panel, instead of the size including what is not being shown. Something along those lines at least, I can't quite wrap my head around the problem which is why I can't figure it out.

Here's the JPanel class that actually get's painted on.

/**
 * Created by GeoDoX on 2015-03-16.
 */
public class GridPanel extends JPanel
{
    private Tile[][] tiles;
    private int width, height;
    private double scale;

    public GridPanel(int width, int height)
    {
        this.width = width;
        this.height = height;

        scale = 1;

        tiles = new Tile[width][height];
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);

        for(int i = 0; i < height; i++)
        {
            g.drawLine(0, i * (int) (TILE_VIEW_SIZE_DEFAULT * scale), width * (int) (TILE_VIEW_SIZE_DEFAULT * scale), i * (int) (TILE_VIEW_SIZE_DEFAULT * scale));
        }

        //System.out.println((int) (TILE_VIEW_SIZE_DEFAULT * scale));

        for(int j = 0; j < width; j++)
        {
            g.drawLine(j * (int) (TILE_VIEW_SIZE_DEFAULT * scale), 0, j * (int) (TILE_VIEW_SIZE_DEFAULT * scale), height * (int) (TILE_VIEW_SIZE_DEFAULT * scale));
        }
    }

    public void paintTile(Tile t, int posX, int posY)
    {
        tiles[posX][posY] = t;
        this.getGraphics().drawImage(t.getTexture(), posX * (int) (TILE_VIEW_SIZE_DEFAULT * scale), posY * (int) (TILE_VIEW_SIZE_DEFAULT * scale), (int) (t.getTexture().getWidth() * scale), (int) (t.getTexture().getHeight() * scale), null);
    }

    public void fill(Tile t)
    {
        for(int i = 0; i < tiles.length; i++)
        {
            for(int j = 0; j < tiles[0].length; j++)
            {
                paintTile(t, i, j);
            }
        }
    }

    public void setScale(double scale)
    {
        this.scale = scale;
        System.out.println(scale);
        this.repaint();
    }

    public double getScale() { return scale; }

    public void updateSize()
    {
        tiles = new Tile[width][height];
    }

    public void setWidthAndHeight(int width, int height)
    {
        this.width = width;
        this.height = height;
        this.repaint();
    }

    public void setTiles(Tile[][] tiles)
    {
        this.tiles = tiles;
        this.width = tiles.length;
        this.height = tiles[0].length;
        drawTiles();
    }

    private void drawTiles()
    {
        for(int i = 0; i < tiles.length; i++)
        {
            for(int j = 0; j < tiles[0].length; j++)
            {
                this.getGraphics().drawImage(tiles[i][j].getTexture(), i * TILE_VIEW_SIZE_DEFAULT, j * TILE_VIEW_SIZE_DEFAULT, tiles[i][j].getTexture().getWidth(), tiles[i][j].getTexture().getHeight(), null);
            }
        }
    }

    public Tile[][] getTiles() { return tiles; }
}

This is the initialization of the ScrollPane, and where it get's added to the GUI.

        gridScrollPane = new JScrollPane(gridPanel);
        gridScrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        gridScrollPane.setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);

        splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, tilePanel, gridScrollPane);

PS: Is there a better way to code the Fill method in GridPanel class? The process is SUPER slow on maps that are max size, 10000 x 10000.

override (based on code posted here)

  • getPreferredSize for GridPanel

  • use getHeight/Weight in paintComponent

  • change scroll increment for JScrollBar for natural scrolling

_________________________________________________________________

important everything is elsewhere

  • no one knows how, what, where, why a size has JFrame, actual part of JSplitPane, not Dimension from JScrollPane, much luck

Edited 1 Year Ago by mKorbel

Unless all your tiles are moving/changing all the time, maybe you can just re-paint those tiles that have changed since the last call to paintComponent - if you remove the super.paintComponent call then your Graphics will still contain its previous contents.

I don't really understand your post mKorbel. Does getPreferredSize not return how big you want the component to be in the GUI?

I'm confused about your post too James, what does that help with?

Edited 1 Year Ago by Doogledude123

Is this in regards to the fill method? Because if it is then I need a way to fill the entire board with tiles.

If not, then I don't know what you mean because I'm never repainting the tiles all at once, except for in the load method. Which is needed because this is used in the load method where I load in map files.

OK, I give up! I have absolutely no idea what you are trying to do.

All I see here is a JPanel subclass with no size info or methods that Swing will recognise, with a paintComponent method that just draws a grid of lines. Then there's a whole stack of methods about Tiles with no info about when or how they are called, except that one of them is apparently very slow.
That's a fill method that appears to paint 100,000,000 tiles to the JPanel's graphics ignoring the normal Swing paint mechanism - which means it will take a long time and achieve absolutely nothing.

Is this based on something you found on the web, or what?

" Does getPreferredSize not return how big you want the component to be in the GUI?"

  • there is only one correct notifier for LayoutManager (for customs too), rest mathods are about multiplications events that descreasing performance and increasing unwanted painting artefacts

______________________________________________________________________________

"instead of repainting 1000x1000 (100 million) tiles each time you just paint the few that have changed."

  • every (J)Components that implements Scrollable (is possible to add to JPanel too) painting only to the Rectagle equals/reduced with/to the JViewport, as is mentioned correctly by @JamesCherrill isn't good idea painting all Objects and off_screen

______________________________________________________________________________

"if you remove the super.paintComponent"

  • repaint is still there, but just cumulating previous painting without cleaning background, foreground, etc :-), I'm think that you meaning == there is one method implemented in (J)Components.setIgnoreRepaint

______________________________________________________________________________

I'd have to search for Tiles in JViewport, which are repainted only in the case that they are visible in the JViewport, you would need, have to wait for

______________________________________________________________________________

your Q contains 1/4 max 1/3 informations that I'm required for real answer, still is there huge space (bigger than entire Milky Way) for dirty guessing on answerers side, another forums required effort as an SSCCE/MCVE, short, runnable, compilable, with hardcoded value in local variables, much luck

Edited 1 Year Ago by mKorbel

This article has been dead for over six months. Start a new discussion instead.