简体   繁体   English

为什么JSplitPane会为我的组件添加边框,如何阻止它?

[英]Why does JSplitPane add a border to my components, and how do I stop it?

JSplitPane seems to add a border to any Component added to it. JSplitPane似乎为添加到其中的任何Component添加了边框。

This is most visible with nested JSplitPanes - eg: 嵌套的JSplitPanes最明显 - 例如:

public class JSplitPaneToy {

  public static void main(String[] args) {
    JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, 
      makePanel(), makePanel());
    sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
    sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
    sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);

    JFrame frame = new JFrame("JSplitPane Toy");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    frame.setContentPane(sp);
    frame.pack();
    frame.setVisible(true);
  }

  private static 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;
  }
}

ie each subsequent nested component appears to be set further back - ie there is some form of shadow border being added. 即每个后续嵌套组件似乎进一步设置 - 即添加某种形式的阴影边框。

  • Why is this border being added? 为什么要添加此边框? (Is this actually a border being added...?) (这实际上是一个边界被添加......?)
  • How can I prevent this 'border' from being added? 如何防止添加此“边框”?

If you want to drop those borders on all JSplitPane, you can change the defaults of the UI like this. 如果要在所有JSplitPane上删除这些边框,可以像这样更改UI的默认值。 However, I usually try not to mess with UI-defaults. 但是,我通常尽量不要弄乱UI默认值。

import java.awt.Dimension;

import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JScrollPane;
import javax.swing.JSplitPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;

public class JSplitPaneToy {

    public static void main(String[] args) {
        UIManager.getDefaults().put("SplitPane.border", BorderFactory.createEmptyBorder());
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                new JSplitPaneToy().initUI();
            }
        });
    }

    public void initUI() {
        JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), makePanel());
        sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
        sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);
        sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT, makePanel(), sp);

        JFrame frame = new JFrame("JSplitPane Toy");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setContentPane(sp);
        frame.pack();
        frame.setVisible(true);
    }

    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;
    }
}

You may want to have a look at the JXMultiSplitPane of the SwingX project, instead of nesting so many splitpanes. 您可能想要查看SwingX项目的JXMultiSplitPane,而不是嵌套这么多的分割窗格。

We use this method to "flatten" a JSplitPane. 我们使用这种方法来“压扁”JSplitPane。 Perhaps this is what you are looking for: 也许这就是你要找的东西:

/**
 * Makes a split pane invisible. Only contained components are shown.
 *
 * @param splitPane
 */
public static void flattenJSplitPane(JSplitPane splitPane) {
    splitPane.setBorder(BorderFactory.createEmptyBorder(1, 1, 1, 1));
    BasicSplitPaneUI flatDividerSplitPaneUI = new BasicSplitPaneUI() {
        @Override
        public BasicSplitPaneDivider createDefaultDivider() {
            return new BasicSplitPaneDivider(this) {
                @Override
                public void setBorder(Border b) {
                }
            };
        }
    };
    splitPane.setUI(flatDividerSplitPaneUI);
    splitPane.setBorder(null);
}

As for why the borders get added, would not know. 至于为什么边界被添加,不知道。 Apparently its some sort of a feature. 显然它是某种功能。 We found it to be an unwanted one and the above method works around it. 我们发现它是一个不需要的,上面的方法可以解决它。 There's probably a simpler way of dealing with this problem, but hey, when you find somethig that works, you stop looking for alternatives. 可能有一种更简单的方法可以解决这个问题,但是,当你找到一些有效的方法时,你就不再寻找替代方案了。

I used this, to reset the border form the Divider. 我用它来重置分隔符的边框。

    SplitPaneUI ui = sp.getUI();
    if( ui instanceof BasicSplitPaneUI ) {
        ((BasicSplitPaneUI)ui).getDivider().setBorder( null );
    }

NOTE: your Example doesnt work splitPane is unknown, it should be sp . 注意:你的例子不起作用splitPane是未知的,它应该是sp

public class JSplitPaneToy {

  public static void main(String[] args) {
    JSplitPane sp = new JSplitPane(JSplitPane.VERTICAL_SPLIT,  makePanel(), makePanel());
    SplitPaneUI 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() );

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

  private static 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;
  }
}

An alternative answer is to set each Component on the JSplitPane to have an empty border - eg 另一种方法是将JSplitPane上的每个Component设置为空边框 - 例如

JComponent a = ...;
JComponent b = ...; 
a.setBorder(BorderFactory.createEmptyBorder());
b.setBorder(BorderFactory.createEmptyBorder());
JSplitPane splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, a, b);

Just override setBroder by JScrollPane like that 只需像JScrollPane那样覆盖setBroder

public class MyScrollPane extends JScrollPane {
 ...
 @Override
 public void setBorder(Border b) {}
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM