第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创建格式文本