【问题标题】:JSplitPane SetDividerLocation ProblemJSplitPane SetDividerLocation 问题
【发布时间】:2009-12-10 06:45:53
【问题描述】:

我有一个 JSplitPane,当它显示时应该将窗格拆分 50%。

现在在给 setDividerLocation 一个 0.5 的参数(如建议的那样)时,Java 似乎将其视为正常数字而不是百分比。如中所示,分隔线几乎位于左侧窗格的开头(窗格垂直拆分),而不是转到窗格的中间。 有什么解决办法吗?

【问题讨论】:

    标签: java jsplitpane


    【解决方案1】:

    我错过了什么吗?这个问题似乎有很多相当复杂的答案......但我认为一个简单的 setResizeWeight(0.5) 可以解决这个问题......它在SplitPane Tutorial中有所描述

    【讨论】:

    • 哦,糟糕,我在 cmets 中忽略了这一点。谢谢。尽管最流行的答案没有提到它,但似乎很奇怪......现在已经有 2 年的历史了。
    【解决方案2】:

    setDividerLocation(double) 方法仅适用于“已实现”的框架,这意味着在您打包或使框架可见之后。

    setDividerLocation(int)方法可以随时使用。

    【讨论】:

    • 这显然是可以理解的
    【解决方案3】:

    您只能在拆分窗格可见时将拆分窗格分隔线的位置设置为百分比。您可以点击拆分窗格所有者的事件以确定何时可以设置分隔线的位置。例如:

    public class MyFrame extends JFrame {
    
      public MyFrame() {
    
        final JSplitPane splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT);
        // ... set up the split pane, and add to the frame ...
    
        // Listen for the frame's "shown" event.
    
        addComponentListener(new ComponentAdapter() {
    
          @Override
          public void componentShown(ComponentEvent componentEvent) {
    
            // Set the divider location to 20%.
            // This works because we know the pane is visible.
    
            splitPane.setDividerLocation(.2);
    
            // Stop listening for "shown" events.
    
            removeComponentListener(this);
          }
    
        });
    
        pack();
      }
    }
    

    【讨论】:

      【解决方案4】:

      这解决了它:

      public class JSplitPane3 extends JSplitPane {
          private boolean hasProportionalLocation = false;
          private double proportionalLocation = 0.5;
          private boolean isPainted = false;
      
          public void setDividerLocation(double proportionalLocation) {
              if (!isPainted) {
                  hasProportionalLocation = true;
                  this.proportionalLocation = proportionalLocation;
              } else {
                  super.setDividerLocation(proportionalLocation);
              }
          }
      
          public void paint(Graphics g) {
              super.paint(g);
              if (!isPainted) {
                  if (hasProportionalLocation) {
                      super.setDividerLocation(proportionalLocation);
                  }
                  isPainted = true;
              }
          }
      
      }
      

      【讨论】:

      • 只是为了澄清,如果我在代码中手动指定它,我只使用 paint() 和没有 hasProportionalLocation 让它工作。比这个怪物短得多
      • 谢谢。刚刚遇到这个,它已经困扰了我们很多年了。 +1
      • 我一直使用这种方法。但是,我注意到您在移动之前确实会暂时看到分隔线位置错误。为了解决这个问题,我采取了覆盖 validate() 而不是覆盖paint(Graphics) 的方式。
      【解决方案5】:

      如果您对每次调整窗格大小时分隔线移动到中间感到满意,您可以添加一个 ComponentListener 并让其 componentResized 方法调用 setDividerLocation(0.5)。

      【讨论】:

      • 您可以为此使用 setResizeWeight(...) 方法。
      【解决方案6】:

      使用setResizeWeight(double);

      【讨论】:

        【解决方案7】:

        我发现稍后调用的setResizeWeightsetDividerLocation 的组合提供了人们期望的行为:

        _splitPane.setResizeWeight(0.5);
        
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                _splitPane.setDividerLocation(0.5);
            }
        });
        

        【讨论】:

        • 因为这样的操作必须在EDT中完成。
        【解决方案8】:

        这对我有用,基于 Dave Rays link

        /**
         * Set JSplitPane proportional divider location
         * 
         * @param jsplitpane JSplitPane to set
         * @param proportionalLocation double <0.0; 1.0>
         */
        public static void setJSplitPaneDividerLocation(final JSplitPane jsplitpane, final double proportionalLocation)
        {
            if (jsplitpane.isShowing())
            {
                if (jsplitpane.getWidth() > 0 && jsplitpane.getHeight() > 0)
                {
                    jsplitpane.setDividerLocation(proportionalLocation);
                }
                else
                {
                    jsplitpane.addComponentListener(new ComponentAdapter()
                    {
                        @Override
                        public void componentResized(ComponentEvent ce)
                        {
                            jsplitpane.removeComponentListener(this);
                            setJSplitPaneDividerLocation(jsplitpane, proportionalLocation);
                        }
                    });
                }
            }
            else
            {
                jsplitpane.addHierarchyListener(new HierarchyListener()
                {
                    @Override
                    public void hierarchyChanged(HierarchyEvent e)
                    {
                        if ((e.getChangeFlags() & HierarchyEvent.SHOWING_CHANGED) != 0 && jsplitpane.isShowing())
                        {
                            jsplitpane.removeHierarchyListener(this);
                            setJSplitPaneDividerLocation(jsplitpane, proportionalLocation);
                        }
                    }
                });
            }
        }
        

        【讨论】:

          【解决方案9】:

          有一个解决方案 here,它是一个简单的函数,不需要子类化或对拆分窗格进行任何其他更改。

          【讨论】:

            【解决方案10】:

            ComponentJSplitPane 中的以下内容也可以:

            @Override
            public void setVisible(final boolean b) {
                super.setVisible(b);
                SwingUtilities.invokeLater(new Runnable() {
            
                    @Override
                    public void run() {
                        AppFrame.this.jSplitPane.setDividerLocation(0.9d);
                    }
            
                });
            }
            

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2012-08-10
              • 2011-10-07
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多