在左上角对齐ScrollPane的困难

时间:2015-01-13 15:27:35

标签: java swing layout

问题是,如何将JScrollPane与resizeble JPane对齐,使其与左上角而不是中心对齐?

这感觉就像是一项明显的任务,但我花了好几个小时尝试所有不同的布局和属性。

可以表达挫折感,因为我只能提出两种选择:

  1. 使用尊重儿童最大首选尺寸的布局FlowLayout为例。副作用 - ScrollPane开始表现得像是Panel
  2. enter image description here

    1. 使用可伸展布局,例如BorderLayout,并将元素放入BorderLayout.CENTERBorderLayout.PAGE_START导致 1。)。我失去了对Panel的位置的控制权,它在中心:
    2. enter image description here

      当窗口很小时,滚动按预期工作:

      enter image description here


      是否可以同时拥有这两个世界:JScrollPane不会延伸beyound最大首选大小,但不会丢失 Scroll

      如果有人需要源代码:

      import java.awt.BorderLayout;
      import java.awt.Dimension;
      import java.awt.GridBagConstraints;
      import java.awt.GridBagLayout;
      
      import javax.swing.JComponent;
      import javax.swing.JFrame;
      import javax.swing.JLabel;
      import javax.swing.JPanel;
      import javax.swing.JScrollPane;
      import javax.swing.JTabbedPane;
      
      public class MainPanelTest extends JFrame {
      
      
          public static void main(String[] args)  {
              new MainPanelTest().setVisible(true);
          }
      
          public MainPanelTest()  {
              super();
              this.setLayout(new BorderLayout());
      
              setupGUI();
          }
      
          private void setupGUI() {
              JTabbedPane tabbedPane = new JTabbedPane();
              tabbedPane.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT);
              this.add(tabbedPane, BorderLayout.CENTER);
      
              JComponent filesPanel = setupFilesPanel();
              tabbedPane.addTab("Files", filesPanel);
      
              JPanel secondPanel = new JPanel();
              tabbedPane.addTab("Placeholder", secondPanel);
      
          }
      
          private JComponent setupFilesPanel() {
              JPanel filesPanel = new JPanel();
              filesPanel.setLayout(new GridBagLayout());
              GridBagConstraints c = new GridBagConstraints();
              c.anchor = GridBagConstraints.NORTHWEST;
              for(int i=0; i<15; i++) {
                  c.gridy = i;
                  filesPanel.add(new JLabel("Test row " + i), c);
              }       
      
              JScrollPane scrollFilesPane = new JScrollPane(filesPanel);
              scrollFilesPane.setMaximumSize(scrollFilesPane.getPreferredSize());
              return scrollFilesPane;
          }
      
      }
      

2 个答案:

答案 0 :(得分:2)

GridBagLayout将空间划分为组件所在的逻辑单元格。仅当逻辑单元格大于其组件时,anchor才有意义。如果同一行/列中的组件需要更大的大小或者存在额外空间且关联的weightxweighty值不为零,则可能发生这种情况。由于您所需的行为与额外空间有关,因此您必须相应地设置权重值。唯一列的weightx不为零,但最后一行的weighty非零,只占用其下方的整个空间:

GridBagLayout gridBagLayout = new GridBagLayout();
JPanel filesPanel = new JPanel(gridBagLayout);
GridBagConstraints c = new GridBagConstraints();
c.gridx = GridBagConstraints.REMAINDER;
c.anchor = GridBagConstraints.NORTHWEST;

c.weightx = 1; // for the column
for(int i=0; i<15; i++)
    filesPanel.add(new JLabel("Test row " + i), c);

// now change the last row:
c.weighty = 1;
gridBagLayout.setConstraints(
  filesPanel.getComponent(filesPanel.getComponentCount()-1), c);

或者你可以不修改单元格,但是通过添加一个空的额外行和列来消耗整个布局,消耗额外的空间,这将有效地将原始行和列移动到左上角:

// add all visible components which should not grow
GridBagLayout gridBagLayout = new GridBagLayout();
JPanel filesPanel = new JPanel(gridBagLayout);
GridBagConstraints c = new GridBagConstraints();
c.gridx = GridBagConstraints.REMAINDER;
for(int i=0; i<15; i++)
    filesPanel.add(new JLabel("Test row " + i), c);

// add an extra row consuming vertical extra space
int nRows=filesPanel.getComponentCount();
gridBagLayout.rowHeights=new int[nRows+1];
gridBagLayout.rowWeights=new double[nRows+1];
gridBagLayout.rowWeights[nRows]=1;
// add an extra column consuming extra horizontal space
gridBagLayout.columnWidths=new int[] { 0, 0 };
gridBagLayout.columnWeights=new double[] { 0, 1 };

答案 1 :(得分:1)

看看这是否是你想要实现的目标:

private JComponent setupFilesPanel() {
    JPanel filesPanel = new JPanel();
    filesPanel.setLayout(new GridBagLayout());
    GridBagConstraints c = new GridBagConstraints();
    c.anchor = GridBagConstraints.NORTHWEST;
    for(int i=0; i<15; i++) {
        c.gridy = i;
        filesPanel.add(new JLabel("Test row " + i), c);
    }       

    // ---- Add this
    JPanel newPanel = new JPanel(new GridBagLayout());
    c.weightx = 1;
    c.weighty = 1;
    newPanel.setBackground(Color.yellow);
    newPanel.add(filesPanel, c);
    // ----

    // ---- change the panel you pass to JScrollPanel constructor:
    JScrollPane scrollFilesPane = new JScrollPane(newPanel); // <--------- newPanel
    scrollFilesPane.setMaximumSize(scrollFilesPane.getPreferredSize());
    return scrollFilesPane;
}

对评论进行了评论。