[笔记] 疯狂JAVA讲义(第3版)第12章 Swing编程

简介: [笔记] 疯狂JAVA讲义(第3版)第12章 Swing编程

第12章 Swing编程


12.1 Swing概述


实际开发Java图形界面程序时,很少使用AWT组件,绝大部分时候使用Swing组件开发。


Swing由100% 纯Java实现,不再依赖本地平台的GUI。


Swing具有两个特征:


1、采用MVC(Model-View-Controller)设计模式。


2、在不同平台上表现一致。


//获取当前支持的LAF(LookAndFeel)
import javax.swing.UIManager;
import java.swing.*;
public class AlllLookAndFeel
{
public static void main(String[] args) {
System.out.println(“可用LAF”);
for(UIManager.LookAndFeelInfo info:
UIManager.getInstalledLookAndFeels()){
System.out.println(info.getName()+" "+info);
}
}
}


12.2 Swing基本组件的用法


Swing为所有AWT组件提供对应实现,通常在AWT组件的组件名前加J就变成了对应的Swing组件。


12.2.1 Java7的Swing组件层次


12.2.2 AWT组件的Swing实现


相比AWT组件,Swing组件提供如下4个额外功能:


1、设置提示信息:setToolTipText()


2、使用图表修饰,Swing为Icon接口提供一个实现类ImageIcon。


3、支持拔插式的外观风格。 每个JComponent对象有一个对应的ComponentUI对象,为它实现会话、事件处理等工作,ComponentUI对象依赖当前使用的PLAF,


使用UIManager.setLookAndFeel()可以改变外观风格。


4、支持设置边框。


每个Swing组件都有一个对应的UI类,是将J去掉然后加UI后缀。


