Search code examples
javaswinguser-interfacejframejcomponent

How to add scrolling feature to a JComponent on a JFrame?


My GUI consists of a Diagram class which extends JFrame. I've created a different class called DrawingTool which extends JComponent. The DrawingTool class is like a canvas area for users to drop and drag shapes. I've also added a button panel at the bottom of the JFrame for the users to click various buttons to choose their desired shape and control actions. I've added the button panel and an instance of the DrawingTool class to the Diagram class. How do I make the canvas area (DrawingTool) scrollable? The way I have attempted it is not working, I know I am missing something.

Here is the Diagram class:

public class Diagram extends JFrame {
JButton serverButton, vipButton, arrowButton, undoButton, dragButton, loadButton, submitButton;
JButton applicationButton;
int currentAction = 1;
Graphics2D graphSettings;
Color strokeColor = Color.BLUE, fillColor = Color.BLACK;

/**
 * Constructor to generate new diagram with empty drawing board and button
 * panel.
 */
public Diagram() {
    // Define the defaults for the JFrame

    this.setSize(1000, 1000);
    this.setTitle("Diagram Tool");
    //this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

    JPanel buttonPanel = new JPanel();

    // Swing box that will hold all the buttons

    Box theBox = Box.createHorizontalBox();

    // Make all the buttons in makeButtons by calling helper function

    serverButton = makeButtons("Server", 2);
    vipButton = makeButtons("VIPs", 3);
    arrowButton = makeButtons("Arrow", 4);
    undoButton = makeButtons("Undo", 5);
    dragButton = makeButtons("Drag", 6);
    loadButton = makeButtons("Load", 11);
    applicationButton = makeButtons("Application", 8);
    submitButton = makeButtons("Submit", 12);

    // Add the buttons to the box

    theBox.add(serverButton);
    theBox.add(vipButton);
    theBox.add(applicationButton);
    theBox.add(arrowButton);
    theBox.add(undoButton);
    theBox.add(dragButton);
    theBox.add(loadButton);
    theBox.add(submitButton);

    // Add the box of buttons to the panel



    buttonPanel.add(theBox);

    // Position the buttons in the bottom of the frame

    JPanel container=new JPanel();
    container.add(new DrawingBoard(),BorderLayout.CENTER);
    JScrollPane jsp=new JScrollPane(container);
    this.add(buttonPanel, BorderLayout.SOUTH);
    this.add(jsp);

    // Make the drawing area take up the rest of the frame

    // Show the frame

    this.setVisible(true);
}

Here is the DrawingBoard class:

private class DrawingBoard extends JComponent implements MouseListener, MouseMotionListener {
    //declare variables

    /**
     * Constructor to initialize the drawing board
     */
    public DrawingBoard() {
        addMouseListener(this);
        addMouseMotionListener(this);

    //  initializeCanvas();
    }
   //Rest of the code for DrawingBoard 
  }

This is how it looks now. I'd like to make the gray canvas area scrollable.

Diagram Image

https://i.sstatic.net/nF9oL.png


Solution

  • What MadProgrammer said in the comments is just about right. You need to set some informations so your ScrollPanel knows how to behave. What is it's own size, the size of the components inside it, etc.

    So normally you'll have a ContentPane, and inside of it panes with your content. To do a scrollable pane you only need to put the ScrollPane inside of your ContentPane and then set a viewport for your ScrollPane. A little code I used fully functional:

    contentPane = new JPanel();
    setContentPane(contentPane);
    contentPane.setLayout(null);
    
    JScrollPane scrollPane = new JScrollPane();
    
    //Vertical and Horizontal scroll bar policy is set to choose when the scroll will be visible    scrollPane.setVerticalScrollBarPolicy(ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED);
        scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
    scrollPane.setBounds(0, 217, 414, 505);
    scrollPane.setPreferredSize(new Dimension(414, 414));
    
    JPanel viewport = new JPanel();
    viewport.setLayout(null);
    viewport.setBounds(0, 0, 414, 505);
    
    //Create your components here, then:
    //viewport.add(component)
    
    viewport.setPreferredSize(new Dimension(414, 150));
    scrollPane.setViewportView(viewport);
    contentPane.add(scrollPane);
    

    Anything you put inside of your ViewPort will be automaticaly scrolable, if it's size is bigger than the PreferredSize.

    Note that all the dimensions I've put is only for example.