我创建了一个自定义 JButton 类来表示垄断板上的空间。该游戏是多人游戏,因此绘制按钮所需的大量信息都保存在服务器上(通过 RMI 访问)。
我的问题是,当我将鼠标悬停在按钮上时,它似乎会自动调用 repaint() (并绘制边框)。这使得程序非常慢,因为每次鼠标悬停在其中一个空间上时,它都必须从服务器上提取数据。
我一直在试图找到一种方法来阻止这种情况的发生,但互联网上的其他所有人似乎都无法让按钮重新绘制()而不是停止它。
有谁知道我可以覆盖的方法或我可以更改以阻止这种情况发生的属性?
我建议重新考虑你的设计。我承认我不知道所有的因素在起作用,但根据你的描述,我认为棋盘的状态不会经常变化,所以应该没有理由在每次尝试油漆时都打电话给服务器。相反,如果您的服务器向客户端广播游戏事件,您将在本地获得repaint调用时所需的状态。
此外,根据您的描述,听起来好像您可以从repaint代码中调用服务器,由鼠标事件触发。这可以在 EDT 中很好地完成。您不应该在您的绘画线程中进行服务器调用,因为它会减慢您的 GUI 的其余部分。应该在工作线程中进行长时间运行的调用。查看SwingWorker和Swing 中有关线程的概念以了解更多详细信息。
即便如此,我认为弄乱重绘逻辑并不是最好的做法。为您的按钮提供渲染自身所需的内容是一个更好的步骤。
在你的挥杆组件的 repaint() (和paint() )方法中永远不应该有大的计算,更不用说服务器调用了......
当然可以,但不能直截了当。
无论您要在 JButton 上绘制什么,都将其转储到 BufferedImage 中。您的 JButton 的 paint() 本质上应该返回一个缓冲图像。BufferedImages 在重绘期间非常快,它们只是一个像素矩阵,重绘之间几乎不需要时间。
package test;
import java.awt.Graphics;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ButtonTest {
public static void main(String[] args){
new ButtonTest().test();
}
public void test(){
JFrame frame = new JFrame("TestFrame");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel pnl = new JPanel();
pnl.add(new MyButton());
frame.add(pnl);
frame.setSize(600, 600);
frame.setVisible(true);
}
class MyButton extends JButton{
public void paint(Graphics g){
//return a buffered image everytime
}
}
}
尽管上述技术看起来有点愚蠢,但您基本上可以在内存中拥有一个缓冲图像,并且应该从 paint() 方法返回。您从服务器 (RMI) 接收到的任何内容都可以使用在后台运行的单独线程转储到 BufferedImage 对象中。
您是否尝试过禁用焦点边框的绘画?查看JButton API 文档了解详细信息。
此外,您可以尝试缓存按钮上显示的数据。而且,一个按钮真的适合你想做的事情吗?请记住,用户期望已知的 GUI 元素以非常特定的方式做出反应。