根窗格默认按钮未与自定义合成器lnf正确配对

时间:2013-08-12 09:24:46

标签: java swing look-and-feel synth defaultbutton

我目前正在开发自定义合成器,但无法正确显示根窗格的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,则它的绘制效果不正确。

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

left: normal button - right: default button

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

也许有人有类似的问题,或者可以给我一个提示,为什么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;
    }
}


laf.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

2 个答案:

答案 0 :(得分:1)

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

enter image description here

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

    @Override
    public Dimension getPreferredSize() {
        return button2.getPreferredSize();
    }
};
button1.setBorder(BorderFactory.createLineBorder(Color.red));

答案 1 :(得分:1)

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

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

例如

这不适用于'DEFAULT'状态

<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"/>