1 应用结构
  新建一个java应用程序JavaApp,并创建相关的包及文件,其中简单实现了一个登录界面(JDBC 访问MYSQL数据库),登录成功后跳转到主界面.在主界面上单击菜单,可以打开子窗体.java swing自带的JTabbedPane没有显示关闭按钮的功能,这里在com.mkmis.controls包下自定义了一个TabbedPane控件,可以实现带关闭按钮的页签面板.应用结构如下图所示:

  2 登陆界面设计
  在IDE中新建一个Login的JFrame窗体,单击[设计]视图,可以将组件面板中的相关控件拖放到界面上,和Vistual Studio的操作差别不大,是界面显示效果较差,不及Vistual Studio.用户名文本框用的文本字段,密码框用的是口令字段控件.登录和退出按钮用的是按钮控件.
  设计完成后,单击运行按钮,界面效果如下图所示:

  3 相关属性设置
  Java Swing的很多属性设置用的方法,而NET用的属性.例如设置窗体标题,java swing用的是setTitle().另外窗体居中用的是setLocationRelativeTo(getOwner()). 获取文本框的值为getText()方法,如下代码所示:
  1     public Login() {
  2         initComponents();
  3         setTitle("登录");
  4         setDefaultCloseOperation(EXIT_ON_CLOSE);
  5         setVisible(true);
  6         setResizable(false);
  7         setLocationRelativeTo(getOwner()); //居中显示
  8
  9     }
  1  private void btnLoginActionPerformed(java.awt.event.ActionEvent evt) {
  2     // TODO add your handling code here:
  3     if(this.txtUserName.getText()!="" && this.txtPWD.getText().toString()!="")
  4     {
  5         Connection conn = DBConnection.getConnection();
  6         PreparedStatement ps = null;
  7         ResultSet rs = null;
  8         try {
  9             ps = conn.prepareStatement(
  "select * from users where UserName = ? and password = ?");
  10             ps.setString(1,this.txtUserName.getText());//
  11             ps.setString(2, this.txtPWD.getText());
  12             rs = ps.executeQuery();
  13             while (rs.next()) {
  14                 User user = new User();
  15                 user.setId(rs.getInt("id"));
  16                 user.setUsername(rs.getString("UserName"));
  17                 user.setPassword(rs.getString("password"));
  18
  19                 System.out.println(user.toString());
  20                 //跳转页面
  21                 FrameMain frm=new FrameMain(user.getUsername());
  22                 frm.setVisible(true);
  23                 this.dispose();//关闭当前窗体
  24
  25             }
  26         } catch (SQLException e) {
  27             e.printStackTrace();
  28         } finally {
  29             DBConnection.closeResultSet(rs);
  30             DBConnection.closeStatement(ps);
  31             DBConnection.closeConnection(conn);
  32         }
  33
  34      }
  35  }
  显示一个窗体是设置其setVisiable(true);关闭一个窗体用的dispose();在登录界面想着输完用户名和密码后,按enter键可以自动登录,在网上搜下,发现了一个变通的方法,是监听密码框的keypressed事件,当然需要验证一下用户名和密码是否为空(此处未加验证!),如下代码所示:
  1    private void txtPWDKeyPressed(java.awt.event.KeyEvent evt) {
  2         // TODO add your handling code here:
  3         if(evt.getKeyCode()==KeyEvent.VK_ENTER)
  4         {
  5             //调用登录事件
  6             btnLoginActionPerformed(null);
  7
  8         }
  9     }
  4 主界面
  登录成功后,单击左边的树叶节点,通过反射动态实例化窗体(实际上菜单应该从数据库加载)并显示,主界面如下:
  图表控件用的是JFreeChart控件,默认显示中文有乱码情况,需要设置显示中文处的字体进行解决.另外设置主界面显示大化的代码为this.setExtendedState(this.getExtendedState()|JFrame.MAXMIZED_BOTH).为了让某个控件可以随着窗体大小变化而自动调整,需要设置其水平和垂直自动调整.
  1     public FrameMain(){
  2         initComponents();
  3          setLocationRelativeTo(getOwner()); //居中显示
  4          this.setExtendedState(this.getExtendedState()|JFrame.MAXIMIZED_BOTH );
  //大化 window
  5          LoadTree();
  6
  7     }
  8     public FrameMain(String uname){
  9         initComponents();
  10          setLocationRelativeTo(getOwner()); //居中显示
  11          this.setExtendedState(this.getExtendedState()|JFrame.MAXIMIZED_BOTH );
  12          LoadTree();
  13          this.lblUser.setText("欢迎 "+uname+ " 登录!");
  14
  15     }
  主界面在初始化时,调用LoadTree方法来填充左边的菜单树,如下所示:
  1     private void LoadTree()
  2     {
  3         //自定义控件,支持关闭按钮
  4         jTabbedPane1.setCloseButtonEnabled(true);
  5
  6         DefaultMutableTreeNode node1 = new DefaultMutableTreeNode("软件部");
  7         node1.add(new DefaultMutableTreeNode("产品部"));
  8         node1.add(new DefaultMutableTreeNode("测试部"));
  9         node1.add(new DefaultMutableTreeNode("设计部"));
  10
  11         DefaultMutableTreeNode node2 = new DefaultMutableTreeNode("销售部");
  12         node2.add(new DefaultMutableTreeNode("jack"));
  13         node2.add(new DefaultMutableTreeNode("Lily"));
  14         node2.add(new DefaultMutableTreeNode("Smith"));
  15
  16         DefaultMutableTreeNode top = new DefaultMutableTreeNode("职员管理");
  17
  18
  19         top.add(new DefaultMutableTreeNode("总经理"));
  20         top.add(node1);
  21         top.add(node2);
  22
  23         //JTree tree=new JTree(top);
  24         DefaultTreeModel model = new DefaultTreeModel (top);
  25         this.jTree1.setModel(model);
  26        //jTree1.getSelectionModel().setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION)
  27        //set jframe icon
  28        try
  29
  30        {
  31        Image icon= ImageIO.read(this.getClass().getResource("/images/Icon.png"));
  32        tabIcon = createImageIcon("/images/Icon.png", "tab icon");
  33
  34        this.setIconImage(icon);
  35        }
  36        catch(IOException ex)
  37        {
  38
  39            System.out.println(ex);
  40
  41        }
  42
  43     }
  在Tree的值变化事件中,通过class.forName()和 cls.newInstance()反射动态实例化窗体,代码如下:
  1     private void jTree1ValueChanged(javax.swing.event.TreeSelectionEvent evt) {
  2         // TODO add your handling code here:
  3
  4        DefaultMutableTreeNode node = (DefaultMutableTreeNode)
  jTree1.getLastSelectedPathComponent();
  5
  6         if (node == null){
  7             //Nothing is selected.
  8              return;
  9         }
  10
  11         Object nodeInfo = node.getUserObject();
  12         String item = (String) nodeInfo;
  13
  14         if (node.isLeaf()) {
  15             String item1 = (String) nodeInfo;
  16             // this.setTitle(item1);
  17             //File f = new File("client.jar");
  18             //URLClassLoader cl = new URLClassLoader(new URL[]{f.toURI().toURL(), null});
  19             //Class<?> clazz = cl.loadClass("epicurus.Client");
  20             //Method main = clazz.getMethod("main", String[].class);
  21             //main.invoke(null, new Object[]{new String[]{}});
  22             try {
  23                 Class cls = Class.forName("com.mkmis.forms.JIFrame1");
  24                 javax.swing.JInternalFrame frm =
  (javax.swing.JInternalFrame) cls.newInstance();
  25                  frm.setVisible(true);
  26
  27                 //jTabbedPane1.addTab(" "+item1+"  ",null,frm);
  28                 jTabbedPane1.addTab(" "+item1+"  ",this.tabIcon,frm);
  29
  30              }
  31              catch (Throwable e) {
  32                 System.err.println(e);
  33              }
  34         } else {
  35             System.out.println("not leaf");
  36         }
  37     }
  在javaswing中的路径也和net不同,下面定义了一个创建ImageIcon的方法:
  1     /** Returns an ImageIcon, or null if the path was invalid. */
  2     protected ImageIcon createImageIcon(String path,String description) {
  3         java.net.URL imgURL = getClass().getResource(path);
  4         if (imgURL != null) {
  5             return new ImageIcon(imgURL, description);
  6         } else {
  7             System.err.println("Couldn't find file: " + path);
  8             return null;
  9         }
  10     }