Scrolling JPanel in JScrollingPanel

I am trying to create a level editor for my platform-platform, I want my levels to be 100 by 100 squares.

So far the editor is working, but I can't scroll the JPanel. I played around and I made a little test class to play with which I will post from.
If you run it, everything it shows shows a grid. However, if I swap two variables (I comment where), it can display the image and scroll to fit the size of that image.

I want to use scrolling for JPanel only so that I can scroll my 100 inch square level.

import java.awt.BorderLayout;

public class ScrollPaneJ extends JFrame {

    // setting the panels
    private JPanel contentPane;
    private JScrollPane scrollPane;

    // dimensions/ variables of the grid
    int size = 16;
    int startX = 112;
    int startY = 48;
    int width = 30;
    int height = 30;

    // this is the grid
    String[][] grid = new String[width][height];

    // this is from the full editor class
    String currentImage = new String("platform");

    ImageIcon currentBackIcon = new ImageIcon("Resources/backdirttile.jpg");

    /**
     * Launch the application.
     */
    public static void main(String[] args) {

        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                try {
                    // adding the scrollpane
                    ScrollPaneJ frame = new ScrollPaneJ();
                    frame.setVisible(true);
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
        });
    }

    /**
     * Create the frame.
     */
    public ScrollPaneJ() {

        setTitle("Scrolling Pane Application");
        setSize(new Dimension(300, 200));
        setBackground(Color.gray);
        setDefaultCloseOperation(EXIT_ON_CLOSE);

        // defining the top and bottom panels, bottom is what I think I'm
        // drawing on, top is where the scrollpanel goes, I copied this code
        // from the internet and I'm not too sure how it works
        JPanel topPanel = new JPanel();
        JPanel bottomPanel = new JPanel(new GridLayout());

        bottomPanel.setLayout(new BorderLayout());
        getContentPane().add(bottomPanel);

        topPanel.setLayout(new BorderLayout());
        getContentPane().add(topPanel);

        // this is the label I was talking about
        Icon image = new ImageIcon("src/MenuDesign.jpg");
        JLabel label = new JLabel(image);

        // Create a tabbed pane
        // if you set it to say label instead of bottomPanel, you can scroll
        // through the size of the label
        scrollPane = new JScrollPane(bottomPanel);
        scrollPane.setBounds(40, 40, 100, 100);
        // set it label here as well.
        scrollPane.getViewport().add(bottomPanel);

        // I was hoping this would force the scrollbar in but it does nothing
        scrollPane
                .setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
        scrollPane
                .setVerticalScrollBarPolicy(JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setBounds(50, 30, 300, 50);
        JPanel contentPane = new JPanel(null);
        contentPane.setPreferredSize(new Dimension(500, 400));
        contentPane.add(scrollPane);

        topPanel.add(scrollPane, BorderLayout.CENTER);
        init();
    }

    public void init() {
        // this sets the grid to empty
        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                grid[x][y] = "";

            }

        }
    }

    @Override
    public void paint(Graphics g) {
        // this paints the grid
        super.paint(g);
        Graphics2D g2d = (Graphics2D) g;
        g2d.setColor(Color.black);

        for (int x = 0; x < width; x++) {
            for (int y = 0; y < height; y++) {
                g2d.drawRect(x * size + startX, y * size + startY, size, size);

                if (grid[x][y].equals("")) {

                    g2d.drawImage(currentBackIcon.getImage(),
                            x * size + startX, y * size + startY, null);

                }

                g2d.setColor(Color.black);
                g2d.drawRect((x * size) + 1 + startX, (y * size) + 1 + startY,
                        size, size);

            }
        }
    }

    public void drawTile() {
        // this isn't enabled which is why you can't paint the grid, however it
        // would change the tile of the square you're mouse is on, to the
        // current tile, it works and isn't really important for what i need
        // help with
        PointerInfo a = MouseInfo.getPointerInfo();
        Point b = a.getLocation();
        int mouseX = (int) b.getX();
        int mouseY = (int) b.getY();
        int gMX = ((mouseX - 48) / 16) - 4;
        int gMY = ((mouseY - 48) / 16) - 3;

        grid[gMX][gMY] = currentImage;
        repaint();
    }
}

      

+3


source to share


2 answers


  • scrollPane.getViewport().add(bottomPanel);

    should be more like scrollPane.getViewportView(bottomPanel);

  • You cannot draw directly on the frame, as child components can be drawn without parental notification, which means that what has ever been painted can be partially destroyed. Instead, this kind of painting has to be performed in the user component, which acts as a representation JScrollPane

    , JViewport

    .
  • A JScrollPane

    requires two things: first, the size that the component would like to be ( preferredSize

    ), and the size of the view in the viewport. If the component does not implement the interface Scrollable

    , then the component is used to define it preferredSize

    . This is why it JLabel

    will work.

A JScrollPane

has JViewport

as its main child component. JViewport

should only have one component, usually assigned either by methods JScrollPane#setViewportView

orJViewport#setView

JScrollPane



See How to use scrollbars for details .

Create a custom component that extends JPanel

and overrides it getPreferredSize

to return the size of the required component. Override the method paintComponent

and do a normal paint job.

More complex custom paint overlay on other components

+3


source


You can also add JScrollPane to your panel like



JPanel p = new JPanel();
add(new JScrollPane(p));

      

0


source







All Articles