我有一个带有JSplitPane的Java GUI程序,用于划分内容。 JSplitPane的左侧是带有许多标签的JTabbedPane-布局非常复杂。当左侧达到某种程度的复杂度时,拖动分隔线以移动分隔线的位置不再起作用,但是我仍然可以通过显式设置位置来移动分隔线。 (如果重要,我正在使用Nimbus LAF。)

似乎不仅仅是左侧的标签数。我左侧包含的某些标签使它停止工作,而其他标签则确定。

有人遇到过这个吗?

我可以通过在JSplitPane子类上添加一种hack解决方法来解决此问题。

    public void enableDividerWorkaround() {
      javax.swing.plaf.basic.BasicSplitPaneUI l_ui = (javax.swing.plaf.basic.BasicSplitPaneUI) getUI();
      BasicSplitPaneDivider l_divider = l_ui.getDivider();

      l_divider.addMouseMotionListener(new MouseMotionAdapter() {
        @Override
        public void mouseDragged(MouseEvent e) {
          Dimension l_pane_size = getSize();
          if (getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
            int l_new_loc = getDividerLocation() + e.getX();
            if (l_new_loc >= 0 && l_new_loc <= l_pane_size.width) {
              setDividerLocation(l_new_loc);
            }
          } else {
            int l_new_loc = getDividerLocation() + e.getY();
            if (l_new_loc >= 0 && l_new_loc <= l_pane_size.height) {
              setDividerLocation(l_new_loc);
            }
          }
        }
      });
    }


更新
这是SSCCE(下)。运行此命令时,第一次将滑块向右拖动时,它将“快照”到长标签的末尾,然后在那里固定。我相信这是由长标签触发的。如果缩短标签,则滑块上的运动范围会更大。那么,这是错误还是预期的行为?

    public class SplitPaneTest extends javax.swing.JFrame {
      public SplitPaneTest() {
        initComponents();
      }
      private void initComponents() {

        jSplitPane1 = new javax.swing.JSplitPane();
        jLabel1 = new javax.swing.JLabel();
        jPanel1 = new javax.swing.JPanel();
        jLabel2 = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        jSplitPane1.setDividerLocation(450);
        jSplitPane1.setName("jSplitPane1");

        jLabel1.setText("right side");
        jLabel1.setName("jLabel1");
        jSplitPane1.setRightComponent(jLabel1);

        jPanel1.setName("jPanel1");

        jLabel2.setText("left side asd adsf asdf asdf asdf sadf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdf asdfa end");
        jLabel2.setName("jLabel2");

        javax.swing.GroupLayout jPanel1Layout = new javax.swing.GroupLayout(jPanel1);
        jPanel1.setLayout(jPanel1Layout);
        jPanel1Layout.setHorizontalGroup(
          jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jLabel2)
            .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
        );
        jPanel1Layout.setVerticalGroup(
          jPanel1Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addGroup(jPanel1Layout.createSequentialGroup()
            .addContainerGap()
            .addComponent(jLabel2)
            .addContainerGap(420, Short.MAX_VALUE))
        );

        jSplitPane1.setLeftComponent(jPanel1);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
          layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jSplitPane1)
        );
        layout.setVerticalGroup(
          layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
          .addComponent(jSplitPane1)
        );

        pack();
      }

      /**
       * @param args the command line arguments
       */
      public static void main(String args[]) {
        java.awt.EventQueue.invokeLater(new Runnable() {
          public void run() {
            new SplitPaneTest().setVisible(true);
          }
        });
      }
      protected javax.swing.JLabel jLabel1;
      protected javax.swing.JLabel jLabel2;
      protected javax.swing.JPanel jPanel1;
      protected javax.swing.JSplitPane jSplitPane1;
    }

最佳答案

我花了很多时间试图达到
SSCCE,但无法这样做





请什么? SSCCE最多5分钟


现在仍然有两个问题


