简体   繁体   English

Java L&F 自定义:如何使用 synth 自定义 BorderFactory 边框?

[英]Java L&F customization: How do I use synth to customize BorderFactory borders?

Specifically, I currently have a JPanel with a TitledBorder.具体来说,我目前有一个带有 TitledBorder 的 JPanel。 I want to customize the look of the border.我想自定义边框的外观。 In my app's current state, the title is drawn, but not the line border itself.在我的应用程序的当前状态下,绘制了标题,但未绘制线条边框本身。

If I bind an imagePainter to the panelBorder method for Panel objects, I can put a custom image around panels -- however it only shows up on those panels that I haven't explicitly set the border on in the code.如果我将一个 imagePainter 绑定到 Panel 对象的 panelBorder 方法,我可以在面板周围放置一个自定义图像——但是它只显示在那些我没有在代码中明确设置边框的面板上。 Here's what that code looks like:下面是代码的样子:

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

How can I do the opposite -- that is, make this custom image only show up on panels I've applied a TitledBorder to?我该如何做相反的事情——也就是说,让这个自定义图像只显示在我应用了 TitledBorder 的面板上?

I have also tried using a named panel:我也尝试过使用命名面板:

panel.setName("MyPanel")

and a name binding:和名称绑定:

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

This allows me to change the style of only particular panels, which is good.这允许我只更改特定面板的样式,这很好。 However, it does not solve the original problem: I still can't customize my panel's NamedBorder.但是,它并没有解决最初的问题:我仍然无法自定义面板的 NamedBorder。

If I specify a NamedBorder, my PanelBorder painter is ignored, and just the name is printed.如果我指定一个 NamedBorder,我的 PanelBorder 绘制器将被忽略,并且只打印名称。 If I take away my NamedBorder, I can use my custom border graphic, but then I have to poke and prod my layout to get a JLabel in the same place that the title was previously, which is undesirable.如果我拿走我的 NamedBorder,我可以使用我的自定义边框图形,但是我必须戳和戳我的布局才能在标题以前的同一个地方得到一个 JLabel,这是不可取的。

Further research has uncovered that the reason there is no rendered line is that TitledBorder's constructor takes an argument of another Border, which it renders in addition to the title.进一步的研究发现,没有渲染线的原因是 TitledBorder 的构造函数采用另一个 Border 的参数,除了标题之外,它还渲染了另一个 Border。 I was not passing this argument, and the default depends on your selected L&F.我没有传递这个参数,默认值取决于您选择的 L&F。 Back when I was using the System L&F, the default was a LineBorder.当我使用 System L&F 时,默认是 LineBorder。 Apparently Synth's default is an EmptyBorder.显然 Synth 的默认值是 EmptyBorder。 Explicitly specifying the LineBorder gets me the line back, which solves most of my problem.显式指定 LineBorder 让我回到这条线,这解决了我的大部分问题。

The rest of my problem involves using a custom graphic for the LineBorder.我的其余问题涉及为 LineBorder 使用自定义图形。 For now I'm getting by rendering my custom graphic as a second PanelBackground image -- it gets composited on top of the actual background and achieves the desired visual effect, though it's not the ideal implementation.现在,我将我的自定义图形渲染为第二个 PanelBackground 图像——它被合成在实际背景之上并实现了所需的视觉效果,尽管它不是理想的实现。

ha, got the reason.哈,知道原因了。 From TitledBorder.getBorder, if synth look and feel is used.来自 TitledBorder.getBorder,如果使用合成器外观。 TitledBorder.border should be defined in the xml file. TitledBorder.border 应该在xml 文件中定义。

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

so my answer is:所以我的回答是:

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

Specify the name of the component you want to apply the special style to, not the region:指定要应用特殊样式的组件的名称,而不是区域:

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

In your Java code, you'll need to set the component's name to match the name you supplied in the XML:在您的 Java 代码中,您需要设置组件的名称以匹配您在 XML 中提供的名称:

panel.setName("mySpecialPanel");

You might consider extending JPanel so that all panels have the same name:您可以考虑扩展 JPanel 以便所有面板都具有相同的名称:

public class MySpecialPanel extends JPanel 
{    
   public MySpecialPanel(String title) 
   {
       super(title);
       this.setName("mySpecialPanel");    
   } 
}

We had the same problem.我们遇到了同样的问题。 Of course your workaround (which you described above) works but it is not a solution.当然,您的解决方法(您在上面描述过)有效,但它不是解决方案。

The workaround we used is:我们使用的解决方法是:

Instead of:代替:

BorderFactory.createTitledBorder("title");

You should use:你应该使用:

Border objBorder = BorderFactory.createLineBorder(Color.black); 
//Also you can create all the rest of the borders here.
BorderFactory.createTitledBorder(objBorder, "title");

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM