JScrollPane not scrolling past a set size

江枫思渺然 提交于 2019-12-02 07:13:17

问题


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: http://i.imgur.com/fwJ9LV6.png (Notice the white border at the edge of the grid)

However, same rectangles at [84][82]: http://i.imgur.com/PZ2rNY3.png (The last rows get sliced).

Now, I've:

  • Increased the preferred and Max sizes of both the scroll pane and the Jpanel to well above what is needed.
  • Checked that the JPanel is the viewport of the scrollable object.

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!


回答1:


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

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);
    }
}



回答2:


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.




回答3:


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.



来源:https://stackoverflow.com/questions/14574770/jscrollpane-not-scrolling-past-a-set-size

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!