java Swing重写对象的paintComponent
如果我有一个无法修改的JPanel
对象,有没有一种方法可以在不使用注入的情况下修改它的paintComponent
方法
我考虑的一种方法是获取JPanel
的Graphics
对象,将其传递给paintComponent()
,对这个Graphics
对象执行操作,最后在我的自定义JPanel
中绘制它。问题是,每次调用原始JPanel
的paintComponent()
时,我都需要这样做
我不需要替换paintComponent()中的内容,我只需要对其进行添加
例如:
JFrame frame = null;
for (Frame f : JFrame.getFrames()) {
if (((JFrame) f).getTitle().equals("Title")) {
JPanel panel = null;
// ... Cycle through all components and get the one that's a JPanel
// I want to use ColorConvertOp to make panel greyscale
}
}
# 1 楼答案
如果您能够修改类的构造,那么可以扩展该类,然后在扩展类中调用
super.paintComponent(g)
。例如:在这种情况下,您将需要一个新类来构建现有类的绘画
这样做的目的是执行父类绘制中完成的所有操作,并为您提供执行更多操作的选项(这似乎是您正在寻找的)
编辑
但是考虑到你没有访问权限,你的选择会变得更加有限。如果面板使用空布局管理器,则可以添加在父面板上绘制的子jpanel(布局管理器会限制子面板可以绘制的面积)。这是不可能的
你也可以使用反射来解释你唯一的选择(除了字节码注入)。这似乎和字节码注入一样难看——下面是一个关于你将要做的事情的不错的概述:Java reflection: How do I override or generate methods at runtime?
我个人的偏好是反编译这个类,按照你想要的方式修改它,重新编译它,然后将它插入到原始的jar中。这可能会使一些仓库、许可证作废,并给你带来其他麻烦。。。但至少它是可维护的
# 2 楼答案
我认为一种可能性是使用^{} 并将其精确定位在
JPanel
上方(如果面板改变了位置,可以使用侦听器让它跟随面板)。然后你可以在玻璃窗格中简单地画出你的东西,然后将其覆盖当然这不是很优雅。。。但是我不认为有任何可能在不注入的情况下改变已经存在的实例的
paintComponents
行为。(证明我错了,这个世界上的Java极客!:P)# 3 楼答案
一种方法是使用Decorator Pattern来包装现有的类。然后,装饰师可以实现paintComponent,首先将其委托给原始组件,然后再在其上绘制。对于这种方法,您需要实际控制组件的创建,或者需要在创建组件层次结构后替换它们(使用父容器的getComponents()查找要修改的组件)
# 4 楼答案
我想这将完成@Durandal的回答:
可以将灰度标志设置为false,以查看其正常渲染方式