web系统主题包的实现
实现的基本思路为,定义好每个控件的抽象,然后分离出一个主题包,由主题包内类继承定义好的抽象类,把每个需要的html标签,或者页面组件抽象出来,具体的实现:通过
拼接html,加入抽象实现返回的参数,拼接成一段html可以解析的html代码片段!
一、预定义一个主题的抽象类,预定义系统所需的图标名称(add、edit、delete等等),需要引入的html组件名称(rtf 文本编辑框,datepicker 时间控件等等),
初始化主题(设置主题名称、css、脚本等),get(获得主题元素,通过父的抽象类,返回一个实现抽象类的子类的实例化对象,因为真正实现抽象类的子类是在
主题包中,这里有我们的一些规则,通过工厂类调用接口(抽象类)就可以实例化所需要的具体实现的子类)
1 package com.sun.Theme; 2 3 import java.util.Map; 4 5 public abstract class AbsTheme { 6 // 图标 7 public static final String ICON_ADD = "add"; // 加(新增) 8 public static final String ICON_MINUS = "minus"; // 减 9 public static final String ICON_DELETE = "delete"; // 删除(垃圾箱) 10 public static final String ICON_EDIT = "edit"; // 编辑 11 public static final String ICON_SAVE = "save"; // 保存 12 public static final String ICON_SUBMIT = "submit"; // 提交 13 // 等等 一系列icon 14 15 public static final String RESOURCE_RTF = "rtf";//rich text format 16 public static final String RESOURCE_FILE = "file"; 17 public static final String RESOURCE_DATEPICKER = "datepicker"; 18 //一系列引入组件的名称 19 20 private static String name; 21 private static String contextPath; 22 private static Map<String, String> icons; 23 24 /** 25 * 初始化 26 * <p> 27 * 设置主题名称、CSS和脚本 28 */ 29 public abstract void init(); 30 31 /** 32 * 获取主题元素 33 * 34 * @param c 主题元素需要实现的接口类 35 * @param <T> 继承Html 36 * @return 37 */ 38 public <T extends AbsHtml> T get(Class<T> c) { 39 // String[] names = c.getName().split("\\."); 40 // String name = names[names.length-1]; 41 String elementName = c.getName().replace("Abs", ""); 42 try { 43 return c.cast(Class.forName(elementName).newInstance()); 44 } catch (Exception e) { 45 } 46 return null; 47 } 48 49 /** 50 * 获取主题资源 51 * 52 * @param resource 资源,这里我们系统中是rtf,file,datepicker 这里引入的资源代表着需要引入的js,和css文件 53 * 可以做成标签的形式,可以在后面博客举出例子 54 * @return 55 */ 56 public abstract String getResource(String resource); 57 58 /** 59 * 获取主题名称 60 * 61 * @return 62 */ 63 public static String getName() { 64 return name; 65 } 66 67 /** 68 * 设置主题名称 69 * 70 * @param name 名称 71 */ 72 protected void setName(String name) { 73 AbsTheme.name = name; 74 } 75 76 /** 77 * 获取请求上下文路径 78 * 79 * @return 80 */ 81 public static String getContextPath() { 82 return contextPath; 83 } 84 85 /** 86 * 设置请求上下文路径 87 * 88 * @param contextPath 路径 89 */ 90 public void setContextPath(String contextPath) { 91 AbsTheme.contextPath = contextPath; 92 } 93 94 /** 95 * 获取图标类 96 * 97 * @param icon 图标 98 * @return 99 */ 100 public static String getIconCls(String icon) { 101 if (null == icons) { 102 return null; 103 } 104 105 return icons.get(icon); 106 } 107 108 /** 109 * 设置图标集合 110 * 111 * @param icons 图表集合 112 */ 113 public void setIcons(Map<String, String> icons) { 114 AbsTheme.icons = icons; 115 } 116 }
Theme类是实现了抽象主题类的子类,在这里,我们可以定义一个主题的标识(比如说bootstrap,easyUI),初始化主题,设置名称,图标集。资源文件的引入,首先既然我们选用了bootstrap那么我们需要引入bootstrap的基础资源包,然后还有我们预定义的所有我们使用到的前端组件的资源文件。
1 package com.sun.Theme; 2 3 import java.util.HashMap; 4 import java.util.Map; 5 6 import org.apache.commons.lang.StringUtils; 7 8 public class Theme extends AbsTheme { 9 public static final String NAME = "bootstrap";//主题名称,可以是EasyUI 10 11 @Override 12 public void init() { 13 this.setName(NAME); 14 15 Map<String, String> icons = new HashMap<String, String>(); 16 icons.put(Theme.ICON_ADD, "glyphicon glyphicon-plus"); 17 icons.put(Theme.ICON_MINUS, "glyphicon glyphicon-minus"); 18 icons.put(Theme.ICON_DELETE, "glyphicon glyphicon-trash"); 19 icons.put(Theme.ICON_EDIT, "glyphicon glyphicon-edit"); 20 icons.put(Theme.ICON_SAVE, "glyphicon glyphicon-floppy-disk"); 21 22 this.setIcons(icons); 23 } 24 25 @Override 26 public String getResource(String resource) { 27 String contextPath = Theme.getContextPath(); 28 StringBuilder builder = new StringBuilder(); 29 //引入资源,关于本主题的所有资源,这里可能就做为一个系统的head内容 30 builder.append("<meta charset=\"utf-8\">\n"); 31 builder.append("<meta name=\"renderer\" content=\"webkit\">\n"); 32 builder.append("<meta http-equiv=\"X-UA-Compatible\" content=\"IE=edge\">\n"); 33 builder.append("<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n"); 34 builder.append("<link href=\"" + contextPath + "/system/css/bootstrap.min.css\" rel=\"stylesheet\" charset=\"UTF-8\">\n"); 35 builder.append("<link href=\"" + contextPath + "/system/css/bootstrap-theme.min.css\" rel=\"stylesheet\" charset=\"UTF-8\">\n"); 36 builder.append("<script src=\"" + contextPath + "/system/script/modernizr-2.8.3.min.js\" charset=\"UTF-8\"></script>\n"); 37 builder.append("<script src=\"" + contextPath + "/system/script/jquery-1.11.1.min.js\" charset=\"UTF-8\"></script>\n"); 38 builder.append("<script src=\"" + contextPath + "/system/script/bootstrap.min.js\" charset=\"UTF-8\"></script>\n"); 39 if (StringUtils.isNotBlank(resource)) { 40 String[] resources = resource.split(","); 41 for (int i = 0; i < resources.length; i++) {//这里用的是我们寻找的一些前端组件 42 String res = resources[i]; 43 if (RESOURCE_DATEPICKER.equals(res)) { 44 builder.append("<link href=\"" + contextPath + "/system/css/bootstrap-datetimepicker.min.css\" rel=\"stylesheet\" charset=\"UTF-8\">\n"); 45 builder.append("<script src=\"" + contextPath + "/system/script/bootstrap-datetimepicker.min.js\" charset=\"UTF-8\"></script>\n"); 46 builder.append("<script src=\"" + contextPath + "/system/script/bootstrap-datetimepicker.zh-CN.js\" charset=\"UTF-8\"></script>\n"); 47 } else if (RESOURCE_FILE.equals(res)) { 48 builder.append("<script src=\"" + contextPath + "/system/script/bootstrap-filestyle.js\"></script>\n"); 49 } else if (RESOURCE_RTF.equals(res)) { 50 builder.append("<script src=\"" + contextPath + "/system/script/ueditor/ueditor.config.js\"></script>"); 51 builder.append("<script src=\"" + contextPath + "/system/script/ueditor/ueditor.all.js\"></script>"); 52 } 53 } 54 } 55 return builder.toString(); 56 } 57 }
ThemeFactory 这是一个工厂类,负责初始化哪一个主题,其中,getTheme方法会根据系统中的配置文件(这算是提供一个切换主题的方式),通过规定的类路径实例化主题对象,初始化主题,这里少写了文件路径context,即(theme.setContextPath) 设置为当前请求类路径(比如struts-----ServletActionContext.getRequest().getContextPath()),这样我们就确定了使用哪一个主题,这里还提供了get()方法获得主题下的元素,实际上是调用了当前theme的get方法,返回继承thme抽象类的具体实现类的实例化对象,即Button继承AbsHtml,那么具体实现就是AbsHtml html = new Button();
1 package com.sun.Theme; 2 3 import java.util.Properties; 4 5 /** 6 * 主题工厂 7 */ 8 public class ThemeFactory { 9 10 private static final String THEME_CONFIG = "theme"; 11 12 /** 13 * 系统采用主题 14 */ 15 private static AbsTheme theme = null; 16 17 private ThemeFactory() { 18 } 19 20 /** 21 * 获取主题 22 * @return 23 */ 24 public static AbsTheme getTheme() { 25 if (null == ThemeFactory.theme) { 26 getTheme(null); 27 } 28 29 return ThemeFactory.theme; 30 } 31 32 /** 33 * 获取主题下的元素 34 * @param c html的Class 35 * @param <T> 泛型 36 * @return 37 */ 38 public static <T extends AbsHtml> T get(Class<T> c) { 39 if (null == ThemeFactory.theme) { 40 getTheme(null); 41 } 42 43 return ThemeFactory.theme.get(c); 44 } 45 46 /** 47 * 根据配置获取主题 48 * @param properties 主题配置信息 49 * @see SysException 50 */ 51 private static void getTheme(Properties properties) { 52 // String themeConfig = properties.getProperty(THEME_CONFIG); 53 // if (StringUtils.isBlank(themeConfig)) { 54 // System.out.println("主题文件没有"); 55 // } 56 57 synchronized (ThemeFactory.class) { 58 if (null != ThemeFactory.theme) { 59 return; 60 } 61 try { 62 String clazz = Theme.class.getName(); 63 AbsTheme theme = (AbsTheme)Class.forName("com.sun.Theme.Theme").newInstance(); 64 theme.init(); 65 66 ThemeFactory.theme = theme; 67 } catch (Exception e) { 68 } 69 } 70 } 71 }
这里我们把html标签组件化,AbsHtml便是抽象出来的顶级类,AbsHtml包含了id,name,width,height等公共属性,也是每个html标签的基本属性,这里方法有相应注释,可以详细了解一下,看看是否有不足之处。
1 package com.sun.Theme; 2 3 import java.util.HashMap; 4 import java.util.Iterator; 5 import java.util.Map; 6 7 import org.apache.commons.lang.StringUtils; 8 9 /** 10 * AbsHtml接口 11 */ 12 public abstract class AbsHtml { 13 14 public static final String ID_SUFFIX = "_"; 15 16 protected Boolean visible; 17 protected Boolean disabled; 18 protected String innerAbsHtml; 19 protected String events; 20 protected Map<String, Object> attributes; 21 protected String id; 22 protected String name; 23 protected String cls; 24 protected Map<String, String> style; 25 protected String title; 26 protected String script; 27 protected String width; 28 protected String height; 29 30 /** 31 * 获取AbsHtml 32 * 33 * @return 34 */ 35 public abstract String getHtml(); 36 37 /** 38 * 是否可见 39 * 40 * @return 41 */ 42 public Boolean isVisible() { 43 if (null == visible) { 44 return Boolean.TRUE; 45 } 46 47 return visible; 48 } 49 50 /** 51 * 设置可见性 52 * 53 * @param visible 是否可见 54 * @param <T> 泛型 55 * @return 56 */ 57 public <T extends AbsHtml> T setVisible(Boolean visible) { 58 this.visible = visible; 59 60 return (T) this; 61 } 62 63 /** 64 * 是否被禁用 65 * <p> 66 * 默认否 67 * 68 * @return 69 */ 70 public Boolean isDisabled() { 71 if (null == disabled) { 72 return Boolean.FALSE; 73 } 74 75 return disabled; 76 } 77 78 /** 79 * 设置是否禁用元素 80 * 81 * @param disabled 是否禁用元素 82 * @param <T> 泛型 83 * @return 84 */ 85 public <T extends AbsHtml> T setDisabled(Boolean disabled) { 86 this.disabled = disabled; 87 88 return (T) this; 89 } 90 91 /** 92 * 禁用元素 93 * 94 * @param <T> 泛型 95 * @return 96 */ 97 public <T extends AbsHtml> T disable() { 98 this.disabled = Boolean.TRUE; 99 100 return (T) this; 101 } 102 103 /** 104 * 启用元素 105 * 106 * @param <T> 泛型 107 * @return 108 */ 109 public <T extends AbsHtml> T enable() { 110 this.disabled = Boolean.FALSE; 111 112 return (T) this; 113 } 114 115 /** 116 * 获取AbsHtml元素的innerAbsHtml 117 * 118 * @return 119 */ 120 public String getInnerHTML() { 121 return this.innerAbsHtml; 122 } 123 124 /** 125 * 设置AbsHtml元素的innerAbsHtml 126 * 127 * @param innerAbsHtml innerAbsHtml 128 * @param <T> 泛型 129 * @return not null 130 */ 131 public <T extends AbsHtml> T setInnerHTML(String innerAbsHtml) { 132 this.innerAbsHtml = innerAbsHtml; 133 134 return (T) this; 135 } 136 137 /** 138 * 获取事件 139 * 140 * @return 141 */ 142 public String getEvents() { 143 return this.events; 144 } 145 146 /** 147 * 148 * 设置事件 149 * 150 * @param events 事件 151 * @param <T> 泛型 152 * <p> 153 * 例如一个input元素的events是:onclick="a()" onblur="b()",则会形成: 154 * <input onclick="a()" onblur="b()" /> 155 * @return 156 */ 157 public <T extends AbsHtml> T setEvents(String events) { 158 this.events = events; 159 160 return (T) this; 161 } 162 163 /** 164 * 165 * 添加事件 166 * 167 * @param <T> 泛型 168 * @param events 事件 169 * @return 170 */ 171 public <T extends AbsHtml> T addEvents(String events) { 172 if (StringUtils.isNotBlank(events)) { 173 if (null == this.events) { 174 this.events = events; 175 } else { 176 this.events += (events.indexOf(" ") == 0 ? events : (" " + events)); 177 } 178 } 179 180 return (T) this; 181 } 182 183 /** 184 * 获取AbsHtml元素属性 185 * 186 * @return 187 */ 188 public Map<String, Object> getAttributes() { 189 return this.attributes; 190 } 191 192 /** 193 * 获取AbsHtml元素属性 194 * 195 * @param name 属性名 196 * @return 197 */ 198 public Object getAttribute(String name) { 199 if (null == this.attributes) { 200 return null; 201 } 202 203 return this.attributes.get(name); 204 } 205 206 /** 207 * 设置AbsHtml元素属性 208 * 209 * @param attributes 属性集合 210 * @param <T> 泛型 211 * @return 212 */ 213 public <T extends AbsHtml> T setAttributes(Map<String, Object> attributes) { 214 this.attributes = attributes; 215 216 return (T) this; 217 } 218 219 /** 220 * 设置AbsHtml元素属性 221 * 222 * @param name 属性名 223 * @param value 属性值 224 * @param <T> 泛型 225 * @return 226 */ 227 public <T extends AbsHtml> T setAttribute(String name, Object value) { 228 if (null == this.attributes) { 229 this.attributes = new HashMap<String, Object>(); 230 } 231 this.attributes.put(name, value); 232 233 return (T) this; 234 } 235 236 /** 237 * 获取AbsHtml元素id 238 * 239 * @return 240 */ 241 public String getId() { 242 if (StringUtils.isNotBlank(this.id)) { 243 return this.id; 244 } 245 246 if (StringUtils.isNotBlank(this.getName())) { 247 this.setId(this.getName() + ID_SUFFIX); 248 } 249 250 return this.id; 251 } 252 253 /** 254 * 设置AbsHtml元素id 255 * 256 * @param id id 257 * @param <T> 泛型 258 * @return 259 */ 260 public <T extends AbsHtml> T setId(String id) { 261 this.id = id; 262 263 return (T) this; 264 } 265 266 /** 267 * 获取AbsHtml元素的name属性 268 * 269 * @return 270 */ 271 public String getName() { 272 return this.name; 273 } 274 275 /** 276 * 设置AbsHtml元素的name 277 * 278 * @param name AbsHtml元素的name 279 * @param <T> 泛型 280 * @return 281 */ 282 public <T extends AbsHtml> T setName(String name) { 283 this.name = name; 284 285 return (T) this; 286 } 287 288 /** 289 * 获取AbsHtml元素的class 290 * 291 * @return 292 */ 293 public String getCls() { 294 return this.cls; 295 } 296 297 /** 298 * 设置AbsHtml元素的class 299 * 300 * @param cls AbsHtml元素的class 301 * @param <T> 泛型 302 * @return 303 */ 304 public <T extends AbsHtml> T setCls(String cls) { 305 this.cls = cls; 306 307 return (T) this; 308 } 309 310 /** 311 * 添加AbsHtml元素的class,不覆盖已有的class 312 * 313 * @param cls AbsHtml元素的class 314 * @param <T> 泛型 315 * @return 316 */ 317 public <T extends AbsHtml> T addCls(String cls) { 318 if (StringUtils.isNotBlank(cls)) { 319 if (null == this.cls) { 320 this.cls = cls; 321 } else { 322 this.cls += (cls.indexOf(" ") == 0 ? cls : (" " + cls)); 323 } 324 } 325 326 return (T) this; 327 } 328 329 /** 330 * 获取AbsHtml元素的样式 331 * 332 * @return 333 */ 334 public String getStyle() { 335 //if (CollectionUtils.isEmpty(style)) {//org.springframework.util.CollectionUtils 336 if (style == null) { 337 return null; 338 } 339 340 StringBuilder builder = new StringBuilder(); 341 for (Iterator<String> iterator = this.style.keySet().iterator(); iterator.hasNext();) { 342 String key = iterator.next(); 343 String value = style.get(key); 344 builder.append(key); 345 builder.append(":"); 346 builder.append(value); 347 if (!value.endsWith(";")) { 348 builder.append(";"); 349 } 350 351 } 352 353 return builder.toString(); 354 } 355 356 /** 357 * 获取AbsHtml元素的样式 358 * 359 * @param key style的键 360 * @return 361 */ 362 public String getStyle(String key) { 363 if (null == style) { 364 return null; 365 } 366 367 return style.get(key); 368 } 369 370 /** 371 * 添加AbsHtml元素的样式 372 * 373 * @param key 键 374 * @param value 值 375 * @param <T> 泛型 376 * @return 377 */ 378 public <T extends AbsHtml> T addStyle(String key, String value) { 379 if (StringUtils.isBlank(key) || key.indexOf(":") != -1 || key.indexOf(";") != -1 || StringUtils.isBlank(value) || value.indexOf(":") != -1) { 380 throw new RuntimeException("违法操作!"); 381 } 382 if (null == style) { 383 style = new HashMap<String, String>(); 384 } 385 style.put(key, value); 386 387 return (T) this; 388 } 389 390 /** 391 * 获取AbsHtml元素的title 392 * 393 * @return 394 */ 395 public String getTitle() { 396 return this.title; 397 } 398 399 /** 400 * 设置AbsHtml元素的title 401 * 402 * @param title AbsHtml元素的title 403 * @param <T> 泛型 404 * @return 405 */ 406 public <T extends AbsHtml> T setTitle(String title) { 407 this.title = title; 408 409 return (T) this; 410 } 411 412 /** 413 * 获取脚本 414 * 415 * @return 416 */ 417 public String getScript() { 418 return this.script; 419 } 420 421 /** 422 * 423 * 设置脚本 424 * 425 * @param script 脚本 426 * <p> 427 * 例如select级联,需要在页面加载完成后, 428 * @param <T> 泛型 429 * @return 430 */ 431 public <T extends AbsHtml> T setScript(String script) { 432 this.script = script; 433 434 return (T) this; 435 } 436 437 /** 438 * 增加脚本 439 * 440 * @param script 脚本 441 * @param <T> 泛型 442 * @return 443 */ 444 public <T extends AbsHtml> T addScript(String script) { 445 if (StringUtils.isBlank(this.script)) { 446 this.script = script; 447 } else { 448 this.script = this.script + script; 449 } 450 451 return (T) this; 452 } 453 454 /** 455 * 元素宽度,这个值会被设置到元素的样式上,请带上单位px或em等 456 * 457 * @return 458 */ 459 public String getWidth() { 460 return width; 461 } 462 463 /** 464 * 设置宽度 465 * 466 * @param width 宽度 467 * @param <T> 泛型 468 * @return 469 */ 470 public <T extends AbsHtml> T setWidth(String width) { 471 this.width = width; 472 473 return (T) this; 474 } 475 476 /** 477 * 元素高度 478 * 479 * @return 480 */ 481 public String getHeight() { 482 return height; 483 } 484 485 /** 486 * 设置高度 487 * 488 * @param height 高度 489 * @param <T> 泛型 490 * @return 491 */ 492 public <T extends AbsHtml> T setHeight(String height) { 493 this.height = height; 494 495 return (T) this; 496 } 497 }
下面演示一个实例组件,AbsButton继承了AbsHtml,并抽象出了button公共的方法,无论哪个主题包,按钮组件都应该继承这个类
1 package com.sun.Theme; 2 3 public abstract class AbsButton extends AbsHtml { 4 5 /** 6 * 按钮类型:按钮 7 */ 8 public static final String BUTTON = "Button"; 9 10 /** 11 * 按钮类型:重置按钮 12 */ 13 public static final String RESET = "reset"; 14 15 /** 16 * 按钮类型:提交按钮 17 */ 18 public static final String SUBMIT = "submit"; 19 20 /** 21 * 按钮类型:查询按钮 22 */ 23 public static final String SEARCH = "search"; 24 25 /** 26 * 默认按钮大小 27 */ 28 public static final int SIZE_DEFAULT = 3; 29 /** 30 * 比默认大小小一号 31 */ 32 public static final int SIZE_SMALL = 2; 33 /** 34 * 比默认大小小两号 35 */ 36 public static final int SIZE_SMALLER = 1; 37 /** 38 * 比默认大小大一号 39 */ 40 public static final int SIZE_LARGE = 4; 41 /** 42 * 比默认大小大两号 43 */ 44 public static final int SIZE_LARGER = 5; 45 46 private String type; 47 private String icon; 48 private int size = SIZE_DEFAULT; 49 private Boolean active; 50 51 52 /** 53 * 按钮类型 54 * @return 55 */ 56 public String getType() { 57 return this.type; 58 } 59 60 /** 61 * 设置按钮类型 62 * @param type type 63 * @param <T> 泛型 64 * @return 65 */ 66 public <T extends AbsButton> T setType(String type) { 67 this.type = type; 68 69 return (T)this; 70 } 71 72 /** 73 * 获取图标 74 * @return 75 */ 76 public String getIcon() { 77 return this.icon; 78 } 79 80 /** 81 * 设置图标 82 * @param icon icon 83 * @param <T> 泛型 84 * @return 85 */ 86 public <T extends AbsButton> T setIcon(String icon) { 87 this.icon = icon; 88 89 return (T)this; 90 } 91 92 /** 93 * 获取按钮大小 94 * <p> 5 : 比4大一号 {@link #SIZE_LARGER} 95 * <p> 4 : 比普通大一号 {@link #SIZE_LARGE} 96 * <p> 3 : 普通大小 {@link #SIZE_DEFAULT} 97 * <p> 2 : 比普通小一号 {@link #SIZE_SMALL} 98 * <p> 1 : 比2小一号 {@link #SIZE_SMALLER} 99 * <p> 超出此范围的,默认大小算 100 * @return 101 */ 102 public int getSize() { 103 return size; 104 } 105 106 /** 107 * 设置按钮大小 108 * @param size size 109 * @param <T> 泛型 110 */ 111 public <T extends AbsButton> T setSize(int size) { 112 this.size = size; 113 114 return (T)this; 115 } 116 117 /** 118 * 是否处于激活状态 119 * 默认否 120 * @return 121 */ 122 public Boolean getActive() { 123 if (null == active) { 124 return Boolean.FALSE; 125 } 126 127 return active; 128 } 129 130 /** 131 * 设置是否处于激活状态 132 * @param active active 133 * @param <T> 泛型 134 * @return 135 */ 136 public <T extends AbsButton> T setActive(Boolean active) { 137 this.active = active; 138 139 return (T)this; 140 } 141 }
这是button组件,实现了AbsButton类,当然这个示例是bootstrap主题,那么,我们只需要拼接出一条<button></button>并附加上图标,样式,大小等等bootstrap样式就可以了
1 package com.sun.Theme; 2 3 import org.apache.commons.lang.StringUtils; 4 5 public class Button extends AbsButton { 6 public static final String BUTTON_CONFIG = "button.class"; 7 public static final String BUTTON_DEFAULT = "btn btn-default"; 8 9 @Override 10 public String getHtml() { 11 12 this.setCls((StringUtils.isBlank(this.getCls()) ? HtmlGenerator.getButtonCls(this.getSize()) : this.getCls()) + (this.getActive() ? " active" : "")); 13 HtmlGenerator.setStyle(this); 14 15 StringBuilder builder = new StringBuilder("<button type=\""); 16 builder.append(null == this.getType() ? AbsButton.BUTTON : this.getType()); 17 builder.append("\""); 18 HtmlGenerator.buildHtml(builder, this, false); 19 builder.append(">"); 20 21 if (StringUtils.isNotBlank(this.getIcon())) { 22 builder.append("<span class=\"" + Theme.getIconCls(this.getIcon()) + "\"></span>"); 23 } 24 if (StringUtils.isNotBlank(this.getInnerHTML())) { 25 builder.append(this.getInnerHTML()); 26 } 27 builder.append("</button>"); 28 if (StringUtils.isNotBlank(this.getScript())) { 29 builder.append(this.getScript()); 30 } 31 32 return builder.toString(); 33 } 34 35 }
这是按钮组的具体实现,这里需要注意的就是按钮组的作用就是把多个按钮分组,那么他肯定需要一个List<AbsHtml> buttons,来存储多个按钮解析生成类似<div><button></button><button></button></div>的html片段
1 package com.sun.Theme; 2 3 import java.util.ArrayList; 4 import java.util.List; 5 6 public abstract class AbsButtonGroup extends AbsHtml { 7 private int size = Button.SIZE_DEFAULT; 8 private List<AbsHtml> buttons; 9 /** 10 * @see Button#getSize 11 * @return 12 */ 13 public int getSize() { 14 return size; 15 } 16 17 /** 18 * @see Button#setSize 19 * @param size size 20 * @param <T> 泛型 21 */ 22 public <T extends AbsButtonGroup> T setSize(int size) { 23 this.size = size; 24 25 return (T)this; 26 } 27 28 /** 29 * 获取所有Button元素 30 * @return 31 */ 32 public List<AbsHtml> getButtons() { 33 return this.buttons; 34 } 35 36 /** 37 * 设置所有Button元素 38 * @param buttons button集合 39 * @param <T> 泛型 40 * @return 41 */ 42 public <T extends AbsButtonGroup> T setButtons(List<AbsHtml> buttons) { 43 this.buttons = buttons; 44 45 return (T)this; 46 } 47 48 /** 49 * 添加Button元素 50 * @param button button 51 * @param <T> 泛型 52 * @return 53 */ 54 public <T extends AbsButtonGroup> T addButton(AbsHtml button) { 55 if (null == this.buttons) { 56 this.buttons = new ArrayList<AbsHtml>(); 57 } 58 59 this.buttons.add(button); 60 61 return (T)this; 62 } 63 64 /** 65 * 插入Button元素 66 * @param index 插入位置 67 * @param button Button元素 68 * @param <T> 泛型 69 * @return 70 */ 71 public <T extends AbsButtonGroup> T insertButton(int index, AbsHtml button) { 72 if (null == this.buttons) { 73 this.buttons = new ArrayList<AbsHtml>(); 74 } 75 76 this.buttons.add(index, button); 77 78 return (T)this; 79 } 80 81 @Override 82 public AbsButtonGroup disable() { 83 super.disable(); 84 if (buttons != null ) { 85 for (AbsHtml button : buttons) { 86 button.disable(); 87 } 88 } 89 90 return this; 91 } 92 93 @Override 94 public AbsButtonGroup enable() { 95 super.enable(); 96 if (buttons != null) { 97 for (AbsHtml button : buttons) { 98 button.enable(); 99 } 100 } 101 102 return this; 103 } 104 105 }
这是一个html的处理的生产类,把公共的属性的生产方法提取出来
1 package com.sun.Theme; 2 3 import java.util.List; 4 5 import org.apache.commons.lang.StringUtils; 6 7 public class ButtonGroup extends AbsButtonGroup { 8 public static final String BUTTON_GROUP_CONFIG = "buttongroup.class"; 9 public static final String BUTTON_GROUP_DEFAULT = "btn-group"; 10 11 @Override 12 public String getHtml() { 13 this.setCls(StringUtils.isBlank(this.getCls()) ? BUTTON_GROUP_DEFAULT : this.getCls()); 14 HtmlGenerator.setStyle(this); 15 16 StringBuilder builder = new StringBuilder("<div role=\"group\" aria-label=\"button group\""); 17 HtmlGenerator.buildHtml(builder, this, false); 18 builder.append(">"); 19 List<AbsHtml> buttons = this.getButtons(); 20 if (buttons != null) { 21 for (int i = 0, j = buttons.size(); i < j; i++) { 22 AbsHtml button = buttons.get(i); 23 if (button instanceof AbsButton) { 24 builder.append(button.getHtml()); 25 } 26 } 27 } 28 builder.append("</div>"); 29 30 return builder.toString(); 31 } 32 }
这是一个html的处理的生产类,把公共的属性的生产方法提取出来
1 package com.sun.Theme; 2 3 import java.util.Iterator; 4 import java.util.Map; 5 import java.util.Map.Entry; 6 7 import org.apache.commons.lang.StringUtils; 8 9 public class HtmlGenerator { 10 11 /** 12 * 通用的html属性生成方法 13 * 该方法会默认处理html的visible属性,如果其visible为true,将会添加样式display:none; 14 * @param builder 15 * @param html 16 * @return 17 */ 18 public static StringBuilder buildHtml(StringBuilder builder, AbsHtml html) { 19 return buildHtml(builder, html, true); 20 } 21 22 /** 23 * 通用的html属性生成方法 24 * @param builder 25 * @param html 26 * @param processVisivle 是否处理visible属性 27 * @return 28 */ 29 public static StringBuilder buildHtml(StringBuilder builder, AbsHtml html, boolean processVisivle) { 30 if (processVisivle && !html.isVisible()) { 31 html.addStyle("display", "none"); 32 } 33 if (html.isDisabled()) { 34 builder.append(" disabled=\"disabled\""); 35 html.addCls("disabled"); 36 } 37 if (!html.isDisabled() && StringUtils.isNotBlank(html.getName())) { 38 builder.append(" name=\"" + html.getName() + "\""); 39 } 40 if (StringUtils.isNotBlank(html.getId())) { 41 builder.append(" id=\"" + html.getId() + "\""); 42 } 43 if (StringUtils.isNotBlank(html.getCls())) { 44 builder.append(" class=\"" + html.getCls() + "\""); 45 } 46 if (StringUtils.isNotBlank(html.getStyle())) { 47 builder.append(" style=\"" + html.getStyle() + "\""); 48 } 49 if (StringUtils.isNotBlank(html.getTitle())) { 50 builder.append(" title=\"" + html.getTitle() + "\""); 51 } 52 53 Map<String, Object> attributes = html.getAttributes(); 54 if (attributes != null) { 55 Iterator<Entry<String, Object>> iterator = attributes.entrySet().iterator(); 56 while (iterator.hasNext()) { 57 Entry<String, Object> attribute = iterator.next(); 58 Object v = attribute.getValue(); 59 60 builder.append(" " + attribute.getKey() + "=\"" + (null == v ? "" : String.valueOf(v)) + "\""); 61 } 62 } 63 if (StringUtils.isNotBlank(html.getEvents())) { 64 builder.append(" " + html.getEvents()); 65 } 66 67 return builder; 68 } 69 70 /** 71 * 获取按钮默认class 72 * @param size 按钮大小 73 * @return 74 */ 75 public static String getButtonCls(int size) { 76 return Button.BUTTON_DEFAULT + " " + HtmlGenerator.getButtonSize(size); 77 } 78 79 /** 80 * 获取按钮大小class 81 * @param size 82 * @return 83 */ 84 public static String getButtonSize(int size) { 85 String css = null; 86 switch (size) { 87 case 5: 88 css = "btn-lg"; 89 break; 90 case 4: 91 break; 92 case 3: 93 css = "btn-sm"; 94 break; 95 case 2: 96 css = "btn-xs"; 97 break; 98 case 1: 99 css = "btn-xs"; 100 break; 101 default: 102 css = "btn-sm"; 103 break; 104 } 105 106 return null == css ? "" : css; 107 } 108 109 /** 110 * 获得按钮的包含宽度=padding+'border-left-width'+'border-right-width' 111 * @param size 尺寸 112 * @return not null 113 */ 114 public static int getButtonInnerWidth(int size) { 115 //border 116 int width = 1*2; 117 switch (size) { 118 //padding 119 case 5: 120 width += 16*2; 121 break; 122 case 4: 123 break; 124 case 3: 125 width += 10*2; 126 break; 127 case 2: 128 width += 5*2; 129 break; 130 case 1: 131 width += 5*2; 132 break; 133 default: 134 width += 10*2; 135 break; 136 } 137 return width; 138 } 139 140 /** 141 * 去除id中的 142 * <p>.</p> 143 * <p>[</p> 144 * <p>]</p> 145 * @param id 146 * @return 147 */ 148 public static String getSimpleId(String id){ 149 return id.replace(".", "_").replace("[", "").replace("]", "").replace("_", ""); 150 } 151 152 /** 153 * 将id转换成能让jquery选择器正确识别的形式 154 * @param selector 155 * @return 156 */ 157 public static String getJquerySelector(String selector){ 158 return selector.replace(".", "\\\\.").replace("[", "\\\\[").replace("]", "\\\\]"); 159 } 160 161 public static StringBuilder getStyle(AbsHtml html) { 162 StringBuilder builder = new StringBuilder(); 163 if (!html.isVisible()) { 164 builder.append("display:none;"); 165 } 166 if (StringUtils.isNotBlank(html.getWidth())) { 167 builder.append("width:").append(html.getWidth()).append(";"); 168 } 169 if (StringUtils.isNotBlank(html.getHeight())) { 170 builder.append("height:").append(html.getHeight()).append(";"); 171 } 172 173 return builder; 174 } 175 176 public static void setStyle(AbsHtml html) { 177 if (!html.isVisible()) { 178 html.addStyle("display", "none"); 179 } 180 if (StringUtils.isNotBlank(html.getWidth())) { 181 html.addStyle("width", html.getWidth()); 182 } 183 if (StringUtils.isNotBlank(html.getHeight())) { 184 html.addStyle("width", html.getHeight()); 185 } 186 } 187 }
说了那么多,这个东西要怎么使用呢,下面是一个使用按钮组(ButtonGroup)的demo,应该很容易理解,
生成的结果为<div role="group" aria-label="button group" class="btn-group"><button type="Button" id="9f9d9e9c-af10-4bcf-a5a2-d9c3b77e7439" class="btn btn-default btn-sm active" title="新增"><span class="glyphicon glyphicon-plus"></span>新增</button><button type="Button" id="d80ac4f7-2c17-426f-ae51-56453770d826" class="btn btn-default btn-sm active"><span class="glyphicon glyphicon-plus"></span></button><button type="Button" id="809faf8f-1fd5-452d-a302-7d0a19d33645" class="btn btn-default btn-sm active"><span class="glyphicon glyphicon-plus"></span></button></div>
1 package com.sun.Theme; 2 3 import java.util.UUID; 4 5 public class HtmlDemo { 6 7 public static void main(String[] args) { 8 String id1 = UUID.randomUUID().toString(); 9 String id2 = UUID.randomUUID().toString(); 10 String id3 = UUID.randomUUID().toString(); 11 Button button1 = ThemeFactory.get(AbsButton.class).setIcon("add").setActive(true).setId(id1).setTitle("新增").setInnerHTML("新增"); 12 Button button2 = ThemeFactory.get(AbsButton.class).setIcon("add").setActive(true).setId(id2); 13 Button button3 = ThemeFactory.get(AbsButton.class).setIcon("add").setActive(true).setId(id3); 14 // System.out.println(button1.getHtml()); 15 // System.out.println(button2.getHtml()); 16 // System.out.println(button3.getHtml()); 17 ButtonGroup bg = ThemeFactory.get(AbsButtonGroup.class).insertButton(0, button1).insertButton(1, button2).insertButton(2, button3); 18 System.out.println(bg.getHtml()); 19 } 20 21 }
那么具体实现呢 当然是标签最合适,这里就不列出button的实例的,和上个例子中的demo是差不多的;
如果我们要修改一个页面,那么我们需要找到这个页面的名字,页面并不会为我们显示页面的名字,下面这个示例就是方便我们查看页面路径的,道理很简单,只要我页面里面使用了<e:import resource="">,那么我就能在审查元素的时候看到文件的名字,当然,还是开发模式下能被看到的好!
1 package com.sun.Theme; 2 3 import java.io.IOException; 4 5 import javax.servlet.http.HttpServletRequest; 6 import javax.servlet.jsp.JspException; 7 import javax.servlet.jsp.JspWriter; 8 import javax.servlet.jsp.PageContext; 9 import javax.servlet.jsp.tagext.SimpleTagSupport; 10 11 public final class ImportTag extends SimpleTagSupport { 12 13 private String resource; 14 15 @Override 16 public void doTag() throws JspException, IOException { 17 HttpServletRequest request = (HttpServletRequest)((PageContext)this.getJspContext()).getRequest(); 18 19 JspWriter out = getJspContext().getOut(); 20 out.write("<!-- path : " + request.getContextPath() + request.getServletPath() + " -->\n"); 21 out.write(ThemeFactory.getTheme().getResource(resource)); 22 23 resource = null; 24 super.doTag(); 25 } 26 27 public void setResource(String resource) { 28 this.resource = resource; 29 } 30 }