Java学习之Swing Gui编程

0x00 前言

前面的使用的Gui是基于Awt 去进行实现,但是在现实写Gui中 AWT实际运用会比较少。

0x01 Swing 概述

AWT 和Swing 区别

实际使用 Java 开发图形界面程序时 ,很少使用 AWT 组件,绝大部分时候都是用 Swing 组件开发的 。 Swing是由100%纯 Java实现的,不再依赖于本地平台的 GUI, 因此可以在所有平台上都保持相同的界面外观。独立于本地平台的Swing组件被称为轻量级组件;而依赖于本地平台的 AWT 组件被称为重量级组件

由于 Swing 的所有组件完全采用 Java 实现,不再调用本地平台的 GUI,所以导致 Swing 图形界面的显示速度要比 AWT 图形界面的显示速度慢一些,但相对于快速发展的硬件设施而言,这种微小的速度差别无妨大碍。

Swing的特点

  1. Swing 组件采用 MVC(Model-View-Controller, 即模型一视图一控制器)设计模式:
模型(Model): 用于维护组件的各种状态;

视图(View): 是组件的可视化表现;

控制器(Controller):用于控制对于各种事件、组件做出响应 。

当模型发生改变时,它会通知所有依赖它的视图,视图会根据模型数据来更新自己。Swing使用UI代理来包装视图和控制器, 还有一个模型对象来维护该组件的状态。例如,按钮JButton有一个维护其状态信息的模型ButtonModel对象 。 Swing组件的模型是自动设置的,因此一般都使用JButton,而无须关心ButtonModel对象。
  1. Swing采用 MVC 模式来维护各组件,所以 当组件的外观被改变时,对组件的状态信息(由模型维护)没有任何影响 。因 此,Swing可以使用插拔式外观感觉 (Pluggable Look And Feel, PLAF)来控制组件外观,使得 Swing图形界面在同一个平台上运行时能拥有不同的外观,用户可以选择自己喜欢的外观 。相比之下,在 AWT 图形界面中,由于控制组件外观的对等类与具体平台相关 ,因此 AWT 组件总是具有与本地平台相同的外观 。

0x02 Swing代码实现

第一个Swing程序

package com.test;

import javax.swing.*;

public class test {
public static void main(String[] args) throws ClassNotFoundException, UnsupportedLookAndFeelException, InstantiationException, IllegalAccessException {
JFrame jFrame = new JFrame("nwebshell");
//设置外观风格
UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
//刷新jf容器及其内部组件的外观
SwingUtilities.updateComponentTreeUI(jFrame);
jFrame.setSize(1024,400);
jFrame.setVisible(true);
}
}

JColorChooser 和JFileChooser

Swing提供了JColorChooser和JFileChooser这两种对话框,可以很方便的完成颜色的选择和本地文件的选择。

JColorChooser

JColorChooser 用于创建颜色选择器对话框 , 该类的用法非常简单,只需要调用它的静态方法就可以快速生成一个颜色选择对话框

代码:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; public class JColorChooserDemo { JFrame jFrame = new JFrame("测试颜色选择器"); JTextArea jta = new JTextArea("我爱中华",6,30); JButton button = new JButton(new AbstractAction("改变文本框的本景色"){ @Override
public void actionPerformed(ActionEvent e) { //弹出颜色选择器
Color result = JColorChooser.showDialog(jFrame, "颜色选择器", Color.WHITE);
jta.setBackground(result);
}
}); public void init(){
jFrame.add(jta); jFrame.add(button,BorderLayout.SOUTH); jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jFrame.pack();
jFrame.setVisible(true);
} public static void main(String[] args) {
new JColorChooserDemo().init();
} }

JFileChooser

JFileChooser 的功能与AWT中的 FileDialog 基本相似,也是用于生成"打开文件"、"保存文件 "对话框。与 FileDialog 不同的是 , JFileChooser 无须依赖于本地平台的 GUI , 它由 100%纯 Java 实现 , 在所有平台 上具有完全相同的行为,并可以在所有平台上具有相同的外观风格。

