2012-05-02 51 views
8

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

回答

12

在ViewPort上使用更改侦听器似乎适用于我。这里是一个小的演示:

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(); 
    } 
} 
+0

好, 奇怪的。感谢您的快速回复。我试过了,确实有效。唉,在我的应用程序中,添加更改侦听器不起作用。我会从这里工作。 – xmjx

+0

对于一些奇怪的原因,输出到stdout和stderr都不会显示在侦听器中。所以它基本上是一个调试问题。再次感谢。 – xmjx

1

我用HierarchyBoundsListener来检测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); 
     } 
    }); 
}