《Java数字图像处理:编程技巧与应用实践》——3.5 一个完整的Swing UI Demo

简介:

本节书摘来自华章计算机《Java数字图像处理:编程技巧与应用实践》一书中的第3章,第3.5节,作者 贾志刚,更多章节内容可以访问云栖社区“华章计算机”公众号查看。

3.5 一个完整的Swing UI Demo

本节将根据前面前四节所讲的Swing UI组件应用知识,实现一个真正的Swing UI演示,以更加贴近实际编程的方式来说明Swing中组件的应用知识。首先来介绍一下要实现的功能:

  • 通过文件对话框选择图像文件,刷新JFrame中的内容面板实现图像显示。
  • 通过单击[处理]按钮实现对图像的必要处理,然后刷新显示图像。

大致的UI组件布局如图3-1所示。

screenshot

其中支持BufferedImage对象显示的自定义JPanel类的实现如下:

package com.book.chapter.three;

import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;

import javax.swing.JPanel;

public class ImagePanel extends JPanel {
    /**
    * 
    */
    private static final long serialVersionUID = 1L;
    private BufferedImage sourceImage;
    private BufferedImage destImage;

    public ImagePanel() {

    }

    @Override
    protected void paintComponent(Graphics g) {
        Graphics2D g2d = (Graphics2D) g;
        g2d.clearRect(0, 0, 
        this.getWidth(), 
        this.getHeight());
        if (sourceImage != null) {
            g2d.drawImage(sourceImage, 0, 0, 
                    sourceImage.getWidth(),
                    sourceImage.getHeight(), null);
            if (destImage != null) {
                g2d.drawImage(destImage,
                sourceImage.getWidth() + 10, 0,
                destImage.getWidth(), 
                destImage.getHeight(), null);
            }
        }
    }

    public void process()
    {
        // do nothing
    }

    public BufferedImage getSourceImage() {
        return sourceImage;
    }

    public void setSourceImage(BufferedImage sourceImage) {
        this.sourceImage = sourceImage;
    }

    public BufferedImage getDestImage() {
        return destImage;
    }

    public void setDestImage(BufferedImage destImage) {
        this.destImage = destImage;
    }

}

SwingUI界面实现与JButton按钮监听处理的类的代码如下:

package com.book.chapter.three;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;

