clojure GUI编程-2

*/-->

pre.src {background-color: #292b2e; color: #b2b2b2;}

pre.src {background-color: #292b2e; color: #b2b2b2;}

pre.src {background-color: #292b2e; color: #b2b2b2;}

pre.src {background-color: #292b2e; color: #b2b2b2;}

clojure GUI编程-2

目录

  • 1. 简介
  • 2. 实现过程
    • 2.1. 添加依赖
    • 2.2. 复制文件
    • 2.3. 设计gui界面
    • 2.4. clojure中加载java gui代码
  • 3. 总结

1 简介

接上一篇GUI开发,每次手写GUI布局代码比较不方便,可以使用netbeans的form designer设计好界面,然后从clojure中加载界面,绑定事件来进行GUI设计。

2 实现过程

由于要编译java代码,使用leiningen进行项目管理比较方便。先创建一个空项目, lein new okex 创建项目。

2.1 添加依赖

修改项目文件夹下的project.clj如下

 1: (defproject okex "0.1.0-SNAPSHOT"
 2:   :description "FIXME: write description"
 3:   :url "http://example.com/FIXME"
 4:   :license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
 5:             :url "https://www.eclipse.org/legal/epl-2.0/"}
 6:
 7:   ;; 使用utf-8编码编译java代码,默认会使用windows系统的默认编码gbk
 8:   :javac-options ["-encoding" "utf-8"]
 9:   :java-source-paths ["src"]
10:
11:   :dependencies [[org.clojure/clojure "1.10.0"]
12:                  [com.cemerick/url "0.1.1"] ;; uri处理
13:                  [slingshot "0.12.2"] ;; try+ catch+
14:                  [com.taoensso/timbre "4.10.0"] ;; logging
15:                  [cheshire/cheshire "5.8.1"] ;; json处理
16:                  [clj-http "3.9.1"] ;; http client
17:                  [com.rpl/specter "1.1.2"] ;; map数据结构查询
18:                  [camel-snake-kebab/camel-snake-kebab "0.4.0"] ;; 命名转换
19:                  [seesaw "1.5.0"] ;; GUI框架
20:                  ]
21:   :main ^:skip-aot okex.core
22:   :aot :all
23:   :target-path "target/%s"
24:   :repl-options {:init-ns okex.core})

2.2 复制文件

把上一篇创建的core2.clj和api.clj复制到src/okex文件夹下,改名core2.clj为core.clj。
并修改命名空间与文件名对应。

2.3 设计gui界面

使用netbeans新建JFrame form,并设计窗体,修改要用到的widget的name属性为对应的swing id名,然后保存这个文件到src/okex文件夹下,注意包名要用okex,文件内容如下:

  1: /*
  2:  * To change this license header, choose License Headers in Project Properties.
  3:  * To change this template file, choose Tools | Templates
  4:  * and open the template in the editor.
  5:  */
  6: package okex;
  7: /**
  8:  *
  9:  */
 10: public class DepthWindow extends javax.swing.JFrame {
 11:
 12:     /**
 13:      * Creates new form DepthWindow
 14:      */
 15:     public DepthWindow() {
 16:         initComponents();
 17:     }
 18:
 19:     /**
 20:      * This method is called from within the constructor to initialize the form.
 21:      * WARNING: Do NOT modify this code. The content of this method is always
 22:      * regenerated by the Form Editor.
 23:      */
 24:     @SuppressWarnings("unchecked")
 25:     // <editor-fold defaultstate="collapsed" desc="Generated Code">//GEN-BEGIN:initComponents
 26:     private void initComponents() {
 27:
 28:         jPanel1 = new javax.swing.JPanel();
 29:         jPanel2 = new javax.swing.JPanel();
 30:         jLabel1 = new javax.swing.JLabel();
 31:         jComboBox1 = new javax.swing.JComboBox<>();
 32:         jLabel2 = new javax.swing.JLabel();
 33:         jComboBox2 = new javax.swing.JComboBox<>();
 34:         jScrollPane1 = new javax.swing.JScrollPane();
 35:         jTable1 = new javax.swing.JTable();
 36:         jScrollPane2 = new javax.swing.JScrollPane();
 37:         jTable2 = new javax.swing.JTable();
 38:         jLabel3 = new javax.swing.JLabel();
 39:         jLabel4 = new javax.swing.JLabel();
 40:
 41:         setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
 42:         setTitle("okex 行情信息");
 43:
 44:         jPanel1.setLayout(new java.awt.BorderLayout(3, 3));
 45:
 46:         jLabel1.setText("基准币种:");
 47:
 48:         jComboBox1.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
 49:         jComboBox1.setName("base-coin"); // NOI18N
 50:
 51:         jLabel2.setText("计价币种:");
 52:
 53:         jComboBox2.setModel(new javax.swing.DefaultComboBoxModel<>(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
 54:         jComboBox2.setToolTipText("");
 55:         jComboBox2.setName("quote-coin"); // NOI18N
 56:
 57:         jTable1.setModel(new javax.swing.table.DefaultTableModel(
 58:             new Object [][] {
 59:                 {null, null, null, null},
 60:                 {null, null, null, null},
 61:                 {null, null, null, null},
 62:                 {null, null, null, null}
 63:             },
 64:             new String [] {
 65:                 "Title 1", "Title 2", "Title 3", "Title 4"
 66:             }
 67:         ));
 68:         jTable1.setName("bids-table"); // NOI18N
 69:         jScrollPane1.setViewportView(jTable1);
 70:
 71:         jTable2.setModel(new javax.swing.table.DefaultTableModel(
 72:             new Object [][] {
 73:                 {null, null, null, null},
 74:                 {null, null, null, null},
 75:                 {null, null, null, null},
 76:                 {null, null, null, null}
 77:             },
 78:             new String [] {
 79:                 "Title 1", "Title 2", "Title 3", "Title 4"
 80:             }
 81:         ));
 82:         jTable2.setName("asks-table"); // NOI18N
 83:         jScrollPane2.setViewportView(jTable2);
 84:
 85:         jLabel3.setFont(new java.awt.Font("sansserif", 1, 12)); // NOI18N
 86:         jLabel3.setText("买入信息");
 87:
 88:         jLabel4.setFont(new java.awt.Font("sansserif", 1, 12)); // NOI18N
 89:         jLabel4.setText("卖出信息");
 90:
 91:         javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2);
 92:         jPanel2.setLayout(jPanel2Layout);
 93:         jPanel2Layout.setHorizontalGroup(
 94:             jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
 95:             .addGroup(jPanel2Layout.createSequentialGroup()
 96:                 .addContainerGap()
 97:                 .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
 98:                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
 99:                 .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE)
100:                 .addContainerGap())
101:             .addGroup(jPanel2Layout.createSequentialGroup()
102:                 .addGap(18, 18, 18)
103:                 .addComponent(jLabel1)
104:                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
105:                 .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, 171, javax.swing.GroupLayout.PREFERRED_SIZE)
106:                 .addGap(125, 125, 125)
107:                 .addComponent(jLabel2, javax.swing.GroupLayout.PREFERRED_SIZE, 69, javax.swing.GroupLayout.PREFERRED_SIZE)
108:                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
109:                 .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, 141, javax.swing.GroupLayout.PREFERRED_SIZE)
110:                 .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
111:             .addGroup(jPanel2Layout.createSequentialGroup()
112:                 .addGap(151, 151, 151)
113:                 .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 113, javax.swing.GroupLayout.PREFERRED_SIZE)
114:                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
115:                 .addComponent(jLabel4, javax.swing.GroupLayout.PREFERRED_SIZE, 83, javax.swing.GroupLayout.PREFERRED_SIZE)
116:                 .addGap(202, 202, 202))
117:         );
118:
119:         jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jLabel1, jLabel2});
120:
121:         jPanel2Layout.linkSize(javax.swing.SwingConstants.HORIZONTAL, new java.awt.Component[] {jComboBox1, jComboBox2});
122:
123:         jPanel2Layout.setVerticalGroup(
124:             jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
125:             .addGroup(jPanel2Layout.createSequentialGroup()
126:                 .addContainerGap()
127:                 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
128:                     .addComponent(jLabel1)
129:                     .addComponent(jComboBox1, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
130:                     .addComponent(jLabel2)
131:                     .addComponent(jComboBox2, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
132:                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
133:                 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
134:                     .addComponent(jLabel3, javax.swing.GroupLayout.PREFERRED_SIZE, 20, javax.swing.GroupLayout.PREFERRED_SIZE)
135:                     .addComponent(jLabel4, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE))
136:                 .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.UNRELATED)
137:                 .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
138:                     .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 284, Short.MAX_VALUE)
139:                     .addComponent(jScrollPane2, javax.swing.GroupLayout.PREFERRED_SIZE, 0, Short.MAX_VALUE))
140:                 .addContainerGap())
141:         );
142:
143:         jComboBox1.getAccessibleContext().setAccessibleName("");
144:
145:         jPanel1.add(jPanel2, java.awt.BorderLayout.CENTER);
146:
147:         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
148:         getContentPane().setLayout(layout);
149:         layout.setHorizontalGroup(
150:             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
151:             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
152:                 .addContainerGap()
153:                 .addComponent(jPanel1, javax.swing.GroupLayout.PREFERRED_SIZE, 468, Short.MAX_VALUE)
154:                 .addContainerGap())
155:         );
156:         layout.setVerticalGroup(
157:             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
158:             .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
159:                 .addContainerGap()
160:                 .addComponent(jPanel1, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
161:                 .addContainerGap())
162:         );
163:
164:         pack();
165:     }// </editor-fold>//GEN-END:initComponents
166:
167:     /**
168:      * @param args the command line arguments
169:      */
170:     public static void main(String args[]) {
171:         /* Set the Nimbus look and feel */
172:         //<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
173:         /* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
174:          * For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html
175:          */
176:         try {
177:             for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
178:                 if ("Nimbus".equals(info.getName())) {
179:                     javax.swing.UIManager.setLookAndFeel(info.getClassName());
180:                     break;
181:                 }
182:             }
183:         } catch (ClassNotFoundException ex) {
184:             java.util.logging.Logger.getLogger(DepthWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
185:         } catch (InstantiationException ex) {
186:             java.util.logging.Logger.getLogger(DepthWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
187:         } catch (IllegalAccessException ex) {
188:             java.util.logging.Logger.getLogger(DepthWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
189:         } catch (javax.swing.UnsupportedLookAndFeelException ex) {
190:             java.util.logging.Logger.getLogger(DepthWindow.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
191:         }
192:         //</editor-fold>
193:
194:         /* Create and display the form */
195:         java.awt.EventQueue.invokeLater(new Runnable() {
196:             public void run() {
197:                 new DepthWindow().setVisible(true);
198:             }
199:         });
200:     }
201:
202:     // Variables declaration - do not modify//GEN-BEGIN:variables
203:     private javax.swing.JComboBox<String> jComboBox1;
204:     private javax.swing.JComboBox<String> jComboBox2;
205:     private javax.swing.JLabel jLabel1;
206:     private javax.swing.JLabel jLabel2;
207:     private javax.swing.JLabel jLabel3;
208:     private javax.swing.JLabel jLabel4;
209:     private javax.swing.JPanel jPanel1;
210:     private javax.swing.JPanel jPanel2;
211:     private javax.swing.JScrollPane jScrollPane1;
212:     private javax.swing.JScrollPane jScrollPane2;
213:     private javax.swing.JTable jTable1;
214:     private javax.swing.JTable jTable2;
215:     // End of variables declaration//GEN-END:variables
216: }

2.4 clojure中加载java gui代码

修改core.clj,导入gui界面的类,并加载,代码如下:

  1: (ns okex.core
  2:   (:require [seesaw.core :as gui]
  3:             [seesaw.table :as table]
  4:             [seesaw.bind :as bind]
  5:             [seesaw.selector :as selector]
  6:             [seesaw.table :refer [table-model]]
  7:             [okex.api :as api]
  8:             [taoensso.timbre :as log])
  9:   (:use com.rpl.specter)
 10:   (:gen-class)
 11:   (:import okex.DepthWindow))
 12:
 13:
 14: ;;;;;;;;;;;;;;;;;;;;; Window-Builder binding
 15:
 16: (defn identify
 17:   "设置root下所有控件的seesaw :id
 18:   只要有name属性的,全部绑定到id"
 19:   [root]
 20:   (doseq [w (gui/select root [:*])]
 21:     (if-let [n (.getName w)]
 22:       (selector/id-of! w (keyword n))))
 23:   root)
 24:
 25: ;;;;;;;;;;;;;;;;;;;;;; 初始化值
 26:
 27: (def coin-pairs "所有交易对信息" (api/get-instruments))
 28: (def base-coins "所有基准货币"
 29:   (-> (select [ALL :base-currency] coin-pairs)
 30:       set
 31:       sort))
 32:
 33: (defn get-quote-coins
 34:   "获取基准货币支持的计价货币"
 35:   [base-coin]
 36:   (select [ALL #(= (:base-currency %) base-coin) :quote-currency] coin-pairs))
 37:
 38: (defn get-instrument-id
 39:   "根据基准货币和计价货币获得币对名称"
 40:   [base-coin quote-coin]
 41:   (select-one [ALL
 42:                #(and (= (:base-currency %) base-coin)
 43:                      (= (:quote-currency %) quote-coin))
 44:                :instrument-id]
 45:               coin-pairs))
 46:
 47: ;; 设置form的默认值
 48: (let [first-base (first base-coins)]
 49:   (def coin-pair-data (atom {:base-coin first-base
 50:                              :quote-coin (-> (get-quote-coins first-base)
 51:                                              first)})))
 52:
 53: ;;;;;;;;;;;;;;;;;;;;;; 服务
 54: (def instruments-info "交易对的深度数据"(atom {}))
 55:
 56: (defn run-get-instrument-services!
 57:   "启动获取交易对深度信息的服务
 58:   没有提供停止功能"
 59:   [instrument-id]
 60:   (when (and instrument-id
 61:              (not (contains? @instruments-info instrument-id)))
 62:     (future (loop []
 63:               (let [data (api/get-spot-instrument-book instrument-id)]
 64:                 (setval [ATOM instrument-id] data instruments-info))
 65:               (Thread/sleep 200)
 66:               (recur)))))
 67:
 68: ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; 辅助函数
 69:
 70: (defn depth-data-model
 71:   "深度数据table模型"
 72:   [data]
 73:   (table-model :columns [{:key :pos :text "价位"}
 74:                          {:key :price :text "价格"}
 75:                          {:key :amount :text "数量"}
 76:                          {:key :order-count :text "订单数"}]
 77:                :rows data))
 78:
 79: (defn update-quote-coin-model!
 80:   "更新计价货币的模型"
 81:   [f model]
 82:   (let [quote-coin (gui/select f [:#quote-coin])]
 83:     (gui/config! quote-coin :model model)))
 84:
 85: (defn get-current-instrument-id
 86:   "获取当前币对的id"
 87:   []
 88:   (let [coin-p @coin-pair-data]
 89:     (get-instrument-id (:base-coin coin-p)
 90:                        (:quote-coin coin-p))))
 91:
 92: (defn bind-transfrom-set-model
 93:   [trans-fn frame id]
 94:   (bind/bind
 95:    (bind/transform #(trans-fn %))
 96:    (bind/property (gui/select frame [id]) :model)))
 97:
 98: (defn add-behaviors
 99:   "添加事件处理"
100:   [root]
101:   (let [base-coin (gui/select root [:#base-coin])
102:         quote-coin (gui/select root [:#quote-coin])]
103:     ;; 基准货币选择事件绑定
104:     (bind/bind
105:      (bind/selection base-coin)
106:      (bind/transform get-quote-coins)
107:      (bind/tee
108:       ;; 设置quote-coin的选择项
109:       (bind/property quote-coin :model)
110:       (bind/bind
111:        (bind/transform first)
112:        (bind/selection quote-coin))))
113:
114:     ;; 绑定基准货币和计价货币的选择事件
115:     (bind/bind
116:      (bind/funnel
117:       (bind/selection base-coin)
118:       (bind/selection quote-coin))
119:      (bind/transform (fn [[base-coin quote-coin]]
120:                        {:base-coin base-coin
121:                         :quote-coin quote-coin}))
122:      coin-pair-data)
123:
124:     ;; 绑定交易对深度信息, 一旦更改就更新depth-view
125:     (bind/bind
126:      instruments-info
127:      (bind/transform #(% (get-current-instrument-id)))
128:      (bind/notify-later)
129:      (bind/tee
130:       (bind-transfrom-set-model #(-> (:bids %)
131:                                      depth-data-model) root :#bids-table)
132:       (bind-transfrom-set-model #(-> (:asks %)
133:                                      depth-data-model) root :#asks-table)))
134:
135:     ;; 当前选择的交易对修改就启动新的深度信息服务
136:     (add-watch coin-pair-data :depth-view (fn [k _ _ new-data]
137:                                             (-> (get-current-instrument-id)
138:                                                 run-get-instrument-services!)))))
139:
140: ;;;;;;;;;;;;;;;;;; 以下为新加的gui加载代码
141:
142: (defn my-form
143:   "加载form"
144:   []
145:   (let [form (identify (DepthWindow.))]
146:
147:     ;; 更新quote-coin的model
148:     (gui/config! (gui/select form [:#base-coin]) :model base-coins)
149:     (update-quote-coin-model! form (-> (:base-coin @coin-pair-data)
150:                                         get-quote-coins))
151:
152:     ;; 先绑定事件,再设置默认值
153:     (add-behaviors form)
154:     (gui/value! form @coin-pair-data)
155:
156:     form))
157:
158: (defn -main [& args]
159:   (gui/invoke-later
160:    (let [form (my-form)]
161:      (-> form gui/pack! gui/show!))))

clojure从java加载代码还是非常简单的,这里多了一个绑定控件的name到swing id的动作。

3 总结

使用netbeans设计GUI,然后从clojure中加载界面代码还是非常方便的。主要是从clojure中调用java非常方便,参考Clojure is a better Java than Java

作者: ntestoc

Created: 2019-05-29 周三 22:01

原文地址:https://www.cnblogs.com/ntestoc/p/10946524.html

时间: 2024-10-12 11:40:19

clojure GUI编程-2的相关文章

第14篇-JAVA GUI编程

第14篇-JAVA GUI编程 每篇一句 :道路一开始开辟的时候总是存在障碍的 初学心得: 原本下定决心才能开始的事情也变得理所当然 (笔者:JEEP/711)[JAVA笔记 | 时间:2017-04-25| JAVA GUI编程 ] 1.什么是界面 图形用户界面(Graphical User Interface,简称 GUI,又称图形用户接口)是指采用图形方式显示的计算机操作用户界面 与早期计算机使用的命令行界面相比,图形界面对于用户来说在视觉上更易于接受 2.Java 基础类 JFC 的基本

Python_017 GUI编程

GUI编程(Tkinter) python提供了多个图形开发界面的库,几个常用Python GUI库如下: Tkinter: Tkinter模块("Tk 接口")是Python的标准Tk GUI工具包的接口.Tk和Tkinter可以在大多数的Unix平台下使用,同样可以应用在Windows和Macintosh系统里.,Tk8.0的后续版本可以实现本地窗口风格,并良好地运行在绝大多数平台中. wxPython:wxPython 是一款开源软件,是 Python 语言的一套优秀的 GUI

Java之GUI编程(二)——布局管理器

在上篇博客Java之GUI编程(一)中我已经对GUI编程的组件和事件做了简单介绍了,现在来看看另外一部分关于组件在各个平台是如何做到仍能保持自己合理的位置大小以及外观的. 已经说了Java是跨平台运行的,但是不同的平台对于点及坐标的定义不完全相同.而且屏幕的解析度分辨率不同也会造成位置的变化,为了确保每个组件的相对位置和大小以及外观,java就设计了布局管理器. 布局管理器是对容器中的元素进行管理,按照一定的规则排放容器里面的元素.它控制了组件的摆放. 布局管理器分类: FlowLayout:浮

MATLAB串口操作和GUI编程

简单的MATLAB GUI编程和串口控制.Word编辑,如需PDF版本,请留言.说实话这个挺难看的……     概述 本文介绍了程序AD9512_Serial_GUI的编程思路和功能.该程序设计到MATLAB的图像用户界面编程的基本方法和串口的基本操作.程序目的在于通过串口写控制字对AD9512进行配置(AD9512通过SPI写入寄存器,本程序只是整个控制程序中的一部分). 修订历史 以下表格展示了本文档的修订过程 日期 版本号 修订内容 2015/01/15 V0.0 初始版本,试验版[1]

Java之GUI编程

可采用的库为AWT,即abstract windowtoolkit 当前第二代GUI开发库为Swing,具有更加完善的控件支持. Component与Container是AWT中最重要的两个类,其中Component是所有控件类的父类,而Container是Window.Frame.Panel等容器类的父类. 布局坐标系,水平方向为x轴,竖直方向为y轴. 布局管理器,当需要绘制控件时,由该管理器提供坐标. Java中共有5种:FlowLayout.GridLayout.BorderLayout.

10.JAVA之GUI编程弹出对话框Dialog

在上节基础上添加对话框显示错误信息. 代码如下: /*弹出对话框显示错误信息,对话框一般不单独出现,一般依赖于窗体.*/ /*练习-列出指定目录内容*/ import java.awt.Button; import java.awt.Dialog; import java.awt.FlowLayout; import java.awt.Frame; import java.awt.Label; import java.awt.TextArea; import java.awt.TextField

4.JAVA之GUI编程事件监听机制

事件监听机制的特点: 1.事件源 2.事件 3.监听器 4.事件处理 事件源:就是awt包或者swing包中的那些图形用户界面组件.(如:按钮) 事件:每一个事件源都有自己特点有的对应事件和共性事件.(如:鼠标单击事件) 监听器:将可以触发某一事件的动作(不止一个动作)都已经封装到了监听器中. 以上三者,在java中都已经定义好了,直接获取其对象来用就可以了. 我们要做的事情是,就是对产生的动作进行处理. 图解事件监听机制: 4.JAVA之GUI编程事件监听机制,布布扣,bubuko.com

3.JAVA之GUI编程Frame窗口

Frame 是带有标题和边框的顶层窗口. 创建图形化界面思路: 1.创建frame窗体: 2.对窗体进行基本设置: 比如大小.位置.布局 3.定义组件: 4.将组件通过add方法添加到窗体中: 5.让窗体显示,通过setVisible(ture). ****************************** 新建一个class类,名称为:studyframe 功能实现如下几点: 1.建立一个窗口: 2.窗口有标题: 3.窗口大小设置: 4.窗口位置设置: 5.窗口可见. 代码如下: impor

python 打开文件对话框 filedialog tkinter GUI 编程

- -读取文件的gui编程 1 # _*_ coding:utf-8 _*_ 2 3 import tkinter 4 from tkinter import filedialog 5 6 def openfiles2(): 7 s2fname = filedialog.askopenfilename(title='打开S2文件', filetypes=[('S2out', '*.out'), ('All Files', '*')]) 8 print(s2fname) 9 def openfil