java - 如何滚动两个 JTextPane?

标签 java swing scroll

我是使用 NetBeans 的 Swing 新手。我想垂直滚动两个并排的 JTextPane。滚动应该同步并通过单个滚动条完成。

如果我从 NetBean 设计器中添加 JTextPanes,它们会自动放入 JScrollPane 中,因此它们可以独立滚动。我删除了封闭的滚动 Pane 并将它们放在 JPanel 中,这样 JPanel 就可以成为单个 JScrollPane 的客户端。这似乎有效,除了当 JTextPanes 很长时它们似乎超出了 JPanel 的末尾。我可以将面板和两个文本 Pane 滚动到某个点。当我到达底部时,我可以将光标放在其中一个文本 Pane 中,然后向下箭头超出我的视野。

这是我的主要方法的代码。我从 NetBeans 设计器生成的内容中复制了布局。

java.awt.EventQueue.invokeLater(new Runnable() {
    public void run() {
topFrame aTopFrame = new topFrame();
JScrollPane scollBothDiffs = new javax.swing.JScrollPane();
JPanel bothDiffsPanel = new javax.swing.JPanel();
JTextPane leftDiffPane = diffPane1;
JTextPane rightDiffPane = diffPane2;


javax.swing.GroupLayout bothDiffsPanelLayout = new javax.swing.GroupLayout(bothDiffsPanel);
bothDiffsPanel.setLayout(bothDiffsPanelLayout);
bothDiffsPanelLayout.setHorizontalGroup(
    bothDiffsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(bothDiffsPanelLayout.createSequentialGroup()
        .addGap(20, 20, 20)
        .addComponent(leftDiffPane, javax.swing.GroupLayout.PREFERRED_SIZE, 463, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
        .addComponent(rightDiffPane, javax.swing.GroupLayout.PREFERRED_SIZE, 463, javax.swing.GroupLayout.PREFERRED_SIZE)
        .addContainerGap(52, Short.MAX_VALUE))
);
bothDiffsPanelLayout.setVerticalGroup(
    bothDiffsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, bothDiffsPanelLayout.createSequentialGroup()
        .addContainerGap()
        .addGroup(bothDiffsPanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.TRAILING)
            .addComponent(rightDiffPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 630, Short.MAX_VALUE)
            .addComponent(leftDiffPane, javax.swing.GroupLayout.Alignment.LEADING, javax.swing.GroupLayout.DEFAULT_SIZE, 630, Short.MAX_VALUE))
        .addContainerGap())
);

scollBothDiffs.setViewportView(bothDiffsPanel);

javax.swing.GroupLayout layout = new javax.swing.GroupLayout(aTopFrame.getContentPane());
aTopFrame.getContentPane().setLayout(layout);
layout.setHorizontalGroup(
    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(layout.createSequentialGroup()
        .addGap(20, 20, 20)
        .addComponent(scollBothDiffs, javax.swing.GroupLayout.DEFAULT_SIZE, 997, Short.MAX_VALUE)
        .addContainerGap())
);
layout.setVerticalGroup(
    layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
        .addContainerGap()
        .addComponent(scollBothDiffs, javax.swing.GroupLayout.DEFAULT_SIZE, 671, Short.MAX_VALUE)
        .addContainerGap())
);

aTopFrame.pack();
aTopFrame.setVisible(true);
}
});

这是一张图片,显示了我对第一个答案的实现,其中文本 Pane 不限于水平显示区域。 Image showing text panes that are too wide for the horizontal display area

并且此图像显示了限制在水平显示区域中的文本 Pane ,但此示例存在原始问题,即如果文本 Pane 很长,则无法垂直滚动。 Image showing text panes that are bounded horizontally

最佳答案

我以前用过的一个技巧是使用两个JScrollPanes,隐藏左 Pane 的垂直滚动条,并将其模型设置为右滚动 Pane 的模型。这样,当用户滚动右滚动条时,它会更新两个滚动 Pane ,因为它们共享相同的模型。这是一个在底部也有双同步水平滚动条的示例:

JTextPane leftDiffPane = diffPane1;
JTextPane rightDiffPane = diffPane2;
JScrollPane spLeft = new JScrollPane(leftDiffPane, JScrollPane.VERTICAL_SCROLLBAR_NEVER, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
JScrollPane spRight = new JScrollPane(leftDiffPane, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
spLeft.getHorizontalScrollBar().setModel(spRight.getHorizontalScrollBar().getModel());
spLeft.getVerticalScrollBar().setModel(spRight.getVerticalScrollBar().getModel());

// ...

请注意,如果您的 JTextPanes 具有不同的大小,它可能无法很好地工作(我没有尝试过,但我最好的猜测是它会导致问题)

您还可以通过将滚轮事件从左侧滚动 Pane 重定向到右侧来修复鼠标滚轮滚动:

spLeft.setWheelScrollingEnabled(false);
spLeft.addMouseWheelListener(new MouseWheelListener() {
    public void mouseWheelMoved(MouseWheelEvent e) {
        spRight.dispatchEvent(e);
    }
});

关于java - 如何滚动两个 JTextPane?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6379255/

相关文章:

java - 如何在java中根据条件对值进行分组

java事件队列事件调度刷新/陷阱事件

java - 当分配新的子类时,JPanel 不会重新绘制

javascript - 向下滚动 iFrame - jQuery/JS

jquery - 将 div 的水平滚动条固定到页面底部

javascript - 从顶部滚动 x 像素后触发函数

java - 如何将光标数据(DbHandler.java)添加到 ListView (MainActicity.java)?

java - 英特尔 MPI mpirun 不会使用 java Process.destroy() 终止

Java:显示一个字母在字符串中出现的次数

java - [Miglayout]调整容器的大小以适合所包含的所有组件的总大小,带有插图和间隙