//使用Swing组件创建窗口,功能基本没实现。实现了右键改变窗口风格
import java.awt.BorderLayout;
import java.awt.event.InputEvent;
import java.awt.event.ActionListener;
import javax.swing.Box;
import javax.swing.ButtonGroup;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JRadioButton;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
public class SwingComponent
{
JFrame f = new JFrame(“测试”);
Icon okIcon = new ImageIcon(“ico/ok.png”);
JButton ok = new JButton(“确认”,okIcon);
JRadioButton male = new JRadioButton(“男”,true);
JRadioButton female = new JRadioButton(“女”,false);
ButtonGroup bg = new ButtonGroup();
JCheckBox married = new JCheckBox(“是否已婚?”,false);
String[] colors = new String[]{“红”,“黄”,“蓝”};
JComboBox<String> colorChooser = new JComboBox<>(colors);
JList<String> colorList = new JList<>(colors);
JTextArea ta = new JTextArea(8,20);
JTextField name = new JTextField(40);
JMenuBar mb = new JMenuBar();
JMenu file = new JMenu(“文件”);
JMenu edit = new JMenu(“编辑”);
Icon newIcon = new ImageIcon(“D://TEST//java//ch12//ico//new.png”);
JMenuItem newItem = new JMenuItem(“新建”,newIcon);
Icon saveIcon = new ImageIcon(“D://TEST//java//ch12//ico//save.png”);
JMenuItem saveItem = new JMenuItem(“保存”,saveIcon);
Icon exitIcon = new ImageIcon(“D://TEST//java//ch12//ico//exit.png”);
JMenuItem exitItem = new JMenuItem(“退出”,exitIcon);
JCheckBoxMenuItem autoWrap = new JCheckBoxMenuItem(“自动换行”);
JMenuItem copyItem = new JMenuItem(“复制”,new ImageIcon(“D://TEST//java//ch12//ico//copy.png”));
JMenuItem pasteItem = new JMenuItem(“粘贴”,new ImageIcon(“D://TEST//java//ch12//ico//paste.png”));
JMenu format = new JMenu(“格式”);
JMenuItem commentItem = new JMenuItem(“注释”);
JMenuItem cancelItem = new JMenuItem(“取消注释”);
JPopupMenu pop = new JPopupMenu();
ButtonGroup flavorGroup = new ButtonGroup();
JRadioButtonMenuItem metalItem = new JRadioButtonMenuItem(“Metal”,true);
JRadioButtonMenuItem nimbuslItem = new JRadioButtonMenuItem(“Nimbus”);
JRadioButtonMenuItem windowsItem = new JRadioButtonMenuItem(“Windows”);
JRadioButtonMenuItem classicItem = new JRadioButtonMenuItem(“Classic”);
JRadioButtonMenuItem motifItem = new JRadioButtonMenuItem(“Motif”);
public void init()
{
JPanel bottom = new JPanel();
bottom.add(name);
bottom.add(ok);
f.add(bottom,BorderLayout.SOUTH);
JPanel checkPanel = new JPanel();
checkPanel.add(colorChooser);
bg.add(male);
bg.add(female);
checkPanel.add(male);
checkPanel.add(female);
checkPanel.add(married);
Box topLeft = Box.createVerticalBox();
JScrollPane taJsp = new JScrollPane(ta);
topLeft.add(taJsp);
topLeft.add(checkPanel);
Box top = Box.createHorizontalBox();
top.add(topLeft);
top.add(colorList);
f.add(top);
newItem.setAccelerator(KeyStroke.getKeyStroke(‘N’, InputEvent.CTRL_DOWN_MASK));//java 9后不推荐使用CTRL_MASK
newItem.addActionListener(e->ta.append(“用户单击了"新建菜单”\n"));
file.add(newItem);
file.add(saveItem);
file.add(exitItem);
edit.add(autoWrap);
edit.addSeparator();
edit.add(copyItem);
edit.add(pasteItem);
commentItem.setToolTipText(“将代码注释起来”);
format.add(commentItem);
format.add(cancelItem);
edit.add(new JMenuItem("-"));
edit.add(format);
mb.add(file);
mb.add(edit);
f.setJMenuBar(mb);
flavorGroup.add(metalItem);
flavorGroup.add(nimbuslItem);
flavorGroup.add(windowsItem);
flavorGroup.add(classicItem);
flavorGroup.add(motifItem);
pop.add(metalItem);
pop.add(nimbuslItem);
pop.add(windowsItem);
pop.add(classicItem);
pop.add(motifItem);
ActionListener flavorListener = e->{
try{
switch (e.getActionCommand()) {
case “Metal风格”:
changeFlavor(1);
break;
case “Nimbus风格”:
changeFlavor(2);
case “Windows风格”:
changeFlavor(3);
case “Windows经典风格”:
changeFlavor(4);
case “Motif风格”:
changeFlavor(5);
default:
break;
}
}
catch(Exception ee){
ee.printStackTrace();
}
};
metalItem.addActionListener(flavorListener);
nimbuslItem.addActionListener(flavorListener);
windowsItem.addActionListener(flavorListener);
classicItem.addActionListener(flavorListener);
motifItem.addActionListener(flavorListener);
ta.setComponentPopupMenu(pop);
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.pack();
f.setVisible(true);
}
private void changeFlavor(int flavor) throws Exception{
switch(flavor){
case 1:
UIManager.setLookAndFeel(“javax.swing.plaf.metal.MetalLookAndFeel”);
break;
case 2:
UIManager.setLookAndFeel(“javax.swing.plaf.nimbus.NimbusLookAndFeel”);
break;
case 3:
UIManager.setLookAndFeel(“com.sun.java.swing.plaf.motif.MotifLookAndFeel”);
break;
case 4:
UIManager.setLookAndFeel(“com.sun.java.swing.plaf.windows.WindowsLookAndFeel”);
break;
case 5:
UIManager.setLookAndFeel(“com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel”);
break;
}
SwingUtilities.updateComponentTreeUI(f.getContentPane());
SwingUtilities.updateComponentTreeUI(mb);
SwingUtilities.updateComponentTreeUI(pop);
}
public static void main(String[] args) {
new SwingComponent().init();
}
}


12.2.3 为组件设置边框


setBorder(Border b)


为Swing组件添加边框可按如下步骤进行;


1、使用BorderFactory或XXXBorder创建XxxBorder实例


2、调用setBorder(Border b)方法


12.2.4 Swing组件的双缓冲和键盘驱动


Swing组件默认采用双缓冲绘图技术,有效改善频繁绘制GUI组件的显示效果(避免闪烁现象)


JComponent 提供了getInputMap()和getActionMap()方法,允许用户通过键盘操作代替鼠标驱动。相当于快捷键。


getInputMap()返回一个InputMap对象,用于将KeyStroke对象和名字关联;getActionMap()返回一个ActionMap对象,用于将名字和Action关联。


典型用法:


component.getInputMap().put(aKeyStroke,aCommand);


component.getActionMap().put(aCommand,anAction);


12.2.5 使用JToolBar创建工具条


12.2.6 使用JFileChooser和Java 7增强的JColorChooser


用于选择文件和 选择颜色。


12.2.7 使用JOptionPane


用于弹出各种类型对话框。


12.3 Swing中的特殊容器


12.3.1 使用JSplitPane


用于创建一个分割面板


12.3.2 使用JTabbedPane


可以在窗口上放置多个标签页。


12.3.3 使用JLayeredPane、JDesktopPane和JInternalFrame


深度容器、多文档界面、内部窗口


12.4 Swing简化的拖放功能


Swing的部分组件已经提供了默认的拖放支持。


使用setDragEabled(true) 启动拖放支持。


Swing还提供了一种特殊的类:TransferHandler,可以直接将某个组件的指定属性设置成拖放目标,


前提是具有setter()方法。


12.5 Java7新增的Swing功能


12.5.1 使用Layer装饰组件


12.5.2 创建透明、不规则形状窗口


12.6 使用JProgressBar、ProgressMonitor和BoundedRangeModel创建进度条


12.6.1 创建进度条


12.6.2 创建进度对话框


12.7 使用JSlider和BoundedRangeModel创建滑动条


12.8 使用JSpinner和SpinnerModel 创建微调控制器


12.9 使用JList、JComboBox创建列表框


12.9.1简单列表框


12.9.2 不强制存储列表项的ListModel和ComboBoxModel


12.9.3 强制存储列表项的DefaultListModel和DefaultComboBoxModel


12.9.4 使用ListCellRenderer改变列表项外观


12.10 使用JTree和TreeModel创建树


12.11 使用JTable和TableModel创建表格


12.12 使用JFormattedTextField和JTextPane创建格式文本


相关文章
|
19天前
|
Java 程序员
Java编程中的异常处理:从基础到高级
在Java的世界中,异常处理是代码健壮性的守护神。本文将带你从异常的基本概念出发,逐步深入到高级用法,探索如何优雅地处理程序中的错误和异常情况。通过实际案例,我们将一起学习如何编写更可靠、更易于维护的Java代码。准备好了吗?让我们一起踏上这段旅程,解锁Java异常处理的秘密!
|
3天前
|
算法 Java 调度
java并发编程中Monitor里的waitSet和EntryList都是做什么的
在Java并发编程中,Monitor内部包含两个重要队列:等待集(Wait Set)和入口列表(Entry List)。Wait Set用于线程的条件等待和协作,线程调用`wait()`后进入此集合,通过`notify()`或`notifyAll()`唤醒。Entry List则管理锁的竞争,未能获取锁的线程在此排队,等待锁释放后重新竞争。理解两者区别有助于设计高效的多线程程序。 - **Wait Set**:线程调用`wait()`后进入,等待条件满足被唤醒,需重新竞争锁。 - **Entry List**:多个线程竞争锁时,未获锁的线程在此排队,等待锁释放后获取锁继续执行。
26 12
|
16天前
|
安全 算法 Java
Java多线程编程中的陷阱与最佳实践####
本文探讨了Java多线程编程中常见的陷阱,并介绍了如何通过最佳实践来避免这些问题。我们将从基础概念入手,逐步深入到具体的代码示例,帮助开发者更好地理解和应用多线程技术。无论是初学者还是有经验的开发者,都能从中获得有价值的见解和建议。 ####
|
19天前
|
安全 Java 编译器
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
Kotlin教程笔记(27) -Kotlin 与 Java 共存(二)
|
16天前
|
Java 调度
Java中的多线程编程与并发控制
本文深入探讨了Java编程语言中多线程编程的基础知识和并发控制机制。文章首先介绍了多线程的基本概念,包括线程的定义、生命周期以及在Java中创建和管理线程的方法。接着,详细讲解了Java提供的同步机制,如synchronized关键字、wait()和notify()方法等,以及如何通过这些机制实现线程间的协调与通信。最后,本文还讨论了一些常见的并发问题,例如死锁、竞态条件等,并提供了相应的解决策略。
40 3
|
19天前
|
Java 开发工具 Android开发
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
Kotlin教程笔记(26) -Kotlin 与 Java 共存(一)
|
21天前
|
开发框架 安全 Java
Java 反射机制:动态编程的强大利器
Java反射机制允许程序在运行时检查类、接口、字段和方法的信息,并能操作对象。它提供了一种动态编程的方式,使得代码更加灵活,能够适应未知的或变化的需求,是开发框架和库的重要工具。
36 2
|
22天前
|
安全 Java 开发者
Java中的多线程编程:从基础到实践
本文深入探讨了Java多线程编程的核心概念和实践技巧,旨在帮助读者理解多线程的工作原理,掌握线程的创建、管理和同步机制。通过具体示例和最佳实践,本文展示了如何在Java应用中有效地利用多线程技术,提高程序性能和响应速度。
54 1
|
18天前
|
Java 数据库连接 编译器
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
Kotlin教程笔记(29) -Kotlin 兼容 Java 遇到的最大的“坑”
35 0
|
1月前
|
监控 安全 Java
Java中的多线程编程:从入门到实践####
本文将深入浅出地探讨Java多线程编程的核心概念、应用场景及实践技巧。不同于传统的摘要形式,本文将以一个简短的代码示例作为开篇,直接展示多线程的魅力,随后再详细解析其背后的原理与实现方式,旨在帮助读者快速理解并掌握Java多线程编程的基本技能。 ```java // 简单的多线程示例:创建两个线程,分别打印不同的消息 public class SimpleMultithreading { public static void main(String[] args) { Thread thread1 = new Thread(() -> System.out.prin
下一篇
DataWorks