java JScrollpane 使用可变大小的内容调整大小
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/4951560/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
JScrollpane resizing with variable-sized content
提问by Sam Barnum
My resizable JScrollPane's content has a minimum width. If the JScrollPane is smaller than this width, horizontal scroll bars should appear. If it's greater than this width, the viewport content should expand to fill up the entire viewport.
我的可调整大小的 JScrollPane 的内容具有最小宽度。如果 JScrollPane 小于此宽度,则应出现水平滚动条。如果它大于此宽度,则视口内容应扩展以填满整个视口。
Seems like a simple concept, and I've got something that's working, but it feels like a hack:
似乎是一个简单的概念,我有一些可行的方法,但感觉就像一个黑客:
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, 0, getMinimumSize().width-1, getMinimumSize().height-1);
g.setColor(Color.BLUE);
g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1);
}
@Override
public Dimension getMinimumSize() {
return new Dimension(200, 200);
}
@Override
public Dimension getPreferredSize() {
return super.getPreferredSize();
}
}
}
Resizing the dialog triggers the ComponentListener, which explicitly sets the preferred size of the viewport view, triggering component validation. However, resizing causes jittery scroll bars. Is there a cleaner way to do this?
调整对话框大小会触发 ComponentListener,它显式设置视口视图的首选大小,从而触发组件验证。但是,调整大小会导致滚动条抖动。有没有更干净的方法来做到这一点?
EDIT:thanks to camickr for the ScrollablePanel link, I've modified my JPanel class to implement Scrollable, and dynamically change the return value for getScrollableTracksViewportWidth().
编辑:感谢 camickr 提供 ScrollablePanel 链接,我修改了我的 JPanel 类以实现 Scrollable,并动态更改 getScrollableTracksViewportWidth() 的返回值。
When the viewport is big, I return true
for getScrollableTracksViewportWidth()
, telling the JScrollPane to fill the view with my component. When the viewport is small, I return false
, so the scrollbars appear.
当视口很大时,我返回true
for 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(), 10, 20);
g.drawRect(0, 0, getMinimumSize().width-1, getMinimumSize().height-1);
g.setColor(Color.BLUE);
g.drawRect(0, 0, getPreferredSize().width-1, getPreferredSize().height-1);
g.drawString("Preferred/Minimum Size", 10, getPreferredSize().height/2);
g.setColor(Color.GREEN);
g.drawLine(0, 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 orientation, final int direction) {
return visibleRect.width;
}
public boolean getScrollableTracksViewportWidth() {
final Container viewport = getParent();
return viewport.getWidth() > getMinimumSize().width;
}
public boolean getScrollableTracksViewportHeight() {
return true;
}
}
}
采纳答案by camickr
Not sure, but you might be able to use the Scrollable Panel. You can configure the component resizing (try using STRETCH). The code works on the preferred size of the component not the minimum size so it may not be exactly what you want.
不确定,但您可以使用Scrollable Panel。您可以配置组件调整大小(尝试使用 STRETCH)。该代码适用于组件的首选大小,而不是最小大小,因此它可能不是您想要的。