转载

Java Swing快速构建窗体应用程序

以前接触java感觉其在桌面开发上,总是不太方便,没有一个好的拖拽界面布局工具,可以快速构建窗体. 最近学习了一下NetBeans IDE 8.1,感觉其窗体设计工具还是很不错的 , 就尝试一下做了一个窗体应用程序. 总体下来,感觉和winform开发相差也不大,只是一些具体的设置或者语法有些差异,可以通过查阅相关资料进行掌握:

1 应用结构

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

Java Swing快速构建窗体应用程序

2 登陆界面设计

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

Java Swing快速构建窗体应用程序

设计完成后,单击运行按钮,界面效果如下图所示:

Java Swing快速构建窗体应用程序

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 主界面

登录成功后,单击左边的树叶节点,通过反射动态实例化窗体(实际上菜单应该从数据库加载)并显示,主界面如下:

Java Swing快速构建窗体应用程序

图表控件用的是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     }

5 JDBC MYSQL代码

1 package com.mkmis.db;  2   3 import java.io.FileInputStream;  4 import java.io.IOException;  5 import java.sql.Connection;  6 import java.sql.DriverManager;  7 import java.sql.PreparedStatement;  8 import java.sql.ResultSet;  9 import java.sql.SQLException; 10 import java.sql.Statement; 11 import java.util.Properties; 12  13  14 public class DBConnection { 15  16     public static Connection getConnection() { 17         Properties props = new Properties(); 18         FileInputStream fis = null; 19         Connection con = null; 20         try { 21             fis = new FileInputStream("db.properties"); 22             props.load(fis); 23             // 24             Class.forName(props.getProperty("DB_DRIVER_CLASS")); 25             //  26             con = DriverManager.getConnection(props.getProperty("DB_URL"), props.getProperty("DB_USERNAME"), props.getProperty("DB_PASSWORD")); 27         } catch (IOException | SQLException | ClassNotFoundException e) { 28             e.printStackTrace(); 29         } 30         return con; 31     } 32  33     // �ر�ResultSet 34     public static void closeResultSet(ResultSet rs) { 35         if (rs != null) { 36             try { 37                 rs.close(); 38                 rs = null; 39             } catch (SQLException e) { 40                 e.printStackTrace(); 41             } 42         } 43     } 44  45     //Statement 46     public static void closeStatement(Statement stm) { 47         if (stm != null) { 48             try { 49                 stm.close(); 50                 stm = null; 51             } catch (SQLException e) { 52                 e.printStackTrace(); 53             } 54         } 55     } 56  57     //PreparedStatement 58     public static void closePreparedStatement(PreparedStatement pstm) { 59         if (pstm != null) { 60             try { 61                 pstm.close(); 62                 pstm = null; 63             } catch (SQLException e) { 64                 e.printStackTrace(); 65             } 66         } 67     } 68  69     //Connection 70     public static void closeConnection(Connection con) { 71         if (con != null) { 72             try { 73                 con.close(); 74                 con = null; 75             } catch (SQLException e) { 76                 e.printStackTrace(); 77             } 78             con = null; 79         } 80     } 81  82 }  View Code

6 图表窗体代码

1 /*   2  * To change this license header, choose License Headers in Project Properties.   3  * To change this template file, choose Tools | Templates   4  * and open the template in the editor.   5  */   6 package com.mkmis.forms;   7    8 import java.awt.Color;   9 import java.awt.Dimension;  10 import java.awt.Font;  11   12 import org.jfree.chart.ChartFactory;  13 import org.jfree.chart.ChartPanel;  14 import org.jfree.chart.JFreeChart;  15 import org.jfree.chart.StandardChartTheme;  16 import org.jfree.chart.axis.CategoryAxis;  17 import org.jfree.chart.axis.NumberAxis;  18 import org.jfree.chart.block.BlockBorder;  19 import org.jfree.chart.plot.CategoryPlot;  20 import org.jfree.chart.renderer.category.BarRenderer;  21 import org.jfree.chart.title.TextTitle;  22 import org.jfree.data.category.CategoryDataset;  23 import org.jfree.data.category.DefaultCategoryDataset;  24 //import org.jfree.ui.ApplicationFrame;  25 //import org.jfree.ui.RefineryUtilities;  26 /**  27  *  28  * @author wangming  29  */  30 public class JIFrame1 extends javax.swing.JInternalFrame {  31   32     /**  33      * Creates new form JIFrame1  34      */  35     public JIFrame1() {  36         initComponents();  37         //hiding title bar of JInternalFrame         38         ((javax.swing.plaf.basic.BasicInternalFrameUI)this.getUI()).setNorthPane(null);  39         this.setBackground(Color.white);  40           41         CategoryDataset dataset = createDataset();  42         JFreeChart chart = createChart(dataset);  43         ChartPanel chartPanel = new ChartPanel(chart);  44         chartPanel.setFillZoomRectangle(true);  45         chartPanel.setMouseWheelEnabled(true);  46         chartPanel.setPreferredSize(new Dimension(500, 270));  47         setContentPane(chartPanel);  48     }  49   50     /**  51      * This method is called from within the constructor to initialize the form.  52      * WARNING: Do NOT modify this code. The content of this method is always  53      * regenerated by the Form Editor.  54      */  55     @SuppressWarnings("unchecked")  56     // <editor-fold defaultstate="collapsed" desc="Generated Code">                            57     private void initComponents() {  58   59         setBorder(null);  60         setClosable(true);  61         setMaximizable(true);  62         setResizable(true);  63   64         javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());  65         getContentPane().setLayout(layout);  66         layout.setHorizontalGroup(  67             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  68             .addGap(0, 410, Short.MAX_VALUE)  69         );  70         layout.setVerticalGroup(  71             layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)  72             .addGap(0, 285, Short.MAX_VALUE)  73         );  74   75         pack();  76     }// </editor-fold>                          77   78         private static final long serialVersionUID = 1L;  79   80     static {  81         // set a theme using the new shadow generator feature available in  82         // 1.0.14 - for backwards compatibility it is not enabled by default  83         ChartFactory.setChartTheme(new StandardChartTheme("JFree/Shadow",  84                 true));  85     }  86   87     /**  88      * Creates a new demo instance.  89      *  90      * @param title  the frame title.  91      */  92     public JIFrame1(String title) {  93         super(title);  94         CategoryDataset dataset = createDataset();  95         JFreeChart chart = createChart(dataset);  96         ChartPanel chartPanel = new ChartPanel(chart);  97         chartPanel.setFillZoomRectangle(true);  98         chartPanel.setMouseWheelEnabled(true);  99         chartPanel.setPreferredSize(new Dimension(500, 270)); 100         setContentPane(chartPanel); 101     } 102  103     /** 104      * Returns a sample dataset. 105      * 106      * @return The dataset. 107      */ 108     private static CategoryDataset createDataset() { 109         DefaultCategoryDataset dataset = new DefaultCategoryDataset(); 110         dataset.addValue(7445, "JFreeSVG", "Warm-up"); 111         dataset.addValue(24448, "Batik", "Warm-up"); 112         dataset.addValue(4297, "JFreeSVG", "Test"); 113         dataset.addValue(21022, "Batik", "Test"); 114         return dataset; 115     } 116  117     /** 118      * Creates a sample chart. 119      * 120      * @param dataset  the dataset. 121      * 122      * @return The chart. 123      */ 124     private static JFreeChart createChart(CategoryDataset dataset) { 125         //中文乱码,设置字体 126         Font font=new Font("微软雅黑",Font.BOLD,18);//测试是可以的 127        128        129         130         131         JFreeChart chart = ChartFactory.createBarChart("性能: JFreeSVG 对比 Batik", null /* x-axis label*/,  132                 "毫秒" /* y-axis label */, dataset); 133         //中文乱码,设置字体 134         chart.getTitle().setFont(font); 135  136         chart.addSubtitle(new TextTitle("在SVG中产生1000个图表")); 137         chart.setBackgroundPaint(Color.white); 138         CategoryPlot plot = (CategoryPlot) chart.getPlot(); 139          NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis(); 140          rangeAxis.setLabelFont(font); 141  142          CategoryAxis domainAxis = plot.getDomainAxis(); 143          domainAxis.setLabelFont(font); 144         // ****************************************************************** 145         //  More than 150 demo applications are included with the JFreeChart 146         //  Developer Guide...for more information, see: 147         // 148         //  >   http://www.object-refinery.com/jfreechart/guide.html 149         // 150         // ****************************************************************** 151  152        153         rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits()); 154         BarRenderer renderer = (BarRenderer) plot.getRenderer(); 155         renderer.setDrawBarOutline(false); 156         chart.getLegend().setFrame(BlockBorder.NONE); 157         return chart; 158     } 159  160     /** 161      * Starting point for the demonstration application. 162      * 163      * @param args  ignored. 164      */ 165 //    public static void main(String[] args) { 166 //        BarChartDemo1 demo = new BarChartDemo1("JFreeChart: BarChartDemo1.java"); 167 //        demo.pack(); 168 //        RefineryUtilities.centerFrameOnScreen(demo); 169 //        demo.setVisible(true); 170 //    } 171  172     // Variables declaration - do not modify                      173     // End of variables declaration                    174 }  View Code

运行此app,一定要引入需要的库,mysql jdbc驱动和jfreechart库

Java Swing快速构建窗体应用程序

正文到此结束
Loading...