如何为 JFrame 上的 JComponent 添加滚动功能?

Posted

技术标签:

【中文标题】如何为 JFrame 上的 JComponent 添加滚动功能?【英文标题】:How to add scrolling feature to a JComponent on a JFrame? 【发布时间】:2018-12-06 21:37:25 【问题描述】:

我的 GUI 包含一个扩展 JFrame 的 Diagram 类。我创建了一个名为 DrawingTool 的不同类,它扩展了 JComponent。 DrawingTool 类就像一个画布区域,供用户拖放和拖动形状。我还在 JFrame 的底部添加了一个按钮面板,供用户单击各种按钮来选择所需的形状和控制动作。我已将按钮面板和 DrawingTool 类的实例添加到 Diagram 类。如何使画布区域(DrawingTool)可滚动?我尝试的方式不起作用,我知道我错过了一些东西。

这是图表类:

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

这是绘图板类:

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 
  

这就是现在的样子。我想让灰色画布区域可滚动。

图表图像

【问题讨论】:

滚动需要一些重要的信息。首先,您需要知道相关组件的总体大小 - 为此,您应该覆盖 getPreferredSize 并返回您的组件想要的“首选大小”。接下来,JScrollPane 将使用它的“当前”大小,与组件的“首选大小”相比,以确定何时应该使用滚动条。您还可以查看Scrollable 界面,它提供了许多有用但高级的功能 注意,JPanel 的默认布局管理器是 FlowLayout,因此指定 BorderLayout.CENTER 约束没有任何作用,因为该约束仅用于具有 BorderLayout 的面板。 【参考方案1】:

MadProgrammer 在 cmets 中所说的几乎是正确的。您需要设置一些信息,以便您的ScrollPanel 知道如何表现。它自己的大小是多少,里面的组件大小等等。

所以通常你会有一个ContentPane,它的内部会显示你的内容。要创建可滚动窗格,您只需将 ScrollPane 放在 ContentPane 中,然后为 ScrollPane 设置视口。我使用的一些功能齐全的代码:

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

您放入 ViewPort 的任何内容 将自动滚动,如果它的大小大于 PreferredSize。

请注意,我放置的所有尺寸都只是示例。

【讨论】:

以上是关于如何为 JFrame 上的 JComponent 添加滚动功能?的主要内容,如果未能解决你的问题,请参考以下文章

JPanel、JFrame、JComponent 和 JApplet 之间的区别

如何为 JTextField 设置动态宽度?

java中如何为JFrame设置背景图片,拜托给一个简单的实例。谢谢了。

在绝对位置 Container 中拖动 JComponent

图形不绘制到 JFrame

Java Swing:为啥我不能在 JFrame 实例上绘制图像()?