JFileChooser使用步骤:

  1. 创建JFileChooser对象:
JFileChooser chooser = new JFileChooser("D:\\a");//指定默认打开的本地磁盘路径
  1. 调用JFileChooser的一系列可选方法,进行初始化
setSelectedFile(File file)/setSelectedFiles(File[] selectedFiles):设定默认选中的文件
setMultiSelectionEnabled(boolean b):设置是否允许多选,默认是单选
setFileSelectionMode(int mode):设置可以选择内容,例如文件、文件夹等,默认只能选择文件
  1. 打开文件对话框
showOpenDialog(Component parent):打开文件加载对话框,并指定父组件
showSaveDialog(Component parent):打开文件保存对话框,并指定父组件
  1. 获取用户选择的结果
File getSelectedFile():获取用户选择的一个文件
File[] getSelectedFiles():获取用户选择的多个文件

代码:

import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException; public class JFileChooserDemo { //创建窗口对象
JFrame jf = new JFrame("测试JFileChooser"); //创建打开文件对话框
JFileChooser chooser = new JFileChooser("."); //创建菜单条
JMenuBar jmb = new JMenuBar();
//创建菜单
JMenu jMenu = new JMenu("文件");
//创建菜单项
JMenuItem open = new JMenuItem(new AbstractAction("打开"){ @Override
public void actionPerformed(ActionEvent e) {
chooser.showOpenDialog(jf);
File imageFile = chooser.getSelectedFile();
try {
image = ImageIO.read(imageFile);
drawArea.repaint();
} catch (IOException e1) {
e1.printStackTrace();
}
}
}); JMenuItem save = new JMenuItem(new AbstractAction("另存为"){ @Override
public void actionPerformed(ActionEvent e) {
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
chooser.showSaveDialog(jf);
File dir = chooser.getSelectedFile();
try {
ImageIO.write(image,"jpeg",new File(dir,"a.jpg"));
} catch (Exception e1) {
e1.printStackTrace();
}
}
}); //用来记录用户选择的图片
BufferedImage image; //显示图片
class MyCanvas extends JPanel{
@Override
public void paint(Graphics g) {
if (image!=null){
g.drawImage(image,0,0,null);
}
}
} JPanel drawArea = new MyCanvas(); public void init(){
//设置图片显示区域大小
drawArea.setPreferredSize(new Dimension(500,300));
jf.add(drawArea); //组装并设置菜单条
jMenu.add(open);
jMenu.add(save);
jmb.add(jMenu);
jf.setJMenuBar(jmb); //显示jf
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
} public static void main(String[] args) {
new JFileChooserDemo().init();
} }

JOptionPane

通过 JOptionPane 可以非常方便地创建一些简单的对话框, Swing 已经为这些对话框添加了相应的组件,无须程序员手动添加组件 。 JOptionPane 提供了如下 4 个方法来创建对话框 。

方法名称 方法功能
showMessageDialog/showInternalMessageDialog 消息对话框 ,告知用户某事己发生 , 用户只能单击"确定"按钮 , 类似于 JavaScript 的 alert 函数 。
showConfirmDialog/showInternalConfirmDialog 确认对话框,向用户确认某个问题,用户可以选择 yes 、 no ~ cancel 等选项 。 类似于 JavaScript 的 comfirm 函数 。该方法返回用户单击了 哪个按钮
showInputDialog/showInternalInputDialog 输入对话框,提示要求输入某些信息,类似于 JavaScript的 prompt 函数。该方法返回用户输入的字符串 。
showOptionDialog/showInternalOptionDialog 自定义选项对话框 ,允许使用自 定义选项 ,可以取代showConfirmDialog 所产生的对话框,只是用起来更复杂 。

当用户与对话框交互结束后,不同类型对话框的返回值如下:

  • showMessageDialog: 无返回值 。
  • showlnputDialog: 返回用户输入或选择的字符串 。
  • showConfirmDialog: 返回 一个整数代表用户选择的选项 。
  • showOptionDialog : 返回 一个整数代表用户选择的选项,如果用户选择第一项,则返回 0; 如果选择第二项,则返回1……依此类推 。

对 showConfirmDialog 所产生的对话框,有如下几个返回值:

  • YES OPTION: 用户 单击了 "是"按钮后返回 。
  • NO OPTION: 用 户单击了"否"按钮后返回 。
  • CANCEL OPTION: 用户单击了"取消"按钮后返回 。
  • OK OPTION : 用户单击了"确定"按钮后返回 。
  • CLOSED OPTION: 用户 单击了对话框右上角的 " x" 按钮后返回。

四种对话框演示

消息对话框:

import cn.itcast.swing.util.ImagePathUtil;

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; public class MessageDialogTest { JFrame jf = new JFrame("测试消息对话框"); JTextArea jta = new JTextArea(6, 30); JButton btn = new JButton(new AbstractAction("弹出消息对话框") { @Override
public void actionPerformed(ActionEvent e) {
//JOptionPane.showMessageDialog(jf, jta.getText(), "消息对话框", JOptionPane.ERROR_MESSAGE);
//JOptionPane.showMessageDialog(jf, jta.getText(), "消息对话框", JOptionPane.INFORMATION_MESSAGE);
//JOptionPane.showMessageDialog(jf, jta.getText(), "消息对话框", JOptionPane.WARNING_MESSAGE);
//JOptionPane.showMessageDialog(jf, jta.getText(), "消息对话框", JOptionPane.QUESTION_MESSAGE);
//JOptionPane.showMessageDialog(jf, jta.getText(), "消息对话框", JOptionPane.PLAIN_MESSAGE);
JOptionPane.showMessageDialog(jf, jta.getText(), "消息对话框", JOptionPane.WARNING_MESSAGE, new ImageIcon(ImagePathUtil.getRealPath("2\\female.png"))); }
}); public void init(){
jf.add(jta);
jf.add(btn, BorderLayout.SOUTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
} public static void main(String[] args) {
new MessageDialogTest().init();
} }

确认对话框:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; public class ConfirmDialogTest { JFrame jf = new JFrame("测试确认对话框"); JTextArea jta = new JTextArea(6, 30); JButton btn = new JButton(new AbstractAction("弹出确认对话框") { @Override
public void actionPerformed(ActionEvent e) { int result = JOptionPane.showConfirmDialog(jf, jta.getText(), "确认对话框",JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE);
if (result == JOptionPane.YES_OPTION){
jta.append("\n用户点击了确定按钮");
} if (result==JOptionPane.NO_OPTION){
jta.append("\n用户点击了取消按钮");
} }
}); public void init(){
jf.add(jta);
jf.add(btn, BorderLayout.SOUTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
} public static void main(String[] args) {
new ConfirmDialogTest().init();
} }

输入对话框:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; public class InputDialogTest { JFrame jf = new JFrame("测试输入对话框"); JTextArea jta = new JTextArea(6, 30); JButton btn = new JButton(new AbstractAction("弹出输入对话框") { @Override
public void actionPerformed(ActionEvent e) { /* String result = JOptionPane.showInputDialog(jf, "请填写您的银行账号:", "输入对话框", JOptionPane.INFORMATION_MESSAGE);
if(result!=null){
jta.append(result.toString());
}
*/ Object result = JOptionPane.showInputDialog(jf, "", "输入对话框", JOptionPane.DEFAULT_OPTION, null, new String[]{"柳岩", "舒淇", "龚玥菲"}, "舒淇");
if (result!=null){
jta.append(result.toString());
}
}
}); public void init(){
jf.add(jta);
jf.add(btn, BorderLayout.SOUTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
} public static void main(String[] args) {
new InputDialogTest().init();
} }

选项对话框:

import javax.swing.*;
import java.awt.*;
import java.awt.event.ActionEvent; public class OptionDialogTest { JFrame jf = new JFrame("测试选项对话框"); JTextArea jta = new JTextArea(6, 30); JButton btn = new JButton(new AbstractAction("弹出选项对话框") { @Override
public void actionPerformed(ActionEvent e) { int result = JOptionPane.showOptionDialog(jf, "请选择尿不湿号码", "选项对话框",JOptionPane.DEFAULT_OPTION,JOptionPane.INFORMATION_MESSAGE,
null,new String[]{"大号","中号","小号"},"中号"); switch (result){
case 0:
jta.setText("用户选择了大号");
break;
case 1:
jta.setText("用户选择了中号");
break;
case 2:
jta.setText("用户选择了小号");
break;
}
}
}); public void init(){
jf.add(jta);
jf.add(btn, BorderLayout.SOUTH); jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.pack();
jf.setVisible(true);
} public static void main(String[] args) {
new OptionDialogTest().init();
} }

0x03 一些想法实现

其实在学习该gui框架时,我觉得主要开发工具中注重点不应该放在设计各种界面框体中,而是注重于一些界面的事件处理。至于多功能的话还需要一些对话框来实现功能分块化。所以在写nwebshell该工具的时候,是采用了netbeans ide,去实现可视化编程,自动生成gui的框体代码。然后复制到idea中进行配置事件。

基本的功能已经实现了,但是还有很多优化没做。包括双向传输加密的时候,返回的结果,其实是未作排版的。还有shell数据的存储,一键生成对应加密的jsp木马。

已实现 单向、双向aes+hex、base64加密和gui界面

0x04 结尾

前前后后这一个工具已经是写了一周左右,一边学习,一边写。期间也是会考虑到一些问题,比如冰蝎这么好用为啥不用冰蝎3,冰蝎3中其实是已经很难检测到了。为什么不基于冰蝎3去进行改造?其实当时想的是冰蝎固然很好用,虽然强特征难以检测到,但是还是会有一些弱特征会被检测,用的人也越来越多。假设后面基于3版本又做了检测呢?如果不更新的话,可能就需要对其进行一个改造,改造的话还得使用jd-gui等工具进行逆向,逆向出来的也会有比较多的错误,还得改代码,虽然说也有大佬去实现了,并且改造成加载内存马等。但是这时间成本其实就已经比较大了,所以就打算进行一个重构,就可以进行自定义一些加密模式,方便一些。但是目前来说其实只能算是一个加密传输的命令执行工具,后面的功能还想构思怎么去编写。在这方面上有更好想法的师傅们可以提出来共同交流。比如怎么更好的隐藏或什么样的加密更好?又或是某个功能怎么实现?

Java学习之Swing Gui编程的更多相关文章

  1. Java学习之AWT GUI编程

    Java学习之AWT GUI编程 0x00 前言 既然前面提到了要重写冰蝎和一些反序列化工具,当然就不能随便说说而已.在编写这些工具还是要使用图形化工具来的方便一些,所以提前把GUI的框架给学习一遍. ...

  2. java学习笔记15--多线程编程基础2

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note15.html,转载请注明源地址. 线程的生命周期 1.线程的生命周期 线程从产生到消亡 ...

  3. Java学习笔记--Swing用户界面组件

    很多与AWT类似. 事件处理参考:Java学习笔记--AWT事件处理 1.设计模式: 模型:存储内容视图:显示内容控制器:处理用户输入· 2. 文本输入常用组件 2.1 文本域: JLabel lab ...

  4. java学习笔记14--多线程编程基础1

    本文地址:http://www.cnblogs.com/archimedes/p/java-study-note14.html,转载请注明源地址. 多线程编程基础 多进程 一个独立程序的每一次运行称为 ...

  5. Java学习疑惑(8)----可视化编程, 对Java中事件驱动模型的理解

    我们编写程序就是为了方便用户使用, 我觉得UI设计的核心就是简洁, 操作过于繁琐的程序让很大一部分用户敬而远之. 即使功能强大, 但是人们更愿意使用易于操作的软件. 近年流行起来的操作手势和逐渐趋于成 ...

  6. JAVA学习中Swing概述中的JFrame学习

    package com.swing; import java.awt.Color;import java.awt.Container;import java.awt.event.WindowAdapt ...

  7. Java学习笔记:GUI基础

    一:我们使用到的java GUI的API可以分为3种类: 组件类(component class) 容器类(container class) 辅助类(helper class) 1:组件类:组件类是用 ...

  8. JAVA学习中Swing部分JDialog对话框窗体的简单学习

    package com.swing; import java.awt.Color;import java.awt.Container;import java.awt.event.ActionEvent ...

  9. Java学习笔记--Swing

    1.创建框架 AWT中Frame类用来描述顶层窗口,在Swing中,这个类的名为JFrame,它从Frame类扩展. JFrame是少数几个在Swing不用绘制在画布上的组件之一,因此,它的修饰部件( ...

随机推荐

  1. spring与struts2整合出现错误HTTP Status 500 - Unable to instantiate Action

    在进行spring和struts2整合的时候因为大意遇到了一个问题,费了半天神终于找到了问题所在,故分享出来望广大博友引以为戒!! 我们都知道在spring和struts2整合时,spring接管了a ...

  2. 初学 Python 需要安装哪些软件?

    自动配置.有效求助.协作编程.版本控制.一站式解决 Python 新手练习中的痛点. 痛点 这个学期,我在北得克萨斯大学(University of North Texas)教 INFO 5731: ...

  3. nexus私服部署

    1,下载安装包,解压,执行以下命令启动服务. nexus.exe /run 2,访问http://localhost:8081访问管理界面,添加一个maver2(proxy)的仓库,代理地址填写阿里云 ...

  4. laravel 验证码 auth方式登录 中间件判断session是否存在

    首先下载laravel的插件 composer下载  实现验证码       composer require mews/captcha 在config/app.php进行配置 'providers' ...

  5. [OGeek2019]bookmanager

    做过的代码量最大的一个题 说出的好也好,不好也不好,利用点很简单,就是一个大规模的heapoverflow,就是逆起来有点儿难度 思路很简单,就是利用堆溢出覆盖结构体中的指针为__free_hook, ...

  6. Spring源码知识概览

    目录 Spring知识总览 1.1 IOC 1.2 Spring中重要接口概览 Spring知识总览 1.1 IOC IOC是控制反转,是一种思想 DI是依赖注入,是控制翻转的一种实现 Spring的 ...

  7. 华为hcip学习备考心得

    大家好我是林中鸟,经过几个月的学习终于顺利拿下了华为的hcip:写这篇文章主要目的是想和大家分享一下我学习备考中的一些经历. 2020年由于疫情影响,社会各行各业都遭受重创,同时也打乱的我的生活规划: ...

  8. 如何在 Debian 9 上搭建 LNMP 环境

    步骤一.安装Nginx Nginx在默认的Debian存储库中可用. 使用以下命令更新软件包索引并安装Nginx: sudo apt update sudo apt install nginx 安装过 ...

  9. Day12 HTML知识

    1.html初识 超文本标记语言(Hypertext Markup Language,HTML)通过标签语言来标记要显示的网页中的各个部分.一套规则,浏览器认识的规则 浏览器按顺序渲染网页文件,然后根 ...

  10. python模块导入(包)

    模块 关注公众号"轻松学编程"了解更多. 1.1. 模块的概述 ​ 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里的代码就会越来越长,越来越不容易维护. 为了编写可维 ...