我有一个带有自定义JPanel的JScrollPane作为内容。滚动窗格具有鼠标滚轮处理程序,因此当用户滚动时,内容将“缩放”,并且JPanel的高度会变大。
我需要确保用户的视口保持JPanel当前鼠标下当前像素行的位置。但是,当我手动尝试在wheel处理程序中设置视口时,我无法确保一致的焦点,因为有时JScrollPane会使用JScrollPane内容变大的默认行为覆盖我的更改。
我已经做了一个简单的示例,显示了我的程序的结构,如下所示,但是该示例仅尝试确保当面板在大小上翻倍时滚动时视口焦点保留在JPanel的底部。滚轮使JPanel的高度加倍/减半。
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;
import java.awt.event.MouseWheelEvent;
import java.awt.event.MouseWheelListener;
import javax.swing.*;
public class Test extends JFrame{
public static void main(String[] args){
Test t= new Test();
t.show();
}
public Test()
{
BorderLayout blm = new BorderLayout();
setLayout(blm);
getContentPane().add(new MyScroller(), BorderLayout.CENTER);
this.setPreferredSize(new Dimension(300, 300));
this.setMinimumSize(new Dimension(300, 300));
pack();
setLocationRelativeTo(null);
setVisible(true);
}
static class MyScroller extends JScrollPane implements MouseWheelListener
{
static InnerPanel controlGrid = new InnerPanel();
int panelHeight = 200;
public MyScroller()
{
super(controlGrid, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);
this.setBackground(Color.blue);
this.addMouseWheelListener(this);
this.setPreferredSize(new Dimension(300, 300));
this.setMinimumSize(new Dimension(300, 300));
}
@Override
public void revalidate()
{
super.revalidate();
if (controlGrid != null)
{
controlGrid.revalidate();
}
}
@Override
public void paintComponent(Graphics g)
{
super.paintComponent(g);
draw(g);
}
public void draw(Graphics g)
{
}
public void mouseWheelMoved(MouseWheelEvent e) {
String message;
int direction = 1;
int notches = e.getWheelRotation();
if (notches < 0) {
panelHeight += panelHeight;
} else {
panelHeight -= (panelHeight > panelHeight ? panelHeight : 0);
}
controlGrid.setPreferredSize(new Dimension(20, panelHeight));
controlGrid.setMinimumSize(new Dimension(20, panelHeight));
repaint();
this.getViewport().setViewPosition(new java.awt.Point(0, panelHeight));
}
static class InnerPanel extends JPanel
{
public InnerPanel(){
this.setBackground(Color.red);
this.setPreferredSize(new Dimension(100, 600));
this.setMinimumSize(new Dimension(100, 600));
}
}
}
}