2014-01-23 36 views
1

我有一个JScrollPane,其中包含由多个组件组成的列标题。其中一个组件需要静态定位,而其他组件需要像正常一样滚动。JScrollPane具有冻结和可滚动组件的列标题

我能想到做的唯一一件事就是添加一个侦听这台冷冻组件的这样的位置滚动条:

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

但是,位置实际上不会更新,直到滚动条没有长时间滚动,所以它看起来相当不吸引人。是的,我已经尝试在frozenHeader及其父母上拨打revalidate(),然后拨打repaint()

这里是重现什么我谈论的例子:

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(红色面板)始终在屏幕的滚动,而不是关闭屏幕居中,和(蓝色面板)继续滚动,如同在示例中一样。

要多添一点而言,我不是简单地把在视口中,或移动frozenHeader出列标题,并简单地将其置于JScrollPane以上的原因是因为我在实际应用中JScrollPane有上左角面板与列标题高度相同。由于应用程序的性质,我需要利用所有的屏幕空间。

任何有关如何完成这一任务的建议将不胜感激!

+0

啊,当结果,我想我需要看到一些示例代码,它复制了你正在谈论的内容...... – MadProgrammer

+0

你可以做的一种方法是,将可滚动的组件在JScrollPane中添加标题并将标题添加到JScrollPane顶部。我希望你指的是垂直滚动。 – jaks

+0

对不起,我更新了帖子,可滚动和固定的标题必须保留在标题中,因为我不能浪费屏幕空间。 – user1725940

回答

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); 
      } 
     }); 
    } 
} 
+0

在你的例子中'scrollHeader'实际上没有滚动,它只是居中。我希望我可以将'frozenHeader'移出列标题,并将它放在上面,就像你在例子中用'freezeHeader'和'scrollHeader'所做的那样,但是那样会显着减少视口的高度(因为由于问题中提到的角落面板+上面放置的冻结标题的高度,列标题仍然是相同的高度。 – user1725940

+0

_“我希望红色面板始终在屏幕中居中,而不是滚动屏幕。”_ - 我刚刚脱掉了您的确切报价。现在你说这不是你想要的? –

+0

对不起,我认为我很清楚,考虑到标题,第一句和示例代码变量名称都引用了列标​​题中使用的冻结和可滚动组件。我现在已经更新了我的文章和代码,希望能够更好地描述我需要完成的任务。 – user1725940