0

我目前正在开发自定义合成器 lnf,但无法正确显示根窗格的 defaultButton。

所有按钮都按照以下定义正确绘制:

<style id="Button">
    <property key="Button.defaultButtonFollowsFocus" type="boolean" value="true"/>
    <property key="Button.textShiftOffset" type="integer" value="1"/>
    <property key="Button.margin" type="insets" value="0 10 0 10"/>
    <insets top="4" left="4" bottom="4" right="4"/>

    <state>
        <imagePainter method="buttonBackground" path="images/Button.Normal.png" sourceInsets="4 4 4 4" paintCenter="true" stretch="true"/>
    </state>

    <state value="MOUSE_OVER">
        <imagePainter method="buttonBackground" path="images/Button.Normal.MouseOver.png" sourceInsets="4 4 4 4" paintCenter="true" stretch="true"/>
    </state>

    <state value="FOCUSED">
...
    </state>
...
</style>
<bind style="Button" type="region" key="Button"/>

但是,如果我将一个按钮设置为根窗格的 defaultButton,则它不会正确绘制。

作为一个例子,我采取了以下截图。左侧为普通按钮,右侧为默认按钮。如果我将左侧设置为默认按钮,则正确绘制右侧并出现相同的问题(所有默认按钮都存在相同的问题,例如,如果我显示 JFileChooseDialog)。

左:普通按钮 - 右:默认按钮

如果我手动设置默认按钮的大小,它会正确显示,所以我认为计算按钮的大小有问题。

也许有人有类似的问题,或者可以给我一个提示,为什么 defaultButton 没有像普通按钮一样穿线。

提前致谢。

编辑:添加了简单的可运行示例代码。没有特别的布局,也没有其他特别的东西。默认按钮只是没有绘制。


DefaultButtonTest.java

public class DefaultButtonTest
{
    public static void main(String[] args) throws InterruptedException, NamingException
    {
        MyLookAndFeel.install();
        JFrame testFrame = new JFrame("test");
        JButton button1 = new JButton("button1");
        JButton button2 = new JButton("button2");
        JPanel testPanel = new JPanel(); // Applying for example FlowLayout makes no difference
        testPanel.add(button1);
        testPanel.add(button2);
        testFrame.setContentPane(testPanel);
        testFrame.getRootPane().setDefaultButton(button1);
        testFrame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
        testFrame.revalidate();
        testFrame.pack();
        testFrame.setVisible(true);
    }
}    


MyLookAndFeel.java

public final class MyLookAndFeel extends SynthLookAndFeel
{
    public final void initialize()
    {
        super.initialize();
        JFrame.setDefaultLookAndFeelDecorated(true);
        JDialog.setDefaultLookAndFeelDecorated(true);
    }

    public final void uninitialize()
    {
        super.uninitialize();
    }

    public static boolean install()
    {
        try
        {
            final long start = System.currentTimeMillis();
            MyLookAndFeel laf = new MyLookAndFeel();
            laf.load(MyLookAndFeel.class.getResourceAsStream("laf.xml"), MyLookAndFeel.class);
            UIManager.setLookAndFeel(laf);
            return true;
        }
        catch (final Exception exception)
        {
            exception.printStackTrace();
            return false;
        }
    }

    public final boolean getSupportsWindowDecorations()
    {
        return true;
    }

    public final UIDefaults getDefaults()
    {
        UIDefaults defaults = super.getDefaults();
        defaults.put(SwingUtilities2.AA_TEXT_PROPERTY_KEY, SwingUtilities2.AATextInfo.getAATextInfo(true));
        defaults.addResourceBundle("com.sun.swing.internal.plaf.metal.resources.metal");
        return defaults;
    }
}


拉夫.xml

<synth>
    <!-- ****************************************************************************************************************************************
    CONTROLS
    ***************************************************************************************************************************************** -->
    <style id="Button">
    <property key="Button.defaultButtonFollowsFocus" type="boolean" value="true"/>
    <property key="Button.textShiftOffset" type="integer" value="1"/>
    <property key="Button.margin" type="insets" value="0 10 0 10"/>
    <insets top="4" left="4" bottom="4" right="4"/>

    <state>
        <imagePainter method="buttonBackground" path="images/Button.Normal.png" sourceInsets="4 4 4 4" paintCenter="true" stretch="true"/>
    </state>

    </style>
    <bind style="Button" type="region" key="Button"/>
</synth
4

2 回答 2

1

根据经验,按钮的首选大小是错误的。一个简单的权宜之计是使用其他按钮的大小,如此处所建议

在此处输入图像描述

final JButton button2 = new JButton("button2");
JButton button1 = new JButton("button1"){

    @Override
    public Dimension getPreferredSize() {
        return button2.getPreferredSize();
    }
};
button1.setBorder(BorderFactory.createLineBorder(Color.red));
于 2013-08-12T13:42:34.147 回答
1

我终于找到了解决这个问题的方法,而且很简单。

虽然像'MOUSE OVER''FOCUSED'这样的状态......从其父级继承其字体和颜色属性,但不需要为它们提供字体和颜色属性。如果按钮或单选按钮定义了“默认”或“选择”之类的状态,则它们不会从其父级继承它们,并且需要明确定义字体和颜色(至少对于大小计算,如上所述,如果我手动设置大小字体和颜色显示正确)。

例如

这不适用于“默认”状态

<style id="Button">
    <property key="Button.textShiftOffset" type="integer" value="1"/>

    <state>
        <imagePainter method="buttonBackground" path="images/Button.Normal.png" sourceInsets="4 4 4 4" paintCenter="true" stretch="true"/>
    </state>

</style>
<bind style="Button" type="region" key="Button"/>


这适用于“默认”状态

<style id="Button">
    <property key="Button.textShiftOffset" type="integer" value="1"/>

    <font name="Dialog" size="16"/>
    <color type="TEXT_FOREGROUND" value="#000000"/>

    <state>
        <imagePainter method="buttonBackground" path="images/Button.Normal.png" sourceInsets="4 4 4 4" paintCenter="true" stretch="true"/>
    </state>

</style>
<bind style="Button" type="region" key="Button"/>
于 2013-08-13T06:40:23.490 回答