我在JScrollPanes中有一个JTextPanes数组。我提到的所有组件都在JScrollPane内的JPanel中。
在程序开始时,没有任何JTextPanes有任何文本,因此它们的滚动条不可见。 JPanel的滚动条是可见的,因为我有很多组件。
我的问题是,如果光标位于其中一个JTextPanes上并且我尝试滚动,则没有任何反应,因为计算机认为我想使用JTextPane的滚动条滚动。我想要发生的是计算机意识到我正在尝试使用JPanel的滚动条滚动。有什么方法可以做到这一点吗?
谢谢!
编辑:
您可以使用此代码生成与上述类似的UI(这是扩展JFrame的类的构造函数 - 为忽略许多良好的编码习惯而道歉):
public JFrameTest() {
JPanel panel = new JPanel( new GridLayout( 10 , 10 , 10 , 10 ) );
for ( int i = 0 ; i < 10 ; i ++ ) {
for ( int j = 0 ; j < 10 ; j ++ ) {
JScrollPane paneToAdd = new JScrollPane( new JTextPane() ) {
/**
*
*/
private static final long serialVersionUID = 1L;
@Override
public Dimension getPreferredSize() {
return new Dimension( 100 , 100 );
}
};
panel.add( paneToAdd );
}
}
add( new JScrollPane( panel ) );
setSize( 700 , 500 );
setVisible( true );
setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
}
答案 0 :(得分:2)
以下代码被视为来自Mouse Wheel Controller的快速破解。
基本上,它拦截包含文本区域的滚动窗格的MouseWheelEvent。如果滚动条可见,它会将事件重新分配回同一个滚动窗格,否则会找到父scrollPane并将事件调度到该scrollPane。
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public class MouseWheelToParent implements MouseWheelListener
{
private JScrollPane scrollPane;
private MouseWheelListener[] realListeners;
public MouseWheelToParent(JScrollPane scrollPane)
{
this.scrollPane = scrollPane;
install();
}
public void install()
{
if (realListeners != null) return;
// Keep track of original listeners so we can use them to
// redispatch an altered MouseWheelEvent
realListeners = scrollPane.getMouseWheelListeners();
for (MouseWheelListener mwl : realListeners)
{
scrollPane.removeMouseWheelListener(mwl);
}
// Intercept events so they can be redispatched
scrollPane.addMouseWheelListener(this);
}
/**
* Remove the class as the default listener and reinstall the original
* listeners.
*/
public void uninstall()
{
if (realListeners == null) return;
// Remove this class as the default listener
scrollPane.removeMouseWheelListener( this );
// Install the default listeners
for (MouseWheelListener mwl : realListeners)
{
scrollPane.addMouseWheelListener( mwl );
}
realListeners = null;
}
// Implement MouseWheelListener interface
/**
* Redispatch a MouseWheelEvent to the real MouseWheelListeners
*/
public void mouseWheelMoved(MouseWheelEvent e)
{
JScrollPane scrollPane = (JScrollPane)e.getComponent();
if (scrollPane.getVerticalScrollBar().isVisible())
{
// Redispatch the event to original MouseWheelListener
for (MouseWheelListener mwl : realListeners)
{
mwl.mouseWheelMoved( e );
}
}
else
{
dispatchToParent(e, scrollPane);
return;
}
}
private void dispatchToParent(MouseWheelEvent e, JScrollPane scrollPane)
{
Component ancestor = SwingUtilities.getAncestorOfClass(JScrollPane.class, scrollPane);
MouseWheelEvent mwe = new MouseWheelEvent(
ancestor,
e.getID(),
e.getWhen(),
e.getModifiers(),
e.getX(),
e.getY(),
e.getXOnScreen(),
e.getYOnScreen(),
e.getClickCount(),
e.isPopupTrigger(),
e.getScrollType(),
e.getScrollAmount(),
e.getWheelRotation());
ancestor.dispatchEvent(mwe);
}
private static void createAndShowUI()
{
JPanel panel = new JPanel( new GridBagLayout() );
GridBagConstraints gbc = new GridBagConstraints();
gbc.insets = new Insets(10, 10, 10, 10);
for (int y = 0; y < 10; y++)
{
for (int x = 0; x < 5; x++)
{
gbc.gridx = x;
gbc.gridy = y;
JTextArea textArea = new JTextArea(5, 20);
JScrollPane scrollPane = new JScrollPane( textArea );
scrollPane.setMinimumSize( scrollPane.getPreferredSize() );
new MouseWheelToParent(scrollPane);
panel.add(scrollPane, gbc);
}
}
JFrame frame = new JFrame("TextAreaSSCCE");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add( new JScrollPane( panel ) );
frame.setSize(400, 400);
frame.setLocationByPlatform( true );
frame.setVisible( true );
}
public static void main(String[] args)
{
EventQueue.invokeLater(new Runnable()
{
public void run()
{
createAndShowUI();
}
});
}
}