带有TitledBorder的面板中的渐变文本字段-性能问题 [英] Gradient textfields in panel with TitledBorder - performance issue

查看:123
本文介绍了带有TitledBorder的面板中的渐变文本字段-性能问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个包含3个内部面板的面板,所有面板均使用TitledBorder.第三个内部面板具有许多用GradientPaint绘制的自定义文本字段.文本字段来自自定义类,该类扩展了JTextField并使用了覆盖的paintComponent方法和MouseListener,因此,当鼠标进入文本字段区域时,渐变颜色会稍有变化(当鼠标离开文本字段).

I have a panel with 3 inner panels that all use a TitledBorder. The third inner panel has a number of custom textfields that are painted with GradientPaint. The textfields come from a custom class that extends JTextField and uses an overriden paintComponent method along with a MouseListener, so that when mouse enters on a textfield area the gradient color slightly changes (and changes back again when mouse leaves the textfield).

问题在于,当这些文本字段位于具有TitledBorder(顺便说一句是复合边框)的面板内时,渐变颜色更改效果不佳.我的意思是他们的响应速度不够快,但是如果不在这样的小组中(我已经测试过),它们的响应就会很好.

The problem is that the gradient color change does not perform very well when those textfields are inside a panel with a TitledBorder (which by the way is a compound border). I mean that they do not respond fast enough, but they respond well when they're not in such a panel (I've tested this).

我认为问题出在边界本身,所以我试图覆盖TitledBorderpaintBorder()方法,每当调用此方法绘制边界时,我都会在其中添加一条打印语句.每次鼠标进入文本框的区域(渐变颜色更改)时,都会再次绘制TitledBorder.如果我在所有文本字段(它们只有4个)上快速移动鼠标指针,那么将再次绘制文本字段(这是正常的),但是每次也会绘制复合TitledBorder,我想这会导致性能下降.问题.

I thought that the problem is the border itself, so I tried to override the TitledBorder's paintBorder() method where I added a print statement whenever this method is called to draw the border... and it seems that every time the mouse enters a textfield's area (and the gradient color changes) the TitledBorder is painted again. If I quickly move the mouse pointer across all the textfields (they're just 4 of them) then the textfields are painted again (which is normal) but the compound TitledBorder is also painted every time and I guess that this causes the performance issue.

我的问题很简单,有什么办法可以使Java每次在面板的内部组件上移动鼠标时都不要再次绘制面板的TitledBorder?

My question is simple, is there any way that I can tell Java NOT to paint again the panel's TitledBorder every time that the mouse moves on the panel's inner components?

我了解这有时可能会引起问题,例如,如果我有一个带有组合框的小titledbordered面板:如果单击该组合框,则弹出菜单可能会隐藏面板边框的一部分(前提是该组合框靠近边框的底部),因此,当再次隐藏弹出菜单本身时,应该再次绘制边框,否则它将在弹出菜单和边框重叠的空间中留下一个空白"区域.

I understand that this may cause problems sometimes, for example if I had a small titledbordered panel with a combobox: if I clicked on that combobox, the popup menu could hide part of the panel's border (provided that the combobox is close to the border's bottom side), so when the popup menu itself is hidden again the border should be painted again or else it would leave a "blank" area at the space where the popup menu and the border overlapped.

但是在以前的情况下,面板只有文本字段,并且当鼠标移动到面板区域时,不需要再次绘制边框,是否可以阻止调用paintComponent(),如果是,如何? (或者我应该尝试一些我从未想到的完全不同的东西-对不起,我不太有经验).

But in the previous case where the panel has only textfields and there is no need that the border should be painted again when the mouse moves at the panel's area, is it acceptable to prevent paintComponent() to be called and if yes, how? (or should I try something completely different that I didn't think of - sorry I'm not very experienced).

我可以提供渐变文本字段paintComponent()方法的代码以及在mouseEntered()上发生的更改,但是我认为问题的原因很明确,而且我对它为什么会发生的假设是正确的(如果我做错了,请纠正我)...

I can provide code of the gradient textfields paintComponent() method and the change that occurs on mouseEntered() but I thought that the problem's cause is clear and my assumption of why it occurs is right (correct me if I'm wrong)...

好,在遍历自定义类尝试进行sscce时,我发现了我非常愚蠢的错误.我使用的是CustomTitledBorder类,而不是标准的TitledBorder类:

Ok while going through my custom classes trying to make the sscce I discovered my very stupid mistake. Instead of the standard TitledBorder I was using a CustomTitledBorder class that:

1)消除了在标题边框右侧添加的2个额外像素 2)使用了复合边框和其他字体(palatino粗体).

1) eliminated the 2 extra pixels added at the right side of the titled border 2) used a compound border and different font (palatino bold).

问题是palatino字体没有存储在内存中,而是在每次调用自定义类的构造函数时从磁盘读取的.因此,每次调用paintBorder()时也会调用它.因此,每当鼠标在具有上述边框的面板中的文本字段上移动时,就会调用它.这是非常愚蠢的,对此我感到很抱歉(并且我试图解决一天或更长时间的性能问题).

The problem was that the palatino font was not stored in memory but was read from the disk every time the constructor of my custom class was called. So it was also called every time paintBorder() was called. And so it was called every time the mouse moved over a textfield in the panel with the above border. This was very stupid, I'm sorry about this (and I was trying to figure out the performance problem for a day and more).

尽管这不能回答我的问题,但是如何避免每次鼠标悬停在文本字段上时都可以执行paintBorder,但是现在不再需要它了(而且我不确定是否可以接受).

This does not answer my question though on how to avoid paintBorder to be executed every time the mouse is over a textfield, but it is not needed anymore (and I'm not really sure if it is acceptable anyway).

推荐答案

BufferedImage中缓存渐变,如此处此处.还要考虑TexturePaint,如此处所示.

Cache the gradient in a BufferedImage, as shown here and here. Also consider TexturePaint, illustrated here.

这篇关于带有TitledBorder的面板中的渐变文本字段-性能问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