如何滚动两个JTextPane?

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

如果我从NetBean设计器添加JTextPanes,它们会自动放入JScrollPane中,以便它们独立滚动。 我删除了封闭的滚动窗格并将它们放在JPanel中,因此JPanel可以是单个JScrollPane的客户端。 这似乎有效,除了当JTextPanes非常长时,它们似乎在JPanel的末尾。 我可以将面板和两个文本窗格滚动到某个点。 当我到达底部时,我可以在其中一个文本窗格中放置一个cusor,并将箭头放在我的视野之外。

这是我的主要方法的代码。 我已经从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); } }); 

这是一个图像,显示我对第一个答案的实现,其中文本窗格不限于水平显示区域。 显示对于水平显示区域来说太宽的文本窗格的图像

此图像显示在水平显示区域中限制的文本窗格,但是如果文本窗格很长,则此示例具有不垂直滚动的原始问题。 图像显示水平限制的文本窗格

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

 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具有不同的大小,它可能无法正常工作(我没有尝试过,但我最好的猜测是它会导致问题)

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

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

如果对两个JTextPane使用GridLayout然后用JScrollPane包装它,则Scroll Bar将用于两个JTextPanes,因为GridLayout被分成相等大小的矩形。

这样的东西应该工作(在Java 6上测试)

 // Text Panes initialization. I am just setting text so you can see // what each pane is. JTextPane leftDiffPane = new JTextPane(); leftDiffPane.setText("left"); JTextPane rightDiffPane = new JTextPane(); rightDiffPane.setText("right"); // Wrap the Text Panes with a Panel since you can only // have a single component within a scroll pane. JPanel bothDiffsPanel = new JPanel(); bothDiffsPanel.setLayout(new GridLayout(1, 2)); bothDiffsPanel.add(leftDiffPane, BorderLayout.WEST); bothDiffsPanel.add(rightDiffPane, BorderLayout.EAST); // Fill in the frame with both of the panels. setLayout(new BorderLayout()); add(new JScrollPane(bothDiffsPanel), BorderLayout.CENTER); 

如果使用上述方法,如果将文本修改为JTextPanes溢出维度,则会出现滚动条,使用时,它将滚动两个组件。 如果修改文本溢出组件,它将向下滚动,以便您的输入可见。

希望有所帮助!