Java 使用FlowLayout的面板不能包含JScrollPanes?
我一开始就是这么做的Java 使用FlowLayout的面板不能包含JScrollPanes?,java,swing,jpanel,jscrollpane,layout-manager,Java,Swing,Jpanel,Jscrollpane,Layout Manager,我一开始就是这么做的 public class MyFrame extends JFrame { public MyFrame() { setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); setPreferredSize(new Dimension(500 ,300)); setResizable(false); pack(); setLocationRelati
public class MyFrame extends JFrame {
public MyFrame() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(500 ,300));
setResizable(false);
pack();
setLocationRelativeTo(null);
initComponents();
}
private void initComponents() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
for (int i=0; i < 100; i++)
panel.add(new JLabel("some text"));
JScrollPane scrollPane = new JScrollPane(panel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
// Here I create a JPanel to replace the contentPane of JFrame
JPanel contentPane = new JPanel();
contentPane.add(scrollPane);
setContentPane(contentPane);
}
一切都好。但正如我之前所做的,垂直滚动条没有显示出来。这是什么原因造成的?将JPanel设置为contentPane是否错误
更新:
如果contentPane更改为BorderLayout,则一切正常
// Here I create a JPanel to replace the contentPane of JFrame
JPanel contentPane = new JPanel(new BorderLayout());
contentPane.add(scrollPane);
setContentPane(contentPane);
那么问题是默认的FlowLayout
已解决:
问题在于流程布局。它环绕JScrollPane并隐藏工具栏。使用
scrollPane.setPreferredSize(new Dimension(500, 400)); // longer space in x-axis
解决它
答复:
JSrollPane不应在使用FlowLayout的容器中使用。在添加面板后,必须使用
pack()
函数更新框架。当你这样做的时候
getContentPane().add(scrollPane);
功能
add
为您完成此操作()在添加面板后,您必须使用pack()
功能更新框架。当你这样做的时候
getContentPane().add(scrollPane);
功能
add
为您完成此操作()在添加面板后,您必须使用pack()
功能更新框架。当你这样做的时候
getContentPane().add(scrollPane);
功能
add
为您完成此操作()在添加面板后,您必须使用pack()
功能更新框架。当你这样做的时候
getContentPane().add(scrollPane);
函数
add
为您做到了这一点()首先,使用您自己的组件作为内容窗格没有什么不好的。但默认内容窗格也是一个JPanel实例,所以实际上没有必要用您自己的面板替换它,除非您想使用非面板内容窗格或自定义面板组件
这是默认内容窗格的外观:
/**
* Called by the constructor methods to create the default
* <code>contentPane</code>.
* By default this method creates a new <code>JComponent</code> add sets a
* <code>BorderLayout</code> as its <code>LayoutManager</code>.
* @return the default <code>contentPane</code>
*/
protected Container createContentPane() {
JComponent c = new JPanel();
c.setName(this.getName()+".contentPane");
c.setLayout(new BorderLayout() {
/* This BorderLayout subclass maps a null constraint to CENTER.
* Although the reference BorderLayout also does this, some VMs
* throw an IllegalArgumentException.
*/
public void addLayoutComponent(Component comp, Object constraints) {
if (constraints == null) {
constraints = BorderLayout.CENTER;
}
super.addLayoutComponent(comp, constraints);
}
});
return c;
}
此方法取自JRootPane。它基本上是一个简单的JPanel,具有定制的布局管理器,如您所见
现在,您的示例中有一些问题
首先是调用的顺序-在将内容添加到框架之前,您要调整框架的大小。只需更改顺序,您将看到您的滚动窗格:
public class MyFrame extends JFrame
{
public MyFrame ()
{
super();
// Add components first
initComponents ();
// Setup frame after so it fits its new content
setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
setPreferredSize ( new Dimension ( 500, 300 ) );
setResizable ( false );
pack ();
setLocationRelativeTo ( null );
}
private void initComponents ()
{
JPanel panel = new JPanel ();
panel.setLayout ( new BoxLayout ( panel, BoxLayout.Y_AXIS ) );
for ( int i = 0; i < 100; i++ )
{
panel.add ( new JLabel ( "some text" ) );
}
JScrollPane scrollPane =
new JScrollPane ( panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
// Here I create a JPanel to replace the contentPane of JFrame
JPanel contentPane = new JPanel ();
contentPane.add ( scrollPane );
setContentPane ( contentPane );
}
public static void main ( String[] args )
{
SwingUtilities.invokeLater ( new Runnable ()
{
public void run ()
{
new MyFrame ().setVisible ( true );
}
} );
}
}
首先,使用您自己的组件作为内容窗格并没有什么不好的。但默认内容窗格也是一个JPanel实例,所以实际上没有必要用您自己的面板替换它,除非您想使用非面板内容窗格或自定义面板组件 这是默认内容窗格的外观:
/**
* Called by the constructor methods to create the default
* <code>contentPane</code>.
* By default this method creates a new <code>JComponent</code> add sets a
* <code>BorderLayout</code> as its <code>LayoutManager</code>.
* @return the default <code>contentPane</code>
*/
protected Container createContentPane() {
JComponent c = new JPanel();
c.setName(this.getName()+".contentPane");
c.setLayout(new BorderLayout() {
/* This BorderLayout subclass maps a null constraint to CENTER.
* Although the reference BorderLayout also does this, some VMs
* throw an IllegalArgumentException.
*/
public void addLayoutComponent(Component comp, Object constraints) {
if (constraints == null) {
constraints = BorderLayout.CENTER;
}
super.addLayoutComponent(comp, constraints);
}
});
return c;
}
此方法取自JRootPane。它基本上是一个简单的JPanel,具有定制的布局管理器,如您所见
现在,您的示例中有一些问题
首先是调用的顺序-在将内容添加到框架之前,您要调整框架的大小。只需更改顺序,您将看到您的滚动窗格:
public class MyFrame extends JFrame
{
public MyFrame ()
{
super();
// Add components first
initComponents ();
// Setup frame after so it fits its new content
setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
setPreferredSize ( new Dimension ( 500, 300 ) );
setResizable ( false );
pack ();
setLocationRelativeTo ( null );
}
private void initComponents ()
{
JPanel panel = new JPanel ();
panel.setLayout ( new BoxLayout ( panel, BoxLayout.Y_AXIS ) );
for ( int i = 0; i < 100; i++ )
{
panel.add ( new JLabel ( "some text" ) );
}
JScrollPane scrollPane =
new JScrollPane ( panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
// Here I create a JPanel to replace the contentPane of JFrame
JPanel contentPane = new JPanel ();
contentPane.add ( scrollPane );
setContentPane ( contentPane );
}
public static void main ( String[] args )
{
SwingUtilities.invokeLater ( new Runnable ()
{
public void run ()
{
new MyFrame ().setVisible ( true );
}
} );
}
}
首先,使用您自己的组件作为内容窗格并没有什么不好的。但默认内容窗格也是一个JPanel实例,所以实际上没有必要用您自己的面板替换它,除非您想使用非面板内容窗格或自定义面板组件 这是默认内容窗格的外观:
/**
* Called by the constructor methods to create the default
* <code>contentPane</code>.
* By default this method creates a new <code>JComponent</code> add sets a
* <code>BorderLayout</code> as its <code>LayoutManager</code>.
* @return the default <code>contentPane</code>
*/
protected Container createContentPane() {
JComponent c = new JPanel();
c.setName(this.getName()+".contentPane");
c.setLayout(new BorderLayout() {
/* This BorderLayout subclass maps a null constraint to CENTER.
* Although the reference BorderLayout also does this, some VMs
* throw an IllegalArgumentException.
*/
public void addLayoutComponent(Component comp, Object constraints) {
if (constraints == null) {
constraints = BorderLayout.CENTER;
}
super.addLayoutComponent(comp, constraints);
}
});
return c;
}
此方法取自JRootPane。它基本上是一个简单的JPanel,具有定制的布局管理器,如您所见
现在,您的示例中有一些问题
首先是调用的顺序-在将内容添加到框架之前,您要调整框架的大小。只需更改顺序,您将看到您的滚动窗格:
public class MyFrame extends JFrame
{
public MyFrame ()
{
super();
// Add components first
initComponents ();
// Setup frame after so it fits its new content
setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
setPreferredSize ( new Dimension ( 500, 300 ) );
setResizable ( false );
pack ();
setLocationRelativeTo ( null );
}
private void initComponents ()
{
JPanel panel = new JPanel ();
panel.setLayout ( new BoxLayout ( panel, BoxLayout.Y_AXIS ) );
for ( int i = 0; i < 100; i++ )
{
panel.add ( new JLabel ( "some text" ) );
}
JScrollPane scrollPane =
new JScrollPane ( panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
// Here I create a JPanel to replace the contentPane of JFrame
JPanel contentPane = new JPanel ();
contentPane.add ( scrollPane );
setContentPane ( contentPane );
}
public static void main ( String[] args )
{
SwingUtilities.invokeLater ( new Runnable ()
{
public void run ()
{
new MyFrame ().setVisible ( true );
}
} );
}
}
首先,使用您自己的组件作为内容窗格并没有什么不好的。但默认内容窗格也是一个JPanel实例,所以实际上没有必要用您自己的面板替换它,除非您想使用非面板内容窗格或自定义面板组件 这是默认内容窗格的外观:
/**
* Called by the constructor methods to create the default
* <code>contentPane</code>.
* By default this method creates a new <code>JComponent</code> add sets a
* <code>BorderLayout</code> as its <code>LayoutManager</code>.
* @return the default <code>contentPane</code>
*/
protected Container createContentPane() {
JComponent c = new JPanel();
c.setName(this.getName()+".contentPane");
c.setLayout(new BorderLayout() {
/* This BorderLayout subclass maps a null constraint to CENTER.
* Although the reference BorderLayout also does this, some VMs
* throw an IllegalArgumentException.
*/
public void addLayoutComponent(Component comp, Object constraints) {
if (constraints == null) {
constraints = BorderLayout.CENTER;
}
super.addLayoutComponent(comp, constraints);
}
});
return c;
}
此方法取自JRootPane。它基本上是一个简单的JPanel,具有定制的布局管理器,如您所见
现在,您的示例中有一些问题
首先是调用的顺序-在将内容添加到框架之前,您要调整框架的大小。只需更改顺序,您将看到您的滚动窗格:
public class MyFrame extends JFrame
{
public MyFrame ()
{
super();
// Add components first
initComponents ();
// Setup frame after so it fits its new content
setDefaultCloseOperation ( JFrame.EXIT_ON_CLOSE );
setPreferredSize ( new Dimension ( 500, 300 ) );
setResizable ( false );
pack ();
setLocationRelativeTo ( null );
}
private void initComponents ()
{
JPanel panel = new JPanel ();
panel.setLayout ( new BoxLayout ( panel, BoxLayout.Y_AXIS ) );
for ( int i = 0; i < 100; i++ )
{
panel.add ( new JLabel ( "some text" ) );
}
JScrollPane scrollPane =
new JScrollPane ( panel, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER );
// Here I create a JPanel to replace the contentPane of JFrame
JPanel contentPane = new JPanel ();
contentPane.add ( scrollPane );
setContentPane ( contentPane );
}
public static void main ( String[] args )
{
SwingUtilities.invokeLater ( new Runnable ()
{
public void run ()
{
new MyFrame ().setVisible ( true );
}
} );
}
}
首先,创建第二个小组的原因是什么?那里 已经是第一个将
BoxLayout
作为布局的面板
经理台。只需设置具有第一个面板的滚动窗格
正如父母所期望的那样
你要么打电话
setContentPane(scrollPane);
或
现在我将解释是什么导致了这种意外行为。这
这种怪癖有时会发生在使用嵌套技术的人身上
在构建它们的布局时。使用嵌套时,布局可能会
相互影响
通过选择另一个布局--FlowLayout
--作为基础基础布局,
您使第一个面板以其首选大小显示。相反
在一个面板中,现在有两个面板,基础面板影响
带标签的面板--它控制其大小。FlowLayout
以首选大小显示其所有子项;它既不尊重咪咪也不尊重她
最大尺寸。因此(第一个)可见面板的大小可以显示其所有标签;
这是首选大小的计算方式——刚好足够大,可以显示其所有属性
儿童然而,有100个标签,它是非常大的;布局被破坏了。它是
垂直方向如此之大以至于我们实际上无法到达窗户的底部
因此,我们的可视面板显示所有标签,显示的目的是什么
滚动条?不需要,因为所有标签都“可见”(放置在
窗户区域),尽管设计已损坏
所以问题不在于滚动条;他们工作正常。如果你
(在您的示例中)将垂直滚动条策略设置为始终vertical\u scrollbar\u
您将看到滚动条,但没有滑块,因为所有标签都“可见”
而且没有任何东西可以滚动。(滚动条显示隐藏在屏幕上的项目。)
布局。)问题在于FlowLayout
仅以首选尺寸显示其组件
以下是一个按预期工作的固定代码示例:
package com.zetcode;
import java.awt.Dimension;
import java.awt.EventQueue;
import javax.swing.BoxLayout;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.ScrollPaneConstants;
public class MyFrame extends JFrame {
public MyFrame() {
initComponents();
setTitle("Scrollbar");
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setPreferredSize(new Dimension(300, 200));
pack();
setLocationRelativeTo(null);
}
private void initComponents() {
JPanel panel = new JPanel();
panel.setLayout(new BoxLayout(panel, BoxLayout.Y_AXIS));
for (int i=0; i < 100; i++)
panel.add(new JLabel("some text"));
JScrollPane scrollPane = new JScrollPane(panel,
ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED,
ScrollPaneConstants.HORIZONTAL_SCROLLBAR_AS_NEEDED);
setContentPane(scrollPane);
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
MyFrame ex = new MyFrame();
ex.setVisible(true);
}
});
}
}
package com.zetcode;
导入java.awt.Dimension;
导入java.awt.EventQueue;
导入javax.swing.BoxLayout;
导入javax.swing.JFrame;
进口ja