gui点击按钮显示信息_Web开发基础-06-GUI入门

本文介绍了GUI编程的关键元素:组件、布局和事件,详细讲解了MVC模式在Swing中的应用。此外,还探讨了Web GUI中的事件处理,以及Vue框架中的MVVM模式和虚拟DOM的概念,包括为什么使用虚拟DOM、diff算法和patch过程。
摘要由CSDN通过智能技术生成

GUI入门

GUI Key elments

任何GUI(Graphical User Interface)都有三个关键元素:组件、布局和事件。

Component

组件是整个GUI的基础。常见组件有Label、TextField、Button等。

e8b8fe5c4344cff3f07761bab2cee30c.gif

Layout

有了组件之后,下面要考虑的就是组件的布局。组件之间是Composite模式,可以转化为一个树状结构。

78234283dca31c632ca6163411e337e6.gif

Event

最后,每个组件都要有事件响应的处理。比如,按按钮,获得焦点,被选择等。

|Act that Results in an Event | Listener Type |

| ----|----|

|User clicks a button, presses Return while typing in a text field, or chooses a menu item | ActionListener|

|User closes a frame (main window)| WindowListener| |User presses a mouse button while the cursor is over a component |MouseListener|

|User moves the mouse over a component | MouseMotionListener|

|Component becomes visible |ComponentListener|

|Comoponent gets the keyboard focus |FocusListener|

|Table or list selection changes |ListSelectionListener|

MVC Style

14eb99213bbc0e0010c21a01560589be.png

View和Model之间是Observer模式。View要先向感兴趣的Model进行注册、Model改变之后通知View,View来Model取数据。View和Controller之间是事件机制。一次View的交互,对应一个响应的Controller。Controller负责修改Model,和选择View的显示。

MVC in Swing

Model

ButtonModel接口的属性 - ActionCommand - Mnemonic - Armed - Enabled - Pressed - Rollover - Selected

同样的模型DefaultButtonModel可以用于不同视图 + 下压按钮 + 单选按钮 + 复选框 + 菜单项

View

JButton

  • 继承JComponent
  • 包含DefaultButtonModel、一些视图数据(标签和图标)、一个负责按钮视图的BasicButtonUI对象

Controller

public class ButtonUIListener
   implements MouseListener, MouseMotionListener,
              ChangeListener
{
   public void mouseMoved(MouseEvent mouseevent)
   public void mouseDragged(MouseEvent mouseevent)
   public void mouseClicked(MouseEvent mouseevent)
   public void mouseEntered(MouseEvent mouseevent)
   public void mouseExited(MouseEvent mouseevent)
   public void mousePressed(MouseEvent mouseevent)
   public void mouseReleased(MouseEvent mouseevent)
   public void stateChanged(ChangeEvent changeevent)
}

Controller修改Model状态

public void mousePressed(MouseEvent mouseevent)
   {
      Button button = (Button)mouseevent.getSource();

      ButtonModel buttonmodel = button.getModel();

      buttonmodel.setPressed(true);

      buttonmodel.setArmed(true);
   }

状态改变后,异步事件响应,View拿Model数据,重画。

public void stateChanged(ChangeEvent changeevent)
   {
      Button button = (Button)changeevent.getSource();

      button.repaint();
   }

MVC in Web GUI

HTML表达了基础组件,生成DOM树,CSS表达样式生成CSS树。从而可以通过layout生成出渲染树。Javascipt代表触发事件机制之后的处理。Javascipt脚本去操作Dom、更改CSS样式时,浏览器又要重新构建DOM、CSSOM树,重新render,重新layout、paint;

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
</head>
<body>

<h1>JavaScript 验证输入</h1>

<p>请输入 1 到 10 之间的数字:</p>

<input id="numb">

<button type="button" onclick="myFunction()">提交</button>

<p id="demo"></p>

<script>
function myFunction() {
    var x, text;

    // 获取 id="numb" 的值
    x = document.getElementById("numb").value;

    // 如果输入的值 x 不是数字或者小于 1 或者大于 10,则提示错误 Not a Number or less than one or greater than 10
    if (isNaN(x) || x < 1 || x > 10) {
        text = "输入错误";
    } else {
        text = "输入正确";
    }
    document.getElementById("demo").innerHTML = text;
}
</script>

</body>
</html>

3d4e5eb27f4ecdf482ca3206caa3e5d4.png

MVC vs MVP vs MVVM

4e8b4c4b8b538a74ff46bb8b10997fe9.png

MVVM in Vue

counter数据和View中的点击次数进行双向绑定。

