Darkstarone
Darkstarone

Reputation: 4730

JScrollPane not scrolling past a set size

I'm using a scroll pane, with a JPanel inside that draws a grid of squares that are objects from a [][] array.

IF the array is [83][81] of size 18^2 rectangles it looks like: https://i.sstatic.net/MEBrt.png (Notice the white border at the edge of the grid)

However, same rectangles at [84][82]: https://i.sstatic.net/36WGm.png (The last rows get sliced).

Now, I've:

And it hasn't changed anything.

My Jpanel Class is:

package BlastRadius;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.JPanel;

/**
 * Canvas Class Stuart Bradley 25-1-2013 Contains the paint component
 */
public class BlastRadiusCanvas extends JPanel {

    GridOfNodes grid = new GridOfNodes();

    @Override
    public void paintComponent(Graphics g) {
        super.paintComponent(g);
        Graphics2D g2d = (Graphics2D) g;
        RenderingHints rh = g2d.getRenderingHints();
        rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
        g2d.setRenderingHints(rh);

        //Draw space
        int pixelsAcross = 32;
        int pixelsDown = 0;
        int size = 18;
        for (int i = 0; i < grid.getRows(); i++) {
            for (int j = 0; j < grid.getColumns(); j++) {
                g2d.setColor(grid.getNodeGrid()[i][j].getColour());
                g2d.fillRect(pixelsAcross, pixelsDown, size, size);
                g2d.setColor(new Color(0, 0, 0));
                g2d.drawRect(pixelsAcross, pixelsDown, size, size);
                //Better Ovals maybe needed, try Ellipise2D class

                if (grid.getNodeGrid()[i][j].getHasOval() == true) {
                    g2d.setColor(new Color(255, 255, 255));
                    g2d.fillOval((pixelsAcross + (size / 2) - 1), (pixelsDown + (size / 2) - 1), size / 4, size / 4);
                }
                pixelsAcross += 18;
            }
            pixelsDown += 18;
            pixelsAcross = 32;
            //Draws gene string for first object in each row
            g2d.setColor(new Color(0, 0, 0));
            g2d.drawString(grid.getNodeGrid()[i][0].getGeneString(), 5, pixelsDown - 5);
        }
    }
}

Scroll pane and related, can post the entire GUI class if needed:

jScrollPane1 = new javax.swing.JScrollPane();
jScrollPane1.setPreferredSize(new java.awt.Dimension(10000, 10000));
jScrollPane1.setViewportView(drawingJPanel);

//Grouping 

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 254, Short.MAX_VALUE)
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
            .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
        );

While I've done GUI's before, both via RAD environments and by hand, scrollable interfaces are somewhat new to me!

Upvotes: 1

Views: 511

Answers (3)

trashgod
trashgod

Reputation: 205865

Because BlastRadiusCanvas contains no components of its own, you can override getPreferredSize() to return the optimal size to display the grid. See this related answer for more details. Also consider implementing the Scrollable interface to return a suitable Dimension from getPreferredScrollableViewportSize(). The image appears to have natural unit and block sizes.

Upvotes: 5

MadProgrammer
MadProgrammer

Reputation: 347314

The BlastRadiusCanvas needs to be providing information back to the scroll pane about how big it wants to be.

enter image description here

Based on my interpretation of what it is your trying to do, try adding the following to your BlastRadiusCanvas

@Override
public Dimension getPreferredSize() {
    return new Dimension((grid.getColumns() * 18) + 64, (grid.getRows() * 18) + 1);
}

Now really, you shouldn't rely on "magic" numbers, it would be better to use something like...

protected static final int GRID_SIZE = 18;
protected static final int H_GAP = 32;

@Override
public Dimension getPreferredSize() {
    return new Dimension((grid.getColumns() * GRID_SIZE) + (H_GAP * 2), (grid.getRows() * GRID_SIZE) + 1);
}

This would make your paintComponent method look more like...

@Override
public void paintComponent(Graphics g) {
    super.paintComponent(g);
    Graphics2D g2d = (Graphics2D) g;
    RenderingHints rh = g2d.getRenderingHints();
    rh.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    g2d.setRenderingHints(rh);

    //Draw space
    int pixelsAcross = H_GAP;
    int pixelsDown = 0;
    int size = GRID_SIZE;
    for (int i = 0; i < grid.getRows(); i++) {
        for (int j = 0; j < grid.getColumns(); j++) {
            g2d.setColor(grid.getNodeGrid()[i][j].getColour());
            g2d.fillRect(pixelsAcross, pixelsDown, size, size);
            g2d.setColor(new Color(0, 0, 0));
            g2d.drawRect(pixelsAcross, pixelsDown, size, size);
            //Better Ovals maybe needed, try Ellipise2D class

            if (grid.getNodeGrid()[i][j].getHasOval() == true) {
                g2d.setColor(new Color(255, 255, 255));
                g2d.fillOval((pixelsAcross + (size / 2) - 1), (pixelsDown + (size / 2) - 1), size / 4, size / 4);
            }
            pixelsAcross += size;
        }
        pixelsDown += size;
        pixelsAcross = H_GAP;
        //Draws gene string for first object in each row
        g2d.setColor(new Color(0, 0, 0));
        g2d.drawString(grid.getNodeGrid()[i][0].getGeneString(), 5, pixelsDown - 5);
    }
}

Upvotes: 5

Darkstarone
Darkstarone

Reputation: 4730

Incase anyone else has the same issue - since hours of googling didn't fix it for me.

Check your JFrame preferred size. If it's too low, it maxes out the amount of grid - or any draw space - you have.

Upvotes: 0

Related Questions