MigLayout错误:“绝对链接值中的不稳定循环依赖!”

时间:2014-10-16 22:31:55

标签: java swing miglayout

为什么这个SSCCE(使用MigLayout库)......

public static void main(String[] args) {

    try {
        UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
    } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException e) {
        e.printStackTrace();
    }

    JFrame frame = new JFrame();
    frame.setLayout(new MigLayout(new LC().fill().insetsAll("0")));

    JTabbedPane jtp = new JTabbedPane();
    jtp.add(new JPanel(), "Tab 1");
    jtp.add(new JPanel(), "Tab 2");

    JLabel label = new JLabel("label");

    JPanel panel = new JPanel(new MigLayout(new LC().fill()));
    panel.add(jtp, "id tabbedpane, grow, span");
    panel.add(label, "pos (tabbedpane.w-label.w) 10, id label");
    label.setBounds(100, 100, 10, 10);

    frame.add(panel, "grow, span");
    frame.setSize(500, 500);
    frame.setLocationRelativeTo(null); // Sorry, Andrew Thompson
    frame.setVisible(true);
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}

抛出此错误:

Unstable cyclic dependency in absolute linked values!
Unstable cyclic dependency in absolute linked values!
Unstable cyclic dependency in absolute linked values!
Unstable cyclic dependency in absolute linked values!

我发现如果你删除WindowsLookAndFeel代码,那么一切运行正常......

enter image description here

因此,这是MigLayout和WindowsLookAndFeel的问题。然而,我的真实应用程序需要使用它。

编辑:

这是抛出错误时框架的样子:

enter image description here

1 个答案:

答案 0 :(得分:3)

看一下source code,会发生这种情况,因为它在进行布局时会对组件的大小进行更正。如果它超过计数* 8 + 10校正,那么它会使代码短路以防止无限循环。

相关来源(删除了一些内容)是:

do {
    doAgain = false;
    for (Iterator<Cell> it = grid.values().iterator(); it.hasNext();) {
        ArrayList<CompWrap> compWraps = it.next().compWraps;
        for (int i = 0, iSz = compWraps.size(); i < iSz; i++) {
            CompWrap cw = compWraps.get(i);

            if (j == 0) {
                doAgain |= doAbsoluteCorrections(cw, bounds);
                // . . .
            }

            // . . .
        }
    }
    clearGroupLinkBounds();
    if (++count > ((compCount << 3) + 10)) {
        System.err.println("Unstable cyclic dependency in absolute linked values!");
        break;
    }

} while (doAgain);

所以正在发生的事情是,如果doAbsoluteCorrections返回true(如果任何组件在完成校正以改变大小依赖性时会改变大小),那么它将重复循环,再次进行校正。你所看到的是它重复这么多次时打印的警告信息。由于校正可能导致链接组件的大小发生变化,因此您可以获得这样的情况:更正为一个组件设置y值并为另一个组件设置y值,然后当第一个组件具有其y值时设置,它取消设置另一个的y值,这将重复,直到我们用完重试。

Windows L&amp; F对我来说经常引起这个问题,因为看起来这些组件总会陷入这样一种情况:他们会进行这种校正并且只会改变1个像素进行校正,但是这种校正导致了它需要重做另一个组件的布局,导致它向后移动1个像素。 “递归”(如果你想这样想的话)是不稳定的,并没有达到稳定的解决方案。

我不知道删除这些消息的解决方案是什么,但如果它不会在您的应用程序中引起异常的“摇晃”(如果有的话,您会知道我的意思),我不会担心它。这只是一条消息,表明它正在放弃更正,因为它被递归了太多次。