强制JScrollPane和JPanel重绘

时间:2013-11-01 16:09:41

标签: java swing jpanel jscrollpane openjdk

我有一个包含JPanel的JScrollPane。 JPanel上的布局是GridBagLayout。在那个JPanel上,我添加了许多自定义组件 - 每个组件都是一个带有3个JLabel的JPanel。

在程序中我第一次将所有这些都放在一边,它运行正常。当我调用代码将另一个自定义组件添加到JPanel时,面板显示为空,但我可以通过检查JPanel的内容来确定我的组件实际存在。如果我调整所有网站的JDialog大小,JPanel将正确绘制。如果我水平滚动JScrollPane,它也可以工作。

我在添加项目时使用与初始布局相同的方法。

我尝试了repaint(),invalidate()和doLayout()的各种组合,但似乎没有任何东西在运行。我以前遇到过这种情况,从来没有能够完全解决它。有什么建议吗?

在OpenJDK 7u25下运行。下面是用于布置滚动窗格和面板的代码。

    private void displayRelatedBug(ArrayList<Bug> a_bugs) {
      // sort the bugs by ID
      ArrayList<Bug> l_sorted = new ArrayList<>(a_bugs);
      Collections.sort(l_sorted);

      pnlRelatedBugs.removeAll();
      pnlRelatedBugs.setLayout(new GridBagLayout());
      GridBagConstraints l_gbc = new GridBagConstraints();
      l_gbc.gridx = 0;
      l_gbc.gridy = 0;
      l_gbc.gridwidth = 1;
      l_gbc.gridheight = 1;
      l_gbc.anchor = GridBagConstraints.NORTHWEST;
      l_gbc.fill = GridBagConstraints.NONE;
      l_gbc.insets = new Insets(3, 4, 0, 0);
      for (Bug r : l_sorted) {
        pnlRelatedBugs.add(new RelatedBugDisplay(r, this), l_gbc);
        l_gbc.gridy++;
      }
      // add a filler at the bottom to push it up
      l_gbc.weighty = 1.0;
      pnlRelatedBugs.add(new MMPanel(), l_gbc);
      // add a filler on the right to push them left
      l_gbc.weighty = 0.0;
      l_gbc.weightx = 1.0;
      l_gbc.gridx++;
      pnlRelatedBugs.add(new MMPanel(), l_gbc);

      // try in vain to make it show up!!!
      pnlRelatedBugs.invalidate();
      pnlRelatedBugs.doLayout();
      pnlRelatedBugs.repaint();
      scrollerRelatedBugs.doLayout();

      SwingUtilities.invokeLater(new Runnable() {
        @Override
        public void run() {
          pnlRelatedBugs.repaint();
          scrollerRelatedBugs.repaint();
          // this seems to help if the scroll bar is showing
          scrollerRelatedBugs.getHorizontalScrollBar().setValue(1);
          scrollerRelatedBugs.getHorizontalScrollBar().setValue(0);
        }
      });

    }

2 个答案:

答案 0 :(得分:7)

每当您从可见面板添加/删除组件时,基本代码为:

panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();

如果没有合适的SSCCE,我们无法确定您的代码在做什么。

答案 1 :(得分:1)

如果您在显示容器时添加/删除/替换/其他操作与组件,您必须revalidaterepaint您的容器,您添加组件以正确显示。