样式与布局
前一章中,我们已经完成了一个todos应用的最基础的功能,但不可否认的是,这个应用看起来太简陋了,几乎没有任何吸引力,而很明显,我们想要开发一个应用的目的就是让人来使用它,哪怕仅仅是自己使用(好惨),也喜欢有一个赏心悦目的ui吧
下面我们想要实现的效果如下:
- 一个精美,显眼的输入框,用于新建清单或者为已有清单增加待办事项
- 输入框居中,并且使用框体增加用户注意力
实现这个目标,并不是很简单的事,尤其是假定还要使用手机,平板电脑等设备来访问,所以,对于我这种懒人来说,最好的方法是使用css框架,目前css框架有很多,比如赫赫有名的Bootstrap,但毕竟Bootstrap使用的太广泛了,难免有千篇一律之嫌,所以就此考虑,使用了一个占有率稍小的前端框架:Semantic UI。
Semantic UI也可以使用Bootstrap提供的cdn来获取,在页面头部增加cdn的引用:
<link href="https://cdn.bootcss.com/semantic-ui/2.2.13/semantic.min.css" rel="stylesheet">
当然,实际项目中可不能这么干,有个好的UI设计和前段开发还是很必要的,因为即使占有率不让Bootstrap那么高,用户也立刻就能看出你使用的默认的样式,给人一种你甚至连自己定制都懒得动的感觉:(
下面使用Semantic UI的强大功能对页面进行一下修改(这里强烈建议看一下Semantic UI文档):
<div class="ui two column centered relaxed grid">
<div class="column row"></div>
<div class="column ">
<h2 class="ui huge header center violet aligned">jTodos!</h2>
<div class="ui raised segment">
<form action="index.jsp" method="post" class="ui fluid action input">
<input type="text" name="todo" placeholder="请输入一个备忘录项目">
<button type="submit" class="ui button">OK</button>
</form>
<div class="ui aligned huge selection divided list">
<c:forEach var="item" items="${todos}">
<div class="item">
<span class="header">${status.index+1}.${item}</span>
</div>
</c:forEach>
</div>
</div>
</div>
</div>
这段html中可以看出SemanticUI的特点,就是采用多种css类组合的方式,强调不同的css类的服用,这段代码最后执行的页面效果如下:
注意:此处严禁吐槽配色!!!
数据模型
对于一个todos来说,现在我假设你希望知道你这个idea的迸发时间,也就是item项发出创建的时间,这时候,就会发现单纯的使用字符串已经满足不了需求了,这时候,就轮到数据模型出场了。
一般来说,项目中会把数据模型统一管理,这里我们也来创建一个单独用于数据模型管理的包
此处不同版本的IntelliJ Idea的显示会不同
首先找到项目的main文件夹,在文件夹下创建java文件夹用来放置代码文件,但此时java文件夹为普通文件夹,需要把他修改为idea可识别的代码文件夹,修改方式如下:
修改前:
然后依次选择 file->Project Structure,
在弹出的窗体中选择java文件夹:
选择java文件夹,然后设置为Sources模式:
然后点击apply,最后点击ok,即可设置完成。
再次强调,此操作与Intellij Idea的版本有关,如果你的版本默认自带代码文件夹,则不需要此步骤。
完成准备工作,我们开始创建模型所在的包,以方便对数据模型的管理,包名一般都为域名的逆序,以保证唯一性,这里包名为:
com.niufennan.jtodos.models
然后创建一个数据类,暂时命名Todo,只做简单的演示,这里类中只有三个字段以及相应的封装,这个类的源代码如下:
package com.niufennan.jtodos.models;
import java.util.Date;
public class Todo {
private int id;
private String item;
private Date createTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getItem() {
return item;
}
public void setItem(String item) {
this.item = item;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
}
这样,每次新增的就不再是一个字符串项,而是一个Todo的数据模型,也就是所谓的一个javabean了。
修改代码如下:
<%
request.setCharacterEncoding("utf-8");
List<Todo> todos=(List<Todo>) application.getAttribute("todos");
if(todos==null){
todos=new ArrayList<>();
application.setAttribute("todos",todos);
}
if(request.getParameter("todo")!=null){
Todo todo=new Todo();
todo.setCreateTime(new Date());
todo.setItem(request.getParameter("todo"));
todos.add(todo);
}
%>
html模板部分修改为:
<c:forEach var="todo" varStatus="status" items="${todos}">
<div class="item">
<span class="header">${status.index+1}.${todo.item}</span>
</div>
</c:forEach>
运行,效果入下:
与之前一模一样。
注意,这种随便改变数据类型的方法,为开发中大大忌,在实际开发中是严禁禁止的行为,但这篇blog为了照顾各个知识点,所以并未从开始进行整体架构设计,以后这种修改数据类型的行为会经常发生。
在此强调一遍,此为开发中的大忌,要严格禁止。
但是,你可能发现了,并没有出现这个todo项创建的时间呀,下面我们把创建时间写入数据模板,修改的代码如下:
<c:forEach var="todo" varStatus="status" items="${todos}">
<div class="item">
<span class="right floated content">${todo.createTime}</span>
<span class="left floated header">${status.index+1}.${todo.item}</span>
</div>
</c:forEach>
显示效果为:
效果很明显,显示上符合了要求,但是,日期的格式很明显是错误的呀,这时候要对日期格式进行修改,就牵扯到在jsp中书写java方法,jsp中写java方法也很简单,写在代码框<%! code %>中即可,注意前边的!,实际代码如下:
<%!
private String formatDate(Date date){
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String dateString = formatter.format(date);
return dateString;
}
%>
页面调用的方式如下:
<%
for (int i=0;i<todos.size();i++) {
%>
<div class="item">
<span class="right floated content"><%= formatDate(todos.get(i).getCreateTime())%></span>
<span class="left floated header"><%=i+1%>.<%=todos.get(i).getItem() %></span>
</div>
<%
}
%>
执行结果如下:
但是,你可能注意到了,我们又回到了html中嵌入代码的老路,这是因为jstl和java代码的调用问题,难道就不能不适用这种嵌入的方法么,答案是当然可以,jstl也提供了日期格式化的方式,首先在页面顶部引入前缀:
<%@ taglib prefix="fmt" uri="http://java.sun.com/jsp/jstl/fmt"%>
然后jstl下模板的写法:
<c:forEach var="todo" varStatus="status" items="${todos}">
<div class="item">
<span class="right floated content"><fmt:formatDate value="${todo.createTime}" type="date" pattern="yyyy-MM-dd HH:mm:ss"/></span>
<span class="left floated header">${status.index+1}.${todo.item}</span>
</div>
</c:forEach>
注意pattern参数.
运行一下,显示的结果应该是与之前没有任何差别.
然后,就可以开开心心的把原来的格式化方法删除了.
本章的也将告于段落,从下一章开始,就会进入servlet和模块化的javabean的世界,难度应该会增加不少,不管怎么说,感谢您的阅读.
注意:本章第三次提醒!!!
Blog仅仅是为了介绍知识点,在实际项目中严禁使用这里使用的一些编码方式,对于由此产生的任何后果,本blog概不负责!!!
感谢您的阅读