事件响应每次按按钮,counter数据+1。View中的点击次数也随之改变。

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Vue 测试实例 - 菜鸟教程(runoob.com)</title>
<script src="https://cdn.staticfile.org/vue/2.2.2/vue.min.js"></script>
</head>
<body>
<div id="app">
  <button v-on:click="counter += 1">增加 1</button>
  <p>这个按钮被点击了 {{ counter }} 次。</p>
</div>

<script>
new Vue({
  el: '#app',
  data: {
    counter: 0
  }
})
</script>
</body>
</html>

8c0d85b7e556d47922eeba74b96bc2b9.png

ViewModel有时候会异步请求Model的数据。当服务器回答后,再根据response数据设置ViewModel,从而达到View的改变。

<div id="app">
  <h1>网站列表</h1>
  <div
    v-for="site in info"
  >
    {{ site.name }}
  </div>
</div>
<script type = "text/javascript">
new Vue({
  el: '#app',
  data () {
    return {
      info: null
    }
  },
  mounted () {
    axios
      .get('https://www.runoob.com/try/ajax/json_demo.json')
      .then(response => (this.info = response.data.sites))
      .catch(function (error) { // 请求失败处理
        console.log(error);
      });
  }
})
</script>

7ba869b9b18fcfd996fb372fe09b364f.png

MVVM可以和函数式编程范式下的函数响应式编程FRP相结合,生成复杂的数据处理。

cbe7e27d2a9e8a2d69398371cca17a00.png

Virtual Dom

From Template to Dom in Vue

Virtual DOM 其实就是一棵以 JavaScript 对象( VNode 节点)作为基础的树,用对象属性来描述节点,实际上它只是一层对真实 DOM 的抽象。最终可以通过一系列操作使这棵树映射到真实环境上。

简单来说,可以把Virtual DOM 理解为一个简单的JS对象,并且最少包含标签名( tag)、属性(attrs)和子元素对象( children)三个属性。不同的框架对这三个属性的命名会有点差别。

对于虚拟DOM,咱们来看一个简单的实例,就是下图所示的这个,详细的阐述了模板 → 渲染函数 → 虚拟DOM树 → 真实DOM的一个过程。

c373d013f5a812e192f080a9f1d3aacd.png

为什么要虚拟Dom?

虚拟DOM的最终目标是将虚拟节点渲染到视图上。但是如果直接使用虚拟节点覆盖旧节点的话,会有很多不必要的DOM操作。例如,一个ul标签下很多个li标签,其中只有一个li有变化,这种情况下如果使用新的ul去替代旧的ul,因为这些不必要的DOM操作而造成了性能上的浪费。

为了避免不必要的DOM操作,虚拟DOM在虚拟节点映射到视图的过程中,将虚拟节点与上一次渲染视图所使用的旧虚拟节点(oldVnode)做对比,找出真正需要更新的节点来进行DOM操作,从而避免操作其他无需改动的DOM。

其实虚拟DOM在Vue.js主要做了两件事:

  • 提供与真实DOM节点所对应的虚拟节点vnode
  • 将虚拟节点vnode和旧虚拟节点oldVnode进行对比,然后更新视图

diff

Vue的diff算法是基于snabbdom改造过来的,仅在同级的vnode间做diff,递归地进行同级vnode的diff,最终实现整个DOM树的更新。因为跨层级的操作是非常少的,忽略不计,这样时间复杂度就从O(n3)变成O(n)。

diff 算法包括几个步骤:

  • 用 JavaScript 对象结构表示 DOM 树的结构;然后用这个树构建一个真正的 DOM 树,插到文档当中
  • 当状态变更的时候,重新构造一棵新的对象树。然后用新的树和旧的树进行比较,记录两棵树差异
  • 把所记录的差异应用到所构建的真正的DOM树上,视图就更新了

05b4fc8e2f3cfa253a64c47514959af7.png

patch

核心函数实现流程:

  • patch(container,vnode) :初次渲染的时候,将Virtual Dom渲染成真正的DOM然后插入到容器里面。
  • patch(vnode,newVnode):再次渲染的时候,将新的vnode和旧的vnode相对比,然后之间差异应用到所构建的真正的DOM树上。

440638b7d9a61e7f9753f62854b240ff.png

Reference:

https://www.cs.utexas.edu/users/dsb/SwingTutorial/1_Basics/lecture.html

https://www.runoob.com/vue2/vuejs-ajax-axios.html

https://www.runoob.com/try/try.php?filename=tryjs_validation_number

https://segmentfault.com/a/1190000014070240

https://zhuanlan.zhihu.com/p/38108311

https://juejin.im/post/5d12c931f265da1bb2773fcc

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值