1

具体来说,我目前有一个带有 TitledBorder 的 JPanel。我想自定义边框的外观。在我的应用程序的当前状态下,绘制的是标题,而不是线条边框本身。

如果我将 imagePainter 绑定到 Panel 对象的 panelBorder 方法,我可以在面板周围放置一个自定义图像——但是它只显示在那些我没有在代码中明确设置边框的面板上。这是该代码的样子:

<style id="PanelStyle">
    <state>
        <imagePainter method="panelBorder" path="images/thick border.png" sourceInsets="3 3 3 3" />
    </state>
</style>
<bind style="PanelStyle" type="region" key="Panel" />

我该如何做相反的事情——也就是说,让这个自定义图像只显示在我应用了 TitledBorder 的面板上?

我也尝试过使用命名面板:

panel.setName("MyPanel")

和名称绑定:

<bind style="PanelStyle" type="name" key="MyPanel">

这使我可以仅更改特定面板的样式,这很好。但是,它并没有解决原来的问题:我仍然无法自定义面板的 NamedBorder。

如果我指定 NamedBorder,我的 PanelBorder 画家将被忽略,只打印名称。如果我拿走我的 NamedBorder,我可以使用我的自定义边框图形,但是我必须戳我的布局以在标题之前所在的同一位置获得一个 JLabel,这是不可取的。

进一步的研究发现,没有渲染线的原因是 TitledBorder 的构造函数接受了另一个 Border 的参数,除了标题之外它还渲染了该参数。我没有传递这个参数,默认值取决于您选择的 L&F。当我使用系统 L&F 时,默认是 LineBorder。显然 Synth 的默认值是 EmptyBorder。显式指定 LineBorder 可以让我返回线,这解决了我的大部分问题。

我剩下的问题涉及为 LineBorder 使用自定义图形。现在,我通过将我的自定义图形渲染为第二个 PanelBackground 图像来获得——它被合成在实际背景之上并实现了所需的视觉效果,尽管它不是理想的实现。

4

3 回答 3

1

哈,找到原因了。来自 TitledBorder.getBorder,如果使用了合成器外观。TitledBorder.border 应该在 xml 文件中定义。

public Border getBorder()       {       
    Border b = border;
if (b == null)
    b = UIManager.getBorder("TitledBorder.border");
    return b; 
}

所以我的回答是:

<object id="TitledBorder_Color" class="java.awt.Color">
        <int>140</int>

        <int>125</int>

        <int>100</int>

        <int>255</int>
    </object>

    <object id="LineBorder" class="javax.swing.border.LineBorder">
        <object idref="TitledBorder_Color"/>
    </object>

    <defaultsProperty key="TitledBorder.border" type="idref" value="LineBorder"/>
于 2009-08-28T06:51:42.953 回答
1

指定要应用特殊样式的组件的名称,而不是区域:

<bind style="PanelStyle" type="name" key="mySpecialPanel" />

在您的 Java 代码中,您需要设置组件的名称以匹配您在 XML 中提供的名称:

panel.setName("mySpecialPanel");

您可以考虑扩展 JPanel 以便所有面板具有相同的名称:

public class MySpecialPanel extends JPanel 
{    
   public MySpecialPanel(String title) 
   {
       super(title);
       this.setName("mySpecialPanel");    
   } 
}
于 2008-11-10T21:50:50.810 回答
0

我们遇到了同样的问题。当然,您的解决方法(您在上面描述的)有效,但它不是解决方案。

我们使用的解决方法是:

代替:

BorderFactory.createTitledBorder("title");

你应该使用:

Border objBorder = BorderFactory.createLineBorder(Color.black); 
//Also you can create all the rest of the borders here.
BorderFactory.createTitledBorder(objBorder, "title");
于 2009-07-13T09:51:45.537 回答