Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/304.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSplitPane分隔器拖动不适用于复杂布局_Java_Swing_Jsplitpane - Fatal编程技术网

Java JSplitPane分隔器拖动不适用于复杂布局

Java JSplitPane分隔器拖动不适用于复杂布局,java,swing,jsplitpane,Java,Swing,Jsplitpane,我有一个Java GUI程序,其中包含一个JSplitPane,用于划分内容。JSplitPane的左侧是一个JTabbedPane,有许多选项卡,这是一个非常复杂的布局。当左侧达到一定的复杂程度时,拖动分隔器以移动分隔器位置不再有效,但我仍然可以通过显式设置位置来移动分隔器。(如果有必要,我正在使用Nimbus LAF。) 这似乎不仅仅是左边标签的数量。我在左侧包含的某些选项卡使其停止工作,而其他选项卡则可以 有人碰到过这个吗 我可以通过在我的JSplitPane子类上添加一个hack变通方法

我有一个Java GUI程序,其中包含一个JSplitPane,用于划分内容。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未能这样做

  • 请问什么???最多5分钟


  • 现在还有两个问题

  • 也有
    SplitPaneUI
    的定义吗,因为
    if(BasicSplitPaneUI的ui实例){
    可以返回相当多的
    false

  • 其中添加了MouseMotionListener的原因说明


首先编辑

JSplitPane的左侧是一个JTabbedPane,其中有许多选项卡 -一个非常复杂的布局。当左侧达到一定的复杂程度时,拖动分隔符以移动分隔符位置no 工作时间更长,但我仍然可以通过显式设置来移动分隔符 地点

调整JSplitPane容器重量时的分配空间 拆分窗格的属性控制拆分时分隔符的行为 窗格已调整大小。如果权重为0,则所有额外的空间都将提供给 右侧或底部组件。如果重量为1,则所有额外空间均为 指定给左侧或顶部组件。权重为.3表示 左侧或顶部组件获得额外空间的三分之一。重量 还确定当分割的大小改变时,子对象如何丢失空间 窗格缩小。例如,权重为0表示左侧或顶部 组件不会丢失任何空间

重量还控制分隔器的起始位置。对于 例如,如果权重为.5,则分隔符放置在中心。 抄袭


编辑第2页

你忘了告诉我们,在Nimbus中,是否有一个完全闪烁的除法器,而不是由标准L&F的其余部分引起的


导入java.awt.Dimension;
导入java.awt.EventQueue;
导入java.awt.event.MouseEvent;
导入java.awt.event.MouseMotionAdapter;
导入javax.swing.BorderFactory;
导入javax.swing.JFrame;
导入javax.swing.JScrollPane;
导入javax.swing.JSplitPane;
导入javax.swing.JTable;
导入javax.swing.plaf.basic.BasicSplitPaneVider;
导入javax.swing.plaf.basic.BasicSplitPaneUI;
公共类JSplitPaneToy{
私人股份有限公司;
公共JSplitPaneToy(){
sp=新的JSplitPane(JSplitPane.HORIZONTAL_SPLIT,makePanel(),makePanel());
/*SplitPaneUI ui=sp.getUI();
if(基本CSplitPaneUI实例){
((BasicSplitPaneUI)ui.getDivider().setBorder(null);
}*/
BasicSplitPaneUI l_ui=(BasicSplitPaneUI)sp.getUI();
BasicSplitPaneDivider l_divider=l_ui.getDivider();
l_divider.addMouseMotionListener(新的MouseMotionAdapter(){
@凌驾
公共无效鼠标标记(鼠标事件e){
尺寸l_窗格_size=sp.getSize();
if(sp.getOrientation()==JSplitPane.HORIZONTAL_SPLIT){
int l_new_loc=sp.getDividerLocation()+e.getX();

如果(l_new_loc>=0&&l_new_loc=0&&l_new_loc,这似乎是故意的行为。在javax.swing.plaf.basic.BasicSplitPaneVider.DragController的构造函数中找到以下代码:

minX = leftC.getMinimumSize().width;
后来在同一节课上

    /**
    * Returns the new position to put the divider at based on
    * the passed in MouseEvent.
    */
    protected int positionForMouseEvent(MouseEvent e) {
      int newX = (e.getSource() == BasicSplitPaneDivider.this) ?
                  (e.getX() + getLocation().x) : e.getX();

      newX = Math.min(maxX, Math.max(minX, newX - offset));
      return newX;
    }
因此,基本UI似乎有意不让您拖动分隔符,从而使左侧小于其最小大小


在我的情况下,这种行为不符合我的需要,所以我的小解决方案是必要的。

An会在这里提供极大的帮助。SSCE中添加了MouseMotionListener,并描述了为什么会添加MouseMotionListener。请问SplitPaneUI tooI有没有定义我花了相当多的时间尝试使用SSCE,但未能做到。我不要认为调整大小的权重适用于这里-JSplitPane没有调整大小,只是分隔器正在移动。我将在SSCCE上再做一次尝试。我想到了一种不同的方法来实现这一点,这可能会奏效。
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;
    }
}
minX = leftC.getMinimumSize().width;
    /**
    * Returns the new position to put the divider at based on
    * the passed in MouseEvent.
    */
    protected int positionForMouseEvent(MouseEvent e) {
      int newX = (e.getSource() == BasicSplitPaneDivider.this) ?
                  (e.getX() + getLocation().x) : e.getX();

      newX = Math.min(maxX, Math.max(minX, newX - offset));
      return newX;
    }