230 likes | 422 Views
swing 基础二. 本节目标. Look And Feel 了解 MVC 体系结构 常用组件 JComboBox JTextPane JTabel JTree. 可插入的外观和感觉. UIManager 管理外观 setLookAndFeel(String className) SwingUtilities.updateComponentTreeUI(frame); 常用外观: Metal:javax.swing.plaf.metal.MetalLookAndFeel
E N D
本节目标 • Look And Feel • 了解MVC体系结构 • 常用组件 • JComboBox • JTextPane • JTabel • JTree
可插入的外观和感觉 • UIManager管理外观 • setLookAndFeel(String className) • SwingUtilities.updateComponentTreeUI(frame); • 常用外观: • Metal:javax.swing.plaf.metal.MetalLookAndFeel • Motif :com.sun.java.swing.plaf.motif.MotifLookAndFeel • GTK+:com.sun.java.swing.plaf.gtk.GTKLookAndFeel • Windows:com.sun.java.swing.plaf.windows.WindowsLookAndFeel
MVC(Model-View-Control)体系结构 Swing胜过AWT的主要优势在于MVC体系结构的普遍使用。在一个MVC用户界面中,存三个通讯对象:模型、视图和控制。模型是指定的逻辑表示法,视图是模型的可视化表示法,而控制则指定了如何处理用户输入。当模型发生改变时,它会通知所有依赖它的视图,视图使用控件指定其相应机制。 为了简化组件的设计工作,在Swing组件中视图和控制两部分合为一体。每个组件有一个相关的分离模型和它使用的界面(包括视图和控件)。比如,按钮JButton有一个存储其状态的分离模型ButtonModel对象。组件的模型是自动设置的,例如一般都使用JButton 而不是使用ButtonModel 对象。另外,通过Model类的子类或通过实现适当的接口,可以为组件建立自己的模型。把数据模型与组件联系起来用setModel( )方法。
几个基于MVC实现的组件 • JComboBox • JTextPane • JTable • JTree
JCombobox ComboBoxModel 定制ListCellRenderer绘制单元格 setRenderer(ListCellRenderer cellRenderer)
JComboBox示例_1 import java.awt.*;import java.awt.event.*;import javax.swing.*;public class JComboBox4{ String[] s={"西瓜","苹果","草莓","香蕉","葡萄"}; public JComboBox4(){ JFrame f=new JFrame("JComboBox"); Container contentPane=f.getContentPane(); JComboBox combo=new JComboBox(s); combo.setBorder(BorderFactory.createTitledBorder("你最喜欢吃哪些水果?")); combo.setRenderer(new ACellRenderer()); combo.setMaximumRowCount(3); contentPane.add(combo); f.pack(); f.show(); f.addWindowListener(new WindowAdapter(){
JComboBox示例_2 public void windowClosing(WindowEvent e){ System.exit(0); } }); } public static void main(String[] args){ new JComboBox4(); }} class ACellRenderer extends JLabel implements ListCellRenderer{ ACellRenderer(){ setOpaque(true); } public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus){
JComboBox示例_3 if (value!=null){ setText(value.toString()); setIcon(new ImageIcon(".\\icons\\fruit"+(index+1)+".jpg")); } if (isSelected){ setBackground(list.getSelectionBackground()); setForeground(list.getSelectionForeground()); }else{ setBackground(list.getBackground()); setForeground(list.getForeground()); } return this; } }
JTextPane示例_1 import java.awt.Color; import javax.swing.ImageIcon; import javax.swing.JFrame; import javax.swing.JTextPane; import javax.swing.text.MutableAttributeSet; import javax.swing.text.SimpleAttributeSet; import javax.swing.text.StyleConstants; import javax.swing.text.StyledDocument; import javax.swing.JScrollPane; public class DemoJTextPane2 extends JFrame { JTextPane jtextPane; MutableAttributeSet center_align, char_style_1, char_style_2; public DemoJTextPane2() { jtextPane = new JTextPane(); JScrollPane scroll = new JScrollPane(jtextPane, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); StyledDocument mydocument=jtextPane.getStyledDocument(); center_align=new SimpleAttributeSet();
JTextPane示例_2 char_style_1=new SimpleAttributeSet(); char_style_2=new SimpleAttributeSet(); StyleConstants.setAlignment(center_align, StyleConstants.ALIGN_CENTER); StyleConstants.setFontFamily(char_style_1,"Timer"); StyleConstants.setFontSize(char_style_1,20); StyleConstants.setForeground(char_style_1,Color.red); StyleConstants.setFontFamily(char_style_2,"Serif"); StyleConstants.setFontSize(char_style_2,14); StyleConstants.setForeground(char_style_2,Color.BLUE); try{ jtextPane.setCaretPosition(mydocument.getLength()); // 设置插入位置 jtextPane.insertIcon(new ImageIcon(this.getClass().getResource("images/qqicon.gif"))); mydocument.insertString(mydocument.getLength(), "\n\nfirst\n\n",char_style_1); } catch(Exception e){}
JTextPane示例_3 try{ mydocument.insertString(mydocument.getLength(), "second\n\n",char_style_2); jtextPane.setCaretPosition(mydocument.getLength()); // 设置插入位置 jtextPane.insertIcon(new ImageIcon(this.getClass().getResource("images/qqicon.gif"))); } catch(Exception e){} getContentPane().add(scroll); setSize(400,300); setVisible(true); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); } public static void main(String args[]){ new DemoJTextPane2(); } }
表格(JTable) • JTable构造方法: • JTable(TableModel dm) • JTable(object[][]rowData,object[]columnNames) • JTable(Vector rowData,Vector columnNames) • JTable类常用的方法有:getModel() //获得表格的数据来源对象getSelectedRow() //获得选中的行数
表格(JTable) 表格是Swing新增加的组件,主要功能是把数据以二维表格的形式显示出来。使用表格,依据M-V-C的思想,最好先生成一个MyTableModel类型的对象来表示数据,这个类是从AbstractTableModel类中继承来的,其中有几个方法是一定要重写,例如getColumnCount,getRowCount,getColumnName,getValueAt。因为JTable会从这个对象中自动获取表格显示所必需的数据,AbstractTableModel类的对象负责表格大小的确定(行、列)、内容的填写、赋值、表格单元更新的检测等等一切跟表格内容有关的属性及其操作。JTable类生成的对象以该TableModel为参数,并负责将TableModel对象中的数据以表格的形式显示出来。
JTable示例_1 import javax.swing.table.AbstractTableModel; import javax.swing.*; import java.awt.*; import java.awt.event.*; public class DemoJTableModel2 implements ActionListener { JTable t = null; public DemoJTableModel2() { JFrame f = new JFrame("DataModel"); JButton b1 = new JButton("数学老师"); b1.addActionListener(this); JButton b2 = new JButton("学生阿呆"); b2.addActionListener(this); JPanel panel = new JPanel(); panel.add(b1); panel.add(b2); t = new JTable(new MyTableModel2_1(1)); t.setPreferredScrollableViewportSize(new Dimension(550, 30)); JScrollPane s = new JScrollPane(t); f.getContentPane().add(panel, BorderLayout.NORTH);
JTable示例_2 f.getContentPane().add(s, BorderLayout.CENTER); f.pack(); f.setVisible(true); f.addWindowListener(new WindowAdapter() { public void windowClosing(WindowEvent e) { System.exit(0); } }); } public void actionPerformed(ActionEvent e) { if (e.getActionCommand().equals("学生阿呆")) t.setModel(new MyTableModel2_1(1)); if (e.getActionCommand().equals("数学老师")) t.setModel(new MyTableModel2_1(2)); t.revalidate(); } public static void main(String args[]) { new DemoJTableModel2(); } }
JTable示例_3 class MyTableModel2_1 extends AbstractTableModel { Object[][] p1 = { { "阿呆", "1234", new Integer(66), new Integer(50),new Integer(116), new Boolean(false), new Boolean(false) } }; String[] n1 = { "姓名", "学号", "语文", "数学", "总分", "及格", "作弊" }; Object[][] p2 = { { "阿呆", "1234", new Integer(50), new Boolean(false),new Boolean(false), "01234" }, { "阿瓜", "1235", new Integer(75), new Boolean(true),new Boolean(false), "05678" } }; String[] n2 = { "姓名", "学号", "数学", "及格", "作弊", "电话" }; int model = 1; public MyTableModel2_1(int i) { model = i; } public int getColumnCount() { if (model == 1) return n1.length; else
JTable示例_4 return n2.length; } public int getRowCount() { if (model == 1) return p1.length; else return p2.length; } public String getColumnName(int col) { if (model == 1) return n1[col]; else return n2[col]; } public Object getValueAt(int row, int col) { if (model == 1) return p1[row][col]; else return p2[row][col]; } public Class getColumnClass(int c) { return getValueAt(0, c).getClass(); } }
JTree示例_1 import java.awt.*; import java.awt.event.*; import javax.swing.*; import javax.swing.tree.*; public class DemoJTree1 extends JPanel { String[][] data = { { "Colors", "Red", "Blue", "Green" }, { "Flavors", "Tart", "Sweet", "Bland" }, { "Length", "Short", "Medium", "Long" }, { "Volume", "High", "Medium", "Low" }, { "Temperature", "High", "Medium", "Low" }, { "Intensity", "High", "Medium", "Low" } }; static int i = 0; // I用于统计按钮点击的次数 DefaultMutableTreeNode root, child, targetNode; JTree tree; DefaultTreeModel model; public DemoJTree1() { setLayout(new BorderLayout()); // 根节点进行初始化 root = new DefaultMutableTreeNode("root");
JTree示例_2 // 树进行初始化,其数据来源是root对象 tree = new JTree(root); DefaultTreeCellRenderer dtcr=new DefaultTreeCellRenderer(); dtcr.setBackgroundSelectionColor(Color.ORANGE); tree.setCellRenderer(dtcr); // 把滚动面板添加到Trees中 add(new JScrollPane(tree)); // 获得数据对象DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); // 按钮test进行初始化 JButton test = new JButton("Press me"); // 按钮test注册监听器 test.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent e) { if (i < data.length) { // 按钮test点击的次数小于data的长度 child = new Branch(data[i++]).node(); // 生成子节点 targetNode = (DefaultMutableTreeNode)
JTree示例_3 tree.getLastSelectedPathComponent(); if (targetNode == null) targetNode = root; model.insertNodeInto(child, targetNode, 0); // 把child添加到chosen } } }); test.setBackground(Color.blue); // 按钮test设置背景色为蓝色 test.setForeground(Color.white); // 按钮test设置前景色为白色 JPanel p = new JPanel(); // 面板p初始化 p.add(test); // 把按钮添加到面板p中 add(p, BorderLayout.SOUTH); // 把面板p添加到Trees中 } public static void main(String args[]) {
JTree示例_4 JFrame jf = new JFrame("JTree demo"); jf.getContentPane().add(new DemoJTree1(), BorderLayout.CENTER); // 把Trees对象添加到JFrame对象的中央 jf.setSize(200, 500); jf.setVisible(true); }} class Branch { DefaultMutableTreeNode r; public Branch(String[] data) { r = new DefaultMutableTreeNode(data[0]); // 给节点r添加多个子节点 for (int i = 1; i < data.length; i++) { r.add(new DefaultMutableTreeNode(data[i])); } } public DefaultMutableTreeNode node() {// 返回节点 return r; }}
Swing的程序设计 Swing的程序设计一般可按照下列流程进行: 1. 引入Swing包 2. 选择"外观和感觉" 3. 设置顶层容器 4. 设置按钮和标签 5. 向容器中添加组件 6. 在组件周围添加边界 7. 进行事件处理