我正在尝试纠正GroupLayout中Aqua按钮的布局,但它是否可能?

时间:2014-02-07 12:36:09

标签: java swing layout layout-manager grouplayout

我注意到,如果您尝试在LEADING中使用GroupLayout对齐,当其中一个组件是按钮而另一个组件不是按钮时,组件就不再对齐。

如果两个组件都是按钮,则会得到如下结果:

getContainerGap(button, EAST, container) -> 14
getContainerGap(another button, EAST, container) -> 14
getContainerGap(button, WEST, container) -> 14
getContainerGap(another button, WEST, container) -> 14
getContainerGap(button, SOUTH, container) -> 17
getPreferredGap(another button, button, RELATED, SOUTH, container) -> 4
getContainerGap(another button, SOUTH, container) -> 17

result of layout when both are buttons

如果你拿出标尺,可以看到左边距恰好是20像素,所以这个结果是正确的。

如果其中一个组件一个按钮(通常我在尝试将按钮对齐到JScrollPane或类似的左边缘时看到这个),你会得到结果如下:

getContainerGap(button, EAST, container) -> 14
getContainerGap(reference component, EAST, container) -> 20
getContainerGap(button, WEST, container) -> 14
getContainerGap(reference component, WEST, container) -> 20
getContainerGap(button, SOUTH, container) -> 17
getPreferredGap(reference component, button, RELATED, SOUTH, container) -> 7
getContainerGap(reference component, SOUTH, container) -> 20

result of layout when one component is not a button

现在如果你拿出标尺,红色边框的左边距恰好是20像素,但按钮会突出另外6个像素。

存在getVisualMargin方法来纠正此问题,您可以看到getContainerGap(button, EAST, container)返回14,这会补偿按钮外的6个像素的额外边距。

如果要布置更多类型的组件,结果会逐渐变差,最终会在布局中一直呈现锯齿状边缘,因为只有相似的组件才会相互对齐。

我想知道这里发生了什么。即使LayoutStyle返回容器间隙的正确值,似乎GroupLayout丢弃了值并使用了另一个组件中的值,这可以保证布局错误。< / p>

测试程序来源:

import javax.swing.BorderFactory;
import javax.swing.GroupLayout;
import javax.swing.JButton;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.LayoutStyle;
import javax.swing.SwingUtilities;
import javax.swing.WindowConstants;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;

public class ButtonVisualMarginTest implements Runnable {
    public static void main(String[] args) {
        SwingUtilities.invokeLater(new ButtonVisualMarginTest());
    }

    @Override
    public void run() {
        LayoutStyle.setInstance(new AquaLayoutStyle());

        JComponent reference = new JComponent() {};
        reference.setName("reference component");
        reference.setPreferredSize(new Dimension(200, 50));
        reference.setMaximumSize(new Dimension(200, 50));
        reference.setBorder(BorderFactory.createLineBorder(Color.RED));

//        JButton reference = new JButton("Another button");
//        reference.setName("another button");
//        reference.setFocusable(false);

        JButton button = new JButton("Text only");
        button.setName("button");
        button.setFocusable(false);

        JPanel container = new JPanel();
        container.setName("container");
        GroupLayout layout = new GroupLayout(container);
        layout.setAutoCreateGaps(true);
        layout.setAutoCreateContainerGaps(true);
        container.setLayout(layout);
        container.setBackground(new Color(192, 192, 255));
        container.setOpaque(true);

        layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING)
            .addComponent(reference)
            .addComponent(button));

        layout.setVerticalGroup(layout.createSequentialGroup()
            .addComponent(reference)
            .addComponent(button));

        JFrame frame = new JFrame("Test");
        frame.setLayout(new BorderLayout());
        frame.add(container, BorderLayout.CENTER);
        frame.setSize(400, 300);
        frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        frame.setVisible(true);

    }
}

我试图使用的AquaLayoutStyle的略微修改版本是here(它太大而无法包含。)

因为人们可能很好奇,所以 使用AquaLayoutStyle的结果是:

result of not using AquaLayoutStyle

以下是使用Xcode在可滚动组件旁边布置按钮时所获得的布局(如果我们希望Java应用程序看起来像本机,那么这就是我们的目标。)

native layout of similar components

0 个答案:

没有答案