2016-12-20 105 views
1

我正在尝试使用swing创建可滚动面板。但是因为我是新手,所以我没有这样做。在我的代码中,没有任何内容显示在jScrollablePane内。Java Swing - 可滚动面板

我创建了一个的JFrame并投入jScrollablePane里面。我创建了一个名为UIElement的类,该类扩展了jPanel,其中包含组件部分和子部分。儿童部分由其他UIElement s组成。

  • 所有UI元素应划归以前的UIElement。就像一个垂直列表。
  • 孩子应该放置在组件
  • 孩子节不能滚动,其高度固定为儿童UIElements的总高度。
  • 组件的固定高度为40.虽然宽度可以随其容器一起延伸。
  • 间隔的宽度应该被固定为40。
  • 除了从间隔,一切的宽度是动态的。
  • A UIElement可能有零个或更多的孩子。

下面是一些图片的例子,不要忘记:宽度是动态的。

enter image description here

这里是代码:

public static void scrollable(String title) { 
    //Create and set up the window. 
    JFrame frame = new JFrame(title); 
    frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
    frame.setSize(500,GraphicsEnvironment.getLocalGraphicsEnvironment().getMaximumWindowBounds().height); 

    JPanel mainPanel = new JPanel(); 
    mainPanel.setLayout(new BoxLayout(mainPanel,BoxLayout.Y_AXIS)); 
    mainPanel.setBackground(Color.WHITE); 

    mainPanel.add(new UIElement()); 

    JScrollPane scrollPane = new JScrollPane(mainPanel,JScrollPane.VERTICAL_SCROLLBAR_ALWAYS,ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); 
    frame.getContentPane().add(scrollPane); 

    //Display the window. 
    frame.setVisible(true); 
} 

这里是的UIElement类:

public abstract class UIElement extends JPanel { 
    public static final int DESIREDHEIGHT = 40; 

    JPanel componentsPanel, childPanel; 

    public UIElement() { 
     super(); 
     this.setLayout(new BoxLayout(this,BoxLayout.Y_AXIS)); 
     this.setBackground(Color.BLACK); 

     // componentsPanel 
     componentsPanel = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       Dimension d = super.getPreferredSize(); 
       d.setSize(d.getWidth(),DESIREDHEIGHT); 
       return d; 
      } 

      @Override 
      public Dimension getMaximumSize() { 
       Dimension d = super.getMaximumSize(); 
       d.setSize(d.getWidth(),DESIREDHEIGHT); 
       return d; 
      } 

      @Override 
      public Dimension getMinimumSize() { 
       Dimension d = super.getPreferredSize(); 
       d.setSize(d.getWidth(),DESIREDHEIGHT); 
       return d; 
      } 
     }; 
     componentsPanel.setLayout(new BoxLayout(componentsPanel,BoxLayout.X_AXIS)); 
     componentsPanel.setBackground(Color.BLUE); 
     this.add(componentsPanel); 

     // child panel 
     childPanel = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       float height = 0; 
       for (Component c: super.getComponents()) 
        height += c.getPreferredSize().height; 
       Dimension d = super.getPreferredSize(); 
       d.setSize(d.getWidth(),height); 
       return d; 
      } 

      @Override 
      public Dimension getMaximumSize() { 
       float height = 0; 
       for (Component c: super.getComponents()) 
        height += c.getMaximumSize().height; 
       Dimension d = super.getMaximumSize(); 
       d.setSize(d.getWidth(),height); 
       return d; 
      } 

      @Override 
      public Dimension getMinimumSize() { 
       float height = 0; 
       for (Component c: super.getComponents()) 
        height += c.getMinimumSize().height; 
       Dimension d = super.getMinimumSize(); 
       d.setSize(d.getWidth(),height); 
       return d; 
      } 
     }; 
     childPanel.setLayout(new BoxLayout(childPanel,BoxLayout.Y_AXIS)); 
     childPanel.setBackground(Color.RED); 

     // parent for childPanel and spacer 
     JPanel childParent = new JPanel(); 
     childParent.setLayout(new BoxLayout(childParent,BoxLayout.X_AXIS)); 

     // spacer 
     JPanel spacer = new JPanel() { 
      @Override 
      public Dimension getPreferredSize() { 
       return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT); 
      } 

      @Override 
      public Dimension getMaximumSize() { 
       return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT); 
      } 

      @Override 
      public Dimension getMinimumSize() { 
       return new Dimension(DESIREDHEIGHT,DESIREDHEIGHT); 
      } 
     }; 
     spacer.setBackground(Color.RED); 
     childParent.add(spacer); 
     // add the childPanel later 
     childParent.add(childPanel); 
    } 


    @Override 
    public Dimension getPreferredSize() { 
     Dimension c = componentsPanel.getPreferredSize(); 
     Dimension d = childPanel.getPreferredSize(); 
     return new Dimension(c.width, c.height + d.height); 
    } 

    @Override 
    public Dimension getMaximumSize() { 
     Dimension c = componentsPanel.getMaximumSize(); 
     Dimension d = childPanel.getMaximumSize(); 
     return new Dimension(c.width, c.height + d.height); 
    } 

    @Override 
    public Dimension getMinimumSize() { 
     Dimension c = componentsPanel.getMinimumSize(); 
     Dimension d = childPanel.getMinimumSize(); 
     return new Dimension(c.width, c.height + d.height); 
    } 

} 

回答

1

不要覆盖getPreferredSize()(或最大/微量大小)的面板。

每个面板将根据面板的布局管理器和添加到面板的组件确定其首选大小。

这就是说,如果面板使用布局管理器,则不需要重写这些方法。您只需要覆盖没有布局管理器的自定义组件的getPreferredSize()方法。在Swing中,这将是一个JButton,JTextField,JLabel等。

所以,如果你正在创建一个自定义组件,那么你设置了大小。如果您只是使用组件作为容器和布局管理器来容纳其他组件,那么您不会计算大小。

+0

https://docs.oracle.com/javase/tutorial/uiswing/layout/problems。html - 搜索单词“修复” – ossobuko

+0

删除了getPreferredSize()方法的所有覆盖项,没有工作 – ossobuko

+0

@ossobuko,您错过了我关于需要定义适当大小的“自定义组件”的观点。如果您使用的只是JPanel,那么层次结构底部的自定义面板需要适当的大小。在我看来使用BoxLayout的层次结构中间的面板不应该重写大小计算。 – camickr