问答文章1 问答文章501 问答文章1001 问答文章1501 问答文章2001 问答文章2501 问答文章3001 问答文章3501 问答文章4001 问答文章4501 问答文章5001 问答文章5501 问答文章6001 问答文章6501 问答文章7001 问答文章7501 问答文章8001 问答文章8501 问答文章9001 问答文章9501

如何用SwingBuilder使用自定义的swing组件

发布网友 发布时间:2022-05-02 03:21

我来回答

1个回答

热心网友 时间:2022-04-22 23:14

groovy已经在SwingBuilder里为我们预设了很多swing组件,以使我们可以用下面这样的快捷形式来构建界面:
swingBuilder.frame(
//属性集
){
//子组件
}
对于仅仅使用swing的原生组件,这没有任何问题,但在实际开发中可能会遇到需要使用对原生组件扩展后的自定义组件(如一个继承了JPanel的MyPanel类)的情况,而这个类明显不可能出现在SwingBuilder的预设列表里,那这种情况下是不是就意味着不可以使用groovy为我们提供的便利,只能用回传统的java形式去构建界面呢?
答案是否定的。SwingBuilder虽然不会预设用户自定义的组件,但它提供了几个接口可以让用户把自定义的组件设置进去,这样就依然可以用groovy的快捷形式来构建界面了。这几个接口分别是:
public void registerFactory(String name, Factory factory)
public void registerBeanFactory(String theName, Class beanClass)
registerFactory()
registerFactory方法可以注册一个自定义组件,name指定了通过swingBuilder构建组件的名称,如JFrame在swingBuilder里预设的name是"frame",这就使得我们可以通过swingBuilder.frame()构建一个JFrame。
第二个参数接收一个实现了Factory接口的类,这个类需指明(实现)如何实例化自定义组件(newInstance),如何处理add进来的子组件(setChild)等一系列策略。通常并不需要直接实现Factory接口,groovy为我们提供了一个抽象类(AbstractFactory),我们应优先继承这个类,然后再按需挑相应的方法进行重写。下面来看一个如何使用这个接口的例子:
/**
* 自定义了一个可以显示背景图片的面板
* @author keenlight
*
*/
class ImagePanel extends JPanel{
/**
*
*/
private static final long serialVersionUID = 1L
private BufferedImage image
public ImagePanel(BufferedImage image){
super()
this.image = image
}
public ImagePanel(BufferedImage image, LayoutManager layout) {
super(layout)
this.image = image
}
public void paintComponent(Graphics g)
{
super.paintComponent(g)
if(image != null){
g.drawImage(image, 0, 0, this)
}
}
}
/**
* ImagePanel的Factory
* @author keenlight
*/
class ImagePanelFactory extends AbstractFactory{
private BufferedImage image
ImagePanelFactory(BufferedImage image){
this.image = image
}
@Override
public Object newInstance(FactoryBuilderSupport builder, Object name, Object value, Map properties) throws InstantiationException, IllegalAccessException {
def layout = properties.remove("layout")
new ImagePanel(image, layout)
}
public void setChild(FactoryBuilderSupport builder, Object parent, Object child) {
if (!(child instanceof Component) || (child instanceof Window)) {
return
}
parent = parent as ImagePanel
try {
def constraints = builder.context.constraints
if (constraints != null) {
parent.add(child, constraints)
if (child instanceof JComponent) {
child.putClientProperty(LayoutFactory.DEFAULT_DELEGATE_PROPERTY_CONSTRAINT, constraints)
}
builder.context.remove('constraints')
} else {
parent.add(child)
}
} catch (MissingPropertyException mpe) {
parent.add(child)
}
}
}
定义好这些类后如何使其生效?只需一步:
def bgImage = ImageIO.read(new File(image_path))
swingBuilder.registerFactory("imagePanel", new ImagePanelFactory(bgImage))
注册好之后,ImagePanel组件便可像其他原生组件一样使用了(如上文的JFrame一样)。
registerBeanFactory()
registerBeanFactory是registerFactory的一种便利形式,调用此接口无需提供Factory,只需提供自定义类的类名即可。比如原生组件里的JPanel就是用这个接口注册的,SwingBuilder类中注册JPanel的源码如下:
registerBeanFactory("panel", JPanel)
这样就可以把JPanel注册为"panel"来使用了。其实registerBeanFactory这个方法里面一样也实例化了一个继承了AbstractFactory类,它会把调用这个方法注册的组件当做一个javaBean(方法名已经很明显了),所以它在继承AbstractFactory类时重写的newInstance方法里是直接返回调用class.newInstance()的实例化结果,class由第二个入参提供。所以对于那些在实例化时调用默认构造器就足够的组件,用registerBeanFactory()方法来注册会更为便利。当然,对于我上面定义的ImagePanel来说就不行了,因为ImagePanel类在实例化时需要接受一个图片对象,所以必须使用略麻烦一点的registerFactory()。
声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com
2023文科男生最吃香的专业 哪些专业好就业 在南京想找上海音乐学院的老师,怎么找? 荔枝核怎么服用-荔枝核煮水一般煮几颗合适 属虎适合什么名字2022年新生儿 有内涵热门名字精选 国内读研好,还是出国读研好 出国读研和国内读研哪个更好 在一个比例中,如果两个外项互为倒数。那么两个内向的什么是一?_百度知 ... 两个外项互为倒数,一个内向是8分之3,另一个内项是多少【怎样求出来... 在一个比例中,两个外向互为倒数,其中一个内项是8,另一个内项是_百度... 在比例中两个外项互为倒数,其中一个内向是2.75,另一个内项是多少_百度... 【初学者】用Window builder设置多个panel 【初学者】用Window builder设置多个panel 手机四位锁一般人都会设置成什么啊 java 如何用eclipse 的window builder做一个可视化的发扑克牌程序,里面扑克 java 如何用eclipse 的window builder做一个可视化的发扑克牌程序,里面扑克 东西卖便宜了,我不想卖给他了,可他不肯还给我? 关于java window builder 关于java window builder 安卓手机忘记了4位解锁密码怎么办 如何用PanelBuilder32打开*.PVA 文件 iOS 的四位锁码有可能被破解吗 东西卖便宜了,后悔怎么办? C++ Builder 中Radiobutton的分组问题 iOS的四位锁码有可能被破解吗? 请问 超类为 javax.swing.JFrame,如何解决图中的问题?window builder editor为什么用不了?在线等 怎么hbuilder自定义panel颜色 c++菜鸟提问,关于c++ builder panel控件,如何在panel控件上实现插入两幅图片,且按照一定的时间间隔转换 PanelView 1000 用什么软件打开 AB触摸屏程序下载问题 wincc和panel builder32 冲突吗 交易猫卖便宜了可以拒绝发货吗 C++builder中如何重载一个combobox控件 C++builder中如何重载一个combobox控件 梦见男朋友打架吐血我愤怒的杀那些人 C++BUILDER中几种容器的使用求答案 C++BUILDER中几种容器的使用求答案 为什么powerpoint 2003文件的缩略图显示是空白的 为什么一些软件会员卖这么贵,卖便宜点不是更多人买吗? 系统版本升级过。手机无锁屏密码的状态下。 关机重启后让输入四位锁 为什么一些软件会员卖这么贵,卖便宜点不是更多人买吗? C++Builder 中Status的每个Panel里的内容怎么用代码控制?? 为什么有的手机配置那么高,却卖得很便宜? 邻居给我说她把东西给我亲戚卖便宜啦,我该怎么说? panel在Borland C++Builder 6.0哪个组件 ofo小黄车解锁后立刻点结束用车,这样只扣一个起步费,如果我不锁车是不是可以无限用? 正品二手包包哪个平台卖便宜 梦见和男朋友回家的路上有两个男人倒在地上吐血? 求高手指点。c++Builder中有TPanel这个类吗?有的话,这个类是干什么的呢? 淘宝上买东西卖家说卖便宜了不给发货怎么办 苹果6怎么解锁