也有SplitPaneUI的定义,因为if (ui instanceof BasicSplitPaneUI) {可以返回漂亮的false
并附上原因说明,其中添加了MouseMotionListener





EDIT_1st。


JSplitPane的左侧是带有许多标签的JTabbedPane
-非常复杂的布局。当左侧达到一定程度的复杂度时,拖动分隔线以移动分隔线的位置
可以使用更长的时间,但是我仍然可以通过显式设置来移动分隔线
那个地点。



wild shot in the dark == you need to know



调整JSplitPane容器大小时分配空间的重量
拆分窗格的控件控制拆分时分隔符的行为
窗格已调整大小。如果权重为0,则将所有多余的空间分配给
右侧或底部组件。如果权重为1,则所有多余空间为
赋予左侧或顶部组件。权重.3指定
左侧或顶部组件将获得额外空间的三分之一。重量
还可确定孩子在拆分大小时如何失去空间
窗格减少。例如,权重为0表示左侧或顶部
组件不会丢失任何空间。

砝码还控制分隔线的起始位置。对于
例如,如果权重为.5,则分隔线位于中间。
复制


// Create a left-right split pane
JSplitPane pane = new JSplitPane(
     JSplitPane.HORIZONTAL_SPLIT, leftComponent, rightComponent);

// Get current weight
double weight = pane.getResizeWeight();    // 0.0 by default

// Keep the size of the right component constant
weight = 1D;
pane.setResizeWeight(weight);

// Split the space evenly
weight = .5D;
pane.setResizeWeight(weight);




EDIT_2nd。

您忘了告诉我们,在Nimbus中,分​​隔线出现了完全闪烁,不是由其他标准L&F引起的





import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.event.MouseEvent;
import java.awt.event.MouseMotionAdapter;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.plaf.basic.BasicSplitPaneDivider;
import javax.swing.plaf.basic.BasicSplitPaneUI;

public class JSplitPaneToy {

    private JSplitPane sp;

    public JSplitPaneToy() {
        sp = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, makePanel(), makePanel());
        /*SplitPaneUI ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }*/
        BasicSplitPaneUI l_ui = (BasicSplitPaneUI) sp.getUI();
        BasicSplitPaneDivider l_divider = l_ui.getDivider();
        l_divider.addMouseMotionListener(new MouseMotionAdapter() {
            @Override
            public void mouseDragged(MouseEvent e) {
                Dimension l_pane_size = sp.getSize();
                if (sp.getOrientation() == JSplitPane.HORIZONTAL_SPLIT) {
                    int l_new_loc = sp.getDividerLocation() + e.getX();
                    if (l_new_loc >= 0 && l_new_loc <= l_pane_size.width) {
                        sp.setDividerLocation(l_new_loc);
                    }
                } else {
                    int l_new_loc = sp.getDividerLocation() + e.getY();
                    if (l_new_loc >= 0 && l_new_loc <= l_pane_size.height) {
                        sp.setDividerLocation(l_new_loc);
                    }
                }
            }
        });
        sp.setBorder(BorderFactory.createEmptyBorder());
        /*sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
         ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }
         sp.setBorder(BorderFactory.createEmptyBorder());
         sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
         ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }
         sp.setBorder(BorderFactory.createEmptyBorder());
         sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
         ui = sp.getUI();
         if (ui instanceof BasicSplitPaneUI) {
         ((BasicSplitPaneUI) ui).getDivider().setBorder(null);
         }
         sp.setBorder(BorderFactory.createEmptyBorder());*/
        JFrame frame = new JFrame("JSplitPane Toy");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(sp);
        frame.pack();
        frame.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JSplitPaneToy();
            }
        });
    }

    private JScrollPane makePanel() {
        JScrollPane pane = new JScrollPane(new JTable(
                new Object[][]{{0, 1, 2}, {1, 2, 3}, {2, 3, 4}}, new Object[]{1, 2, 3}) {
        });
        pane.setPreferredSize(new Dimension(200, 100));
        return pane;
    }
}

08-07 05:13