带有Frozen和Scrollable组件的JScrollPane列标题

时间:2014-01-23 04:49:05

标签: java swing jscrollpane

我有一个JScrollPane,其列标题由多个组件组成。其中一个组件需要静态定位,而其他组件需要像平常一样滚动。

我唯一想到的就是在滚动条上添加一个监听器,它设置冻结组件的位置,如下所示:

frozenHeader.setLocation(scrollViewport.getVisibleRect().getLocation()).  

但是,在滚动条不长滚动之前,该位置实际上不会更新,因此它看起来相当不吸引人。是的,我尝试在revalidate()及其父级repaint()上调用frozenHeader后跟import java.awt.Color; import java.awt.Dimension; import java.awt.GridBagConstraints; import java.awt.GridBagLayout; import javax.swing.JFrame; import javax.swing.JPanel; import javax.swing.JScrollPane; /** * * @author brian */ public class TestScroll extends JFrame { private JScrollPane scrollPane; private JPanel viewport; private JPanel colHeader; // This should be frozen private JPanel frozenHeader; // This should scroll private JPanel scrollHeader; public TestScroll() { this.setSize(new Dimension(500, 400)); this.setResizable(false); this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); // Set up the scroll pane scrollPane = new JScrollPane(); viewport = new JPanel(); viewport.setPreferredSize(new Dimension(1000, 400)); scrollPane.setViewportView(viewport); // Set up the scroll panes column header colHeader = new JPanel(new GridBagLayout()); frozenHeader = new JPanel(); // Width is equal to the frame's width, as it should stay in the same location frozenHeader.setPreferredSize(new Dimension(500, 30)); frozenHeader.setBackground(Color.RED); scrollHeader = new JPanel(); // Width equal to viewportview's as it should scroll scrollHeader.setPreferredSize(new Dimension(1000, 30)); scrollHeader.setBackground(Color.BLUE); JLabel label = new JLabel("Text"); scrollHeader.add(label); GridBagConstraints c = new GridBagConstraints(); c.anchor = GridBagConstraints.WEST; c.gridx = 0; c.gridy = 0; colHeader.add(frozenHeader, c); c.gridy = 1; colHeader.add(scrollHeader, c); scrollPane.setColumnHeaderView(colHeader); add(scrollPane); } public static void main(String args[]) { java.awt.EventQueue.invokeLater(new Runnable() { public void run() { new TestScroll().setVisible(true); } }); } }

以下是重现我所说的内容的示例:

frozenHeader

我希望scrollHeader(红色面板)始终在屏幕中居中而不是滚动屏幕,scrollHeader(蓝色面板)继续滚动,就像在示例中一样

要添加更多上下文,我之所以不是简单地将frozenHeader放在视口中,或将JScrollPane移出列标题而只是将其放在JScrollPane上方是因为我的实际应用程序中的{{1}}有一个左上角面板,它与列标题的高度相同。由于应用程序的性质,我需要利用所有的屏幕空间。

非常感谢有关如何实现这一目标的任何建议!

1 个答案:

答案 0 :(得分:1)

  

“我希望红色面板始终位于屏幕中央,而不是滚动屏幕。”

问题是您正在设置columnHeaderView。这可以轻松完成,但只需将colHeader面板添加为独立实体,设置columnHeaderView

    colHeader = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
    colHeader.add(frozenHeader);
    JPanel panelForScrollPaneAndScrollHeader = new JPanel(new BorderLayout());
    panelForScrollPaneAndScrollHeader.add(scrollHeader, BorderLayout.NORTH);
    panelForScrollPaneAndScrollHeader.add(scrollPane, BorderLayout.CENTER);

    add(colHeader, BorderLayout.NORTH);
    add(panelForScrollPaneAndScrollHeader, BorderLayout.CENTER);

执行此操作时的结果

enter image description here

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.FlowLayout;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;

public class TestScroll1 extends JFrame{
    private JScrollPane scrollPane;
    private JPanel viewport;
    private JPanel colHeader;
    private JPanel frozenHeader;
    private JPanel scrollHeader;

    public TestScroll1() {
        frozenHeader = new JPanel();
        frozenHeader.setPreferredSize(new Dimension(500, 30));
        frozenHeader.setBackground(Color.RED);

        scrollHeader = new JPanel();
        scrollHeader.setPreferredSize(new Dimension(1000, 30));
        scrollHeader.setBackground(Color.BLUE);

        scrollPane = new JScrollPane();
        viewport = new JPanel();
        viewport.setPreferredSize(new Dimension(1000, 400));
        scrollPane.setViewportView(viewport);


        colHeader = new JPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
        colHeader.add(frozenHeader);
        JPanel panelForScrollPaneAndScrollHeader = new JPanel(new BorderLayout());
        panelForScrollPaneAndScrollHeader.add(scrollHeader, BorderLayout.NORTH);
        panelForScrollPaneAndScrollHeader.add(scrollPane, BorderLayout.CENTER);
        add(colHeader, BorderLayout.NORTH);
        add(panelForScrollPaneAndScrollHeader, BorderLayout.CENTER);


        setSize(new Dimension(500, 400));
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setLocationRelativeTo(null);

    }

    public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new TestScroll1().setVisible(true);
            }
        });
    }
}