简单;我在import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.TitledBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
JPanel p1 = new JPanel();
p1.setBorder(new TitledBorder(null, "Customer Details", TitledBorder.CENTER, TitledBorder.TOP, null, null));
JPanel p2 = new JPanel();
p2.setBorder(new TitledBorder(null, "Customer Details", TitledBorder.CENTER, TitledBorder.TOP, UIManager.getFont("Label.font").deriveFont(Font.BOLD), null));
JPanel p3 = new JPanel();
p3.setBorder(new TitledBorder(null, "Customer Details", TitledBorder.CENTER, TitledBorder.TOP, UIManager.getFont("Label.font").deriveFont(Font.ITALIC), null));
JPanel p4 = new JPanel();
p4.setBorder(new TitledBorder(null, "Customer Details", TitledBorder.CENTER, TitledBorder.TOP, UIManager.getFont("Label.font").deriveFont(Font.BOLD | Font.ITALIC), null));
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
gbc.weightx = 1;
gbc.weighty = 1;
gbc.fill = GridBagConstraints.BOTH;
add(p1, gbc);
add(p2, gbc);
add(p3, gbc);
add(p4, gbc);
}
@Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
}
}
;
JPanel
正如所料;默认情况下,JScrollPane
会侦听JScrollPane
,以便当滚轮旋转并且光标悬停在MouseWheelEvent
上时滚动效果很好。
但之后;我刚刚更新JPanel
以便它实现JPanel
,并为MouseWheelListener
本身添加了这个鼠标滚轮监听器。
JPanel
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.isControlDown()) {
if (e.getWheelRotation() < 0) {
System.out.println("mouse wheel Up");
} else {
System.out.println("mouse wheel Down");
}
}
}
响应此实现的时间;按下 Ctrl 并且当光标悬停在JPanel
上时,滚轮正在旋转。但是JPanel
的默认行为意外丢失!!!
当光标悬停在JScrollPane
上时我旋转滚轮时JPanel
的滚动没有响应!!!
似乎; JScrollPane
的此实现会中断MouseWheelListener
的默认值。
因此;如何在不违反默认实施的情况下为JPanel
实施MouseWheelListener
?
答案 0 :(得分:8)
MouseWheelEvents
并且滚动行为有一些微妙的警告。
例如,当您打开此页面(我的意思是您正在阅读的那个页面)时,将鼠标放在中间,然后开始使用滚轮向下滚动,您将滚动代码段。请注意虽然代码片段包含在有滚动条的代码块中,但是连续旋转鼠标滚轮将不触发滚动在代码块中,但仅限于整个页面。但是当你移动鼠标时 一个代码块,而之后滚动鼠标滚轮,那么你将滚动代码仅阻止 - 并且不整个页面。
同样,旋转鼠标滚轮可能不会影响悬停的可滚动条。我认为这取决于Window Manager和Look&amp;感觉,但在某些情况下,您将滚动包含焦点组件的滚动窗格 - 即使鼠标光标位于此组件之外,即使它位于可分割组件之上(您也可以例如,在Windows资源管理器中观察这一点!
然而,其中一些机制和细微之处也可以在Swing组件中找到。例如,redispatching mechanism如果组件本身未处理,则将MouseWheelEvents
传递给祖先。
遵循这种模式,一个解决方案(概念上类似于the one that LuxxMiner proposed,但可能更通用)可能只是简单地将MouseWheelEvent
重新分配给父组件:
package stackoverflow;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingUtilities;
public class MouseWheelListenerForPanelInScrollpane
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
@Override
public void run()
{
createAndShowGUI();
}
});
}
private static void createAndShowGUI()
{
JFrame f = new JFrame();
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.getContentPane().setLayout(new GridLayout(1,2));
MouseWheelListenerPanel m = new MouseWheelListenerPanel();
m.setPreferredSize(new Dimension(100,4000));
JScrollPane scrollPane = new JScrollPane(m);
f.getContentPane().add(scrollPane);
f.setSize(500,500);
f.setLocationRelativeTo(null);
f.setVisible(true);
}
}
class MouseWheelListenerPanel extends JPanel implements MouseWheelListener
{
MouseWheelListenerPanel()
{
addMouseWheelListener(this);
}
@Override
public void mouseWheelMoved(MouseWheelEvent e)
{
if (e.isControlDown())
{
if (e.getWheelRotation() < 0)
{
System.out.println("mouse wheel Up");
}
else
{
System.out.println("mouse wheel Down");
}
}
else
{
getParent().dispatchEvent(e);
}
}
}
答案 1 :(得分:6)
如果ctrl 不,请添加else
将事件直接重新分配到滚动窗格:
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.isControlDown()) {
if (e.getWheelRotation() < 0) {
System.out.println("mouse wheel Up");
} else {
System.out.println("mouse wheel Down");
}
} else {
// pass the event on to the scroll pane
getParent().dispatchEvent(e);
}
}
答案 2 :(得分:4)
我不知道这是否真的有资格作为正确的答案,因为它是一种解决方法,但我想出了以下解决方案:只需调用mouseWheelMoved
方法即可。仅当 Ctrl 未被按下时才scrollPane
:
if (e.isControlDown()) {
if (e.getWheelRotation() < 0) {
infoLabel.setText("Mouse Wheel Up");
} else {
infoLabel.setText("Mouse Wheel Down");
}
} else {
scrollPane.getListeners(MouseWheelListener.class)[0].mouseWheelMoved(e);
}
完整示例:
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.border.TitledBorder;
public class Example {
public Example() {
JFrame frame = new JFrame();
frame.setLayout(new BorderLayout());
frame.add(new ScrollPanePanel());
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setSize(400, 400);
frame.setVisible(true);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
new Example();
}
});
}
}
class ScrollPanePanel extends JPanel implements MouseWheelListener {
private JLabel infoLabel;
private JScrollPane scrollPane;
public ScrollPanePanel() {
JPanel panel = new JPanel(new GridLayout(0, 1));
for (int i = 1; i <= 100; i++) {
panel.add(new JLabel("Label " + i));
}
panel.addMouseWheelListener(this);
scrollPane = new JScrollPane(panel);
infoLabel = new JLabel(" ");
JPanel infoPanel = new JPanel();
infoPanel.add(infoLabel);
setLayout(new BorderLayout());
add(scrollPane);
add(infoPanel, BorderLayout.SOUTH);
}
@Override
public void mouseWheelMoved(MouseWheelEvent e) {
if (e.isControlDown()) {
if (e.getWheelRotation() < 0) {
infoLabel.setText("Mouse Wheel Up");
} else {
infoLabel.setText("Mouse Wheel Down");
}
} else {
scrollPane.getListeners(MouseWheelListener.class)[0].mouseWheelMoved(e);
}
}
}