Java Swing快速構建窗體應用程序


  以前接觸java感覺其在桌面開發上,總是不太方便,沒有一個好的拖拽界面布局工具,可以快速構建窗體. 最近學習了一下NetBeans IDE 8.1,感覺其窗體設計工具還是很不錯的 , 就嘗試一下做了一個窗體應用程序. 總體下來,感覺和winform開發相差也不大,只是一些具體的設置或者語法有些差異,可以通過查閱相關資料進行掌握:

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     }

 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庫

 
 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM