Java 如何检测JScrollPane';s滚动条更改可见性?

Java 如何检测JScrollPane';s滚动条更改可见性?,java,swing,jscrollpane,jscrollbar,Java,Swing,Jscrollpane,Jscrollbar,我有一个JScrollPane,它在水平行中包含一些图像。如果图像行对于视图端口太长,JScrollPane会显示一个滚动条,从而降低视图端口的高度。我想调整图像大小以适应视图端口。如何检测视图端口更改了其大小?不幸的是,注册更改事件处理程序似乎不起作用 在视口中使用change listener似乎适合我。下面是一个小演示: import java.awt.BorderLayout; import java.io.UnsupportedEncodingException; import ja

我有一个JScrollPane,它在水平行中包含一些图像。如果图像行对于视图端口太长,JScrollPane会显示一个滚动条,从而降低视图端口的高度。我想调整图像大小以适应视图端口。如何检测视图端口更改了其大小?不幸的是,注册更改事件处理程序似乎不起作用

在视口中使用change listener似乎适合我。下面是一个小演示:

import java.awt.BorderLayout;
import java.io.UnsupportedEncodingException;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.SwingWorker;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

public class Main {

    public static void main(String[] args) throws UnsupportedEncodingException {
        JFrame frame = new JFrame();
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        JPanel panel = new JPanel(new BorderLayout());
        final JPanel buttons = new JPanel();
        final JScrollPane pane = new JScrollPane(buttons);
        pane.getViewport().addChangeListener(new ChangeListener() {

            @Override
            public void stateChanged(ChangeEvent e) {
                System.err.println("Change in " + e.getSource());
                System.err.println("Vertical visible? " + pane.getVerticalScrollBar().isVisible());
                System.err.println("Horizontal visible? " + pane.getHorizontalScrollBar().isVisible());
            }
        });
        panel.add(pane);
        frame.setContentPane(panel);
        frame.setSize(300, 200);
        frame.setVisible(true);
        SwingWorker<Void, Void> worker = new SwingWorker<Void, Void>() {

            @Override
            protected Void doInBackground() throws Exception {
                for (int i = 0; i < 10; i++) {
                    Thread.sleep(800);
                    buttons.add(new JButton("Hello " + i));
                    buttons.revalidate();
                }
                return null;
            }
        };
        worker.execute();
    }
}
导入java.awt.BorderLayout;
导入java.io.UnsupportedEncodingException;
导入javax.swing.JButton;
导入javax.swing.JFrame;
导入javax.swing.JPanel;
导入javax.swing.JScrollPane;
导入javax.swing.SwingWorker;
导入javax.swing.event.ChangeEvent;
导入javax.swing.event.ChangeListener;
公共班机{
公共静态void main(字符串[]args)引发UnsupportedEncodingException{
JFrame=新JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel panel=newjpanel(newborderlayout());
最终JPanel按钮=新JPanel();
最终JScrollPane=新JScrollPane(按钮);
pane.getViewport().addChangeListener(新的ChangeListener()){
@凌驾
公共无效状态已更改(更改事件e){
System.err.println(“在“+e.getSource()中的更改”);
System.err.println(“垂直可见?”+pane.getVerticalScrollBar().isVisible());
System.err.println(“水平可见?”+pane.getHorizontalScrollBar().isVisible());
}
});
面板。添加(面板);
frame.setContentPane(面板);
框架。设置尺寸(300200);
frame.setVisible(true);
SwingWorker worker=新SwingWorker(){
@凌驾
受保护的Void doInBackground()引发异常{
对于(int i=0;i<10;i++){
睡眠(800);
添加(新的JButton(“Hello”+i));
按钮。重新验证();
}
返回null;
}
};
worker.execute();
}
}
我使用检测JScrollPane大小的变化:

onAncestorResized(scroll, evt -> resizeYourImages());
下面是附加侦听器的一种方便方法:

static void onAncestorResized(JComponent component, Consumer<HierarchyEvent> callback) {
    component.addHierarchyBoundsListener(new HierarchyBoundsAdapter() {
        @Override
        public void ancestorResized(HierarchyEvent e) {
            callback.accept(e);
        }
    });
}
静态无效onAncestorResized(JComponent组件,使用者回调){
addHierarchyBoundsListener(新的HierarchyBoundsAdapter(){
@凌驾
已取消存储大小调整的公共空间(分层事件e){
接受(e);
}
});
}

好吧,奇怪。谢谢你的快速回复。我试过了,确实有效。唉,在我的应用程序中,添加更改侦听器是不起作用的。我将从这里开始工作。出于某种奇怪的原因,到stdout和stderr的输出都没有显示在侦听器中。所以这基本上是一个调试问题。再次感谢。