我的可调整大小的JScrollPane的内容具有最小宽度.如果JScrollPane小于此宽度,则应显示水平滚动条.如果它大于此宽度,则应扩展视口内容以填满整个视口.
看起来像一个简单的概念,我有一些工作,但它感觉像一个黑客:
import javax.swing.*; import java.awt.*; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; public class SSBTest { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { final Component view = new MyView(); final JScrollPane jScrollPane = new JScrollPane(view); jScrollPane.addComponentListener(new ComponentAdapter() { @Override public void componentResized(final ComponentEvent e) { final Dimension minimumSize = view.getMinimumSize(); final int width = Math.max(minimumSize.width,jScrollPane.getViewport().getWidth()); view.setPreferredSize(new Dimension(width,minimumSize.height)); } }); showInDialog(jScrollPane); } }); } private static void showInDialog(final JScrollPane jScrollPane) { final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test"); dialog.setResizable(true); dialog.setModal(true); dialog.setVisible(true); System.exit(0); } private static final class MyView extends JPanel { @Override protected void paintComponent(final Graphics g) { super.paintComponent(g); g.setColor(Color.RED); g.drawString("Dimensions are " + getSize(),10,20); g.drawRect(0,getMinimumSize().width-1,getMinimumSize().height-1); g.setColor(Color.BLUE); g.drawRect(0,getPreferredSize().width-1,getPreferredSize().height-1); } @Override public Dimension getMinimumSize() { return new Dimension(200,200); } @Override public Dimension getPreferredSize() { return super.getPreferredSize(); } } }
调整对话框的大小触发ComponentListener,它显式地设置视口视图的首选大小,触发组件验证.然而,调整大小会导致抖动滚动条.有没有更清洁的方法来做到这一点?
编辑:感谢camickr的ScrollablePanel链接,我修改了我的JPanel类来实现Scrollable,并动态地更改getScrollableTracksViewportWidth()的返回值.
当视口大时,我返回true为getScrollableTracksViewportWidth(),告诉JScrollPane填充视图与我的组件.当视口很小时,我返回false,所以滚动条出现.
import javax.swing.*; import java.awt.*; public class SSBTest { public static void main(String[] args) { SwingUtilities.invokeLater(new Runnable() { public void run() { final Component view = new MyView(); final JScrollPane jScrollPane = new JScrollPane(view); showInDialog(jScrollPane); } }); } private static void showInDialog(final JScrollPane jScrollPane) { final JDialog dialog = new JOptionPane(jScrollPane).createDialog("JScrollPane Resize Test"); dialog.setResizable(true); dialog.setModal(true); dialog.setVisible(true); System.exit(0); } private static final class MyView extends JPanel implements Scrollable { @Override protected void paintComponent(final Graphics g) { super.paintComponent(g); g.setColor(Color.RED); g.drawString("MyView: " + getWidth() + "x" + getHeight(),getPreferredSize().height-1); g.drawString("Preferred/Minimum Size",getPreferredSize().height/2); g.setColor(Color.GREEN); g.drawLine(0,getWidth(),getHeight()); } @Override public Dimension getMinimumSize() { return new Dimension(200,200); } @Override public Dimension getPreferredSize() { return getMinimumSize(); } public Dimension getPreferredScrollableViewportSize() { return getPreferredSize(); } public int getScrollableUnitIncrement(final Rectangle visibleRect,final int orientation,final int direction) { return 10; } public int getScrollableBlockIncrement(final Rectangle visibleRect,final int direction) { return visibleRect.width; } public boolean getScrollableTracksViewportWidth() { final Container viewport = getParent(); return viewport.getWidth() > getMinimumSize().width; } public boolean getScrollableTracksViewportHeight() { return true; } } }
解决方法
不确定,但您可能可以使用
Scrollable Panel.您可以配置组件调整大小(尝试使用STRETCH).代码适用于组件的首选大小,而不是最小尺寸,因此可能并不完全符合您的要求.