public class MainUI extends JFrame 
        implements ActionListener {

    /**
    * 
    */
    private static final long serialVersionUID = 1L;
    public static final String IMAGE_CMD = "选择图像...";
    public static final String PROCESS_CMD = "处理";

    private JButton imgBtn;
    private JButton processBtn;
    private ImagePanel imagePanel;

    // image
    private BufferedImage srcImage;

    public MainUI()
    {
        setTitle("JFrame UI - 演示");
        imgBtn = new JButton(IMAGE_CMD);
        processBtn = new JButton(PROCESS_CMD);

        // buttons
        JPanel btnPanel = new JPanel();
        btnPanel.setLayout(new
                     FlowLayout(FlowLayout.RIGHT));
        btnPanel.add(imgBtn);
        btnPanel.add(processBtn);

        // filters
        imagePanel = new ImagePanel();
        getContentPane().setLayout(new BorderLayout());
        getContentPane().add(imagePanel,
                     BorderLayout.CENTER);
        getContentPane().add(btnPanel, BorderLayout.SOUTH);

        // setup listener
        setupActionListener();

    }

    private void setupActionListener() {
        imgBtn.addActionListener(this);
        processBtn.addActionListener(this);
    }

    @Override
    public void actionPerformed(ActionEvent e) {

        if(SwingUtilities.isEventDispatchThread())
        {
            System.out.println("Event Dispath Thread!!");
        }

        if(srcImage == null)
        {
            JOptionPane.showMessageDialog(this, 
                        "请先选择图像源文件");
            try {
                JFileChooser chooser = 
                        new JFileChooser();
                setFileTypeFilter(chooser);
                chooser.showOpenDialog(null);
                File f = chooser.getSelectedFile();
                if(f != null)
                {
                    srcImage = ImageIO.read(f);
                    imagePanel.setSourceImage(
                            srcImage);
                    imagePanel.repaint();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            return;
        }
        if(IMAGE_CMD.equals(e.getActionCommand()))
        {
            try {
                JFileChooser chooser = 
                        new JFileChooser();
                setFileTypeFilter(chooser);
                chooser.showOpenDialog(null);
                File f = chooser.getSelectedFile();
                if(f != null)
                {
                    srcImage = ImageIO.read(f);
                    imagePanel.setSourceImage(
                            srcImage);
                    imagePanel.repaint();
                }
            } catch (IOException e1) {
                e1.printStackTrace();
            }
            imagePanel.repaint();
        }
        else if(PROCESS_CMD.equals(e.getActionCommand()))
        {
            imagePanel.process();
            imagePanel.repaint();
        }
    }

    public void setFileTypeFilter(JFileChooser chooser)
    {
        FileNameExtensionFilter filter = 
            new FileNameExtensionFilter(
                "JPG & PNG Images", "jpg", "png");
            chooser.setFileFilter(filter);
    }

    public void openView()
    {
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        setPreferredSize(new Dimension(800, 600));
        pack();
        setVisible(true);
    }

    public static void main(String[] args) {
        MainUI ui = new MainUI();
        ui.openView();
    }
}
相关文章
|
3天前
|
设计模式 安全 Java
Java编程中的单例模式:理解与实践
【10月更文挑战第31天】在Java的世界里,单例模式是一种优雅的解决方案,它确保一个类只有一个实例,并提供一个全局访问点。本文将深入探讨单例模式的实现方式、使用场景及其优缺点,同时提供代码示例以加深理解。无论你是Java新手还是有经验的开发者,掌握单例模式都将是你技能库中的宝贵财富。
10 2
|
15天前
|
存储 Java
Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。
【10月更文挑战第19天】本文详细介绍了Java中的HashMap和TreeMap,通过具体示例展示了它们在处理复杂数据结构问题时的应用。HashMap以其高效的插入、查找和删除操作著称,而TreeMap则擅长于保持元素的自然排序或自定义排序,两者各具优势,适用于不同的开发场景。
28 1
|
8天前
|
人工智能 前端开发 Java
基于开源框架Spring AI Alibaba快速构建Java应用
本文旨在帮助开发者快速掌握并应用 Spring AI Alibaba,提升基于 Java 的大模型应用开发效率和安全性。
基于开源框架Spring AI Alibaba快速构建Java应用
|
12天前
|
存储 安全 Java
系统安全架构的深度解析与实践:Java代码实现
【11月更文挑战第1天】系统安全架构是保护信息系统免受各种威胁和攻击的关键。作为系统架构师,设计一套完善的系统安全架构不仅需要对各种安全威胁有深入理解,还需要熟练掌握各种安全技术和工具。
41 10
|
6天前
|
Java 程序员 数据库连接
Java中的异常处理:理解与实践
【10月更文挑战第29天】在Java编程的世界里,异常像是不请自来的客人,它们可能在任何时候闯入我们的程序宴会。了解如何妥善处理这些意外访客,不仅能够保持我们程序的优雅和稳健,还能确保它不会因为一个小小的失误而全盘崩溃。本文将通过浅显易懂的方式,带领读者深入异常处理的核心概念,并通过实际示例展现如何在Java代码中实现有效的异常管理策略。
|
11天前
|
SQL 监控 Java
技术前沿:Java连接池技术的最新发展与应用
本文探讨了Java连接池技术的最新发展与应用,包括高性能与低延迟、智能化管理和监控、扩展性与兼容性等方面。同时,结合最佳实践,介绍了如何选择合适的连接池库、合理配置参数、使用监控工具及优化数据库操作,为开发者提供了一份详尽的技术指南。
21 7
|
9天前
|
SQL Java 数据库连接
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率
在Java应用中,数据库访问常成为性能瓶颈。连接池技术通过预建立并复用数据库连接,有效减少连接开销,提升访问效率。本文介绍了连接池的工作原理、优势及实现方法,并提供了HikariCP的示例代码。
21 3
|
9天前
|
存储 Java 关系型数据库
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践
在Java开发中,数据库连接是应用与数据交互的关键环节。本文通过案例分析,深入探讨Java连接池的原理与最佳实践,包括连接创建、分配、复用和释放等操作,并通过电商应用实例展示了如何选择合适的连接池库(如HikariCP)和配置参数,实现高效、稳定的数据库连接管理。
22 2
|
10天前
|
缓存 Java 调度
Java中的多线程编程:从基础到实践
【10月更文挑战第24天】 本文旨在为读者提供一个关于Java多线程编程的全面指南。我们将从多线程的基本概念开始,逐步深入到Java中实现多线程的方法,包括继承Thread类、实现Runnable接口以及使用Executor框架。此外,我们还将探讨多线程编程中的常见问题和最佳实践,帮助读者在实际项目中更好地应用多线程技术。
17 3
|
12天前
|
监控 安全 Java
Java多线程编程的艺术与实践
【10月更文挑战第22天】 在现代软件开发中,多线程编程是一项不可或缺的技能。本文将深入探讨Java多线程编程的核心概念、常见问题以及最佳实践,帮助开发者掌握这一强大的工具。我们将从基础概念入手,逐步深入到高级主题,包括线程的创建与管理、同步机制、线程池的使用等。通过实际案例分析,本文旨在提供一种系统化的学习方法,使读者能够在实际项目中灵活运用多线程技术。