当前位置: 代码迷 >> 综合 >> JavaGUI-Swing
  详细解决方案

JavaGUI-Swing

热度:67   发布时间:2024-01-21 04:02:55.0

JavaGUI-Swing

sf2gis@163.com

2015年12月31日

 

1  目标:针对JVM重写AWT,减少对OS的依赖。

2 原理:使用Java重写AWT组件,模拟各个组件,减少对OS的依赖,使各平台都具有相同外观。

Swing继承AWT的事件机制、基础容器、布局,在容器中针对JVM编程,模拟不同平台的组件,实现所有平台的组件一致性,减少了平台依赖(基本容器各平台基本相同,但依然有依赖),但这需要更多的内存,速度会减慢。

Swing在AWT的基础上重写了所有的组件(在原组件的名字前加上J前缀(果然是Java的亲儿子)),扩展了原有的组件和形式(UIManager)。

AWT使用方法参见:JavaGUI-AWT.docx

3 流程:创建组件,设置布局,添加监听对象

3.1 创建组件:在AWT的组件名前加J,就是Swing重写的组件

           JFrame f=new JFrame();

3.2 设置布局:使用AWT相同的布局。

3.3 添加监听对象:使用AWT相同的事件机制。

3.4 示例

参考:http://blog.csdn.net/aeolus1019/article/details/7980950

 

 

/**

 * Demo

 */

package lee;

 

importjava.awt.BorderLayout;

importjava.awt.event.ActionEvent;

importjava.awt.event.ActionListener;

 

importjavax.swing.JButton;

importjavax.swing.JFrame;

 

/**

 * @author sf2gis@163.com

 *

 */

public class Main{

      /**

       *@param args

       */

      public static void main(String[] args) {

           // TODO Auto-generated method stub

           JFrame f=new JFrame();

           f.setLayout(new BorderLayout());

           f.setBounds(30,30,200,200);

           f.setVisible(true);

           f.setTitle("Hello,World!");

          

          

           JButton btn1=newJButton("btn1");

           f.add(btn1,BorderLayout.NORTH);

           btn1.addActionListener(new ActionListener() {

                

                 @Override

                 public voidactionPerformed(ActionEvent e) {

                      // TODO Auto-generatedmethod stub

                      System.out.println("btn1,click");

                 }

           });

           f.pack();

      }

}

4 方法:外观风格UIManager

4.1 目标:控制组件的外观风格。

4.2 原理:由于Swing全部使用Java模拟了所有平台的组件,因此外观控制变得方便。使用UIManager控制组件的外观,可以使用不同的外观对象为组件设置外观。

4.3 流程:设置外观,更新外观。

4.3.1设置外观:UIManager.SetLookAndFeel()。

                                  UIManager.setLookAndFeel(newMetalLookAndFeel());

                                  UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

4.3.2更新外观:SwingUtilities.updateComponentTreeUI(组件)。

                      SwingUtilities.updateComponentTreeUI(f);

4.3.3示例:Swing外观风格

参考:http://tieba.baidu.com/p/1607650603

//Main.java

/**

 * Demo

 */

package lee;

 

import java.awt.*;

importjava.awt.event.*;

 

importjavax.swing.*;

importjavax.swing.event.*;

importjavax.swing.plaf.metal.MetalLookAndFeel;

importjavax.swing.plaf.nimbus.NimbusLookAndFeel;

 

/**

 * @author sf2gis@163.com

 *

 */

public class Main{

      static int laf;

 

      /**

       *@param args

       */

      public static void main(String[] args)

                 throwsUnsupportedLookAndFeelException {

           // TODO Auto-generated method stub

           //ew SwingComponent().init();

           final JFrame f = new JFrame();

           f.setLayout(new FlowLayout());

           f.setBounds(30, 30, 200, 200);

           f.setVisible(true);

           f.setTitle("Hello,World!");

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

                

           //get laf

           for(UIManager.LookAndFeelInfoinfo:UIManager.getInstalledLookAndFeels()){

                 System.out.println(info.getName()+"="+info);

           }

          

           //view laf

           JButton btn1 = newJButton("btn1");

           f.add(btn1);

           JCheckBox cb = newJCheckBox("cb");

           f.add(cb);

           JComboBox<String> combo = newJComboBox<>(new String[]{"aa","bb","cc"});

           f.add(combo);

 

           btn1.addActionListener(newActionListener() {

                 @Override

                 public voidactionPerformed(ActionEvent e) {

                      // TODO Auto-generatedmethod stub

                      try {

                            switch (laf) {

                            case 0:

                                  UIManager.setLookAndFeel(newMetalLookAndFeel());

                                  break;

                            case 1:

                                  UIManager.setLookAndFeel(newNimbusLookAndFeel());

                                  break;

                            case 2:

                                  UIManager.setLookAndFeel("com.sun.java.swing.plaf.motif.MotifLookAndFeel");

                                  break;

                            case 3:

                                  UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");

                                  break;

                            case 4:

                                  UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsClassicLookAndFeel");

                                  break;

                            default:

                                  break;

                            }

                      } catch (UnsupportedLookAndFeelException| ClassNotFoundException | InstantiationException | IllegalAccessException e1){

                            // TODOAuto-generated catch block

                            e1.printStackTrace();

                      }

                      SwingUtilities.updateComponentTreeUI(f);

                      System.out.println(laf++);

                      if(5==laf){

                            laf=0;

                      }

                 }

           });

           f.pack();

      }

}

5 方法:常用组件

5.1 组织结构:AWT的派生增强版,但是结构改变

Object:基类

-|Container:容器

--|Window

---|JWindow

---|JDialog

---|Frame

--|Panel

--|JComponent:基本组件

---|JButton等具体组件

---|JMenuBar:菜单栏

参考:http://blog.sina.com.cn/s/blog_90b03d9201015v05.html

5.2 容器:AWT增强版。

5.2.1关闭按钮自动退出程序:f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

5.3 布局管理器:AWT的扩展。

保留原有的布局,增加了BoxLayout。

5.3.1.1  BoxLayout:GridBagLayout的简化版本。

//Main.java

/**

 * Demo

 */

package lee;

 

importjava.awt.BorderLayout;

importjava.awt.Button;

importjava.awt.CardLayout;

importjava.awt.FlowLayout;

importjava.awt.Frame;

 

import javax.swing.Box;

import javax.swing.BoxLayout;

 

/**

 * @author sf2gis@163.com

 *

 */

public class Main{

 

      /**

       *@param args

       */

      public static void main(String[] args) {

           // TODO Auto-generated method stub

           Frame f=new Frame();

           f.setLayout(new BorderLayout());

           f.setBounds(30,30,200,200);

           f.setVisible(true);

           f.setTitle("Hello,World!");

           Box hori=Box.createHorizontalBox();

           hori.add(new Button("1"));

           f.add(hori,BorderLayout.NORTH);

           Box ver=Box.createVerticalBox();

           ver.add(new Button("2"));

           f.add(ver,BorderLayout.WEST);

           Box ver2=Box.createVerticalBox();

           ver2.add(new Button("3"));

           ver2.add(new Button("4"));

           ver2.add(new Button("5"));

           f.add(ver2,BorderLayout.CENTER);

           f.pack();

      }

 

}

5.4 事件机制:使用Action扩展Listener,抽象一个动作(不仅仅是响应函数)。

5.4.1目标:抽象的动作,具有快捷键,助记符等,图标等属性,能够执行相关的动作。

5.4.2原理:扩展Listener,将原先的响应函数抽象为一个具体的动作,增加快捷键,助记符等属性和相应的动作。

Action是ActionListener的子接口,一般使用Action的实现类AbstractAction(具有默认实现)作为直接基类。

5.4.3流程:创建Action的子类,设置Action对象属性,设置组件的Action

5.4.3.1  创建AbstractAction的子类:实现ActionPerformed。

class MyAction extends AbstractAction{

 

      @Override

      public void actionPerformed(ActionEvent e) {

           // TODO Auto-generated method stub

           System.out.println("MyAction1");

      }

5.4.3.2  设置Action的对象属性:

           mya.putValue(Action.NAME,"xx");

           mya.putValue(Action.SHORT_DESCRIPTION,"short_xx");

           mya.putValue(Action.LONG_DESCRIPTION,"long_xx");

           mya.putValue(Action.ACCELERATOR_KEY,KeyStroke.getKeyStroke('B',InputEvent.CTRL_MASK));

           mya.putValue(Action.MNEMONIC_KEY,KeyEvent.VK_A);

           mya.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY,1);

5.4.3.3  设置组件的Action:

           btn1.setAction(mya);

5.4.3.4  示例

//Main.java

/**

 * Demo

 */

package lee;

 

import java.awt.*;

importjava.awt.event.*;

importjava.beans.PropertyChangeListener;

 

importjavax.swing.*;

 

/**

 * @author sf2gis@163.com

 *

 */

public class Main{

      static int laf;

 

      /**

       *@param args

       */

      public static void main(String[] args)

                 throwsUnsupportedLookAndFeelException {

           // TODO Auto-generated method stub

           //ew SwingComponent().init();

           final JFrame f = new JFrame();

           f.setLayout(new FlowLayout());

           f.setBounds(30, 30, 200, 200);

           f.setVisible(true);

           f.setTitle("Hello,World!");

           f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

          

           JButton btn1=new JButton();

           f.add(btn1);

           MyAction mya=new MyAction();

           btn1.setAction(mya);

           mya.putValue(Action.NAME,"xx");

           mya.putValue(Action.SHORT_DESCRIPTION,"short_xx");

           mya.putValue(Action.LONG_DESCRIPTION,"long_xx");

           mya.putValue(Action.ACCELERATOR_KEY,KeyStroke.getKeyStroke('B',InputEvent.CTRL_MASK));

           mya.putValue(Action.MNEMONIC_KEY,KeyEvent.VK_A);

           mya.putValue(Action.DISPLAYED_MNEMONIC_INDEX_KEY,1);

           JButton btn2=new JButton();

           f.add(btn2);

           btn2.setAction(mya);

          

           //menu

           JMenuBar mb = new JMenuBar();

           f.setJMenuBar(mb);

           JMenu m = newJMenu("File");

           mb.add(m);

           JMenuItem miOpen = new JMenuItem();

           m.add(miOpen);

           miOpen.setAction(mya);

          

           f.pack();

      }

}

 

class MyAction extends AbstractAction{

 

      @Override

      public void actionPerformed(ActionEvent e) {

           // TODO Auto-generated method stub

           System.out.println("MyAction1");

      }

     

}

5.4.4方法:监听属性变化、设置快捷键等属性。

 

标签Name:用于设置Button或Menu的文本。,

快捷键:菜单时使用ACCELERATOR_KEY(CTRL+KEY),按钮时使用NMEMINC_KEY(ALT+KEY)。

快捷键助记符:显示NAME的第N(从0开始)个字符作为快捷键符。

Tooltip:SHORT_DESCRIPTION,鼠标悬浮时显示的文字。

5.5 菜单:AWT增强版

5.5.1结构:AWT相同的树形结构。

5.5.2菜单快捷键:使用menuitem.setAccelerator(KeyStroke.getKeyStroke())设置。

5.5.3示例

//main.java

f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

 

/**

 * Demo

 */

package lee;

 

import java.awt.*;

importjava.awt.event.*;

 

importjavax.swing.*;

 

/**

 * @author sf2gis@163.com

 *

 */

public class Main{

      static int laf;

 

      /**

       *@param args

       */

      public static void main(String[] args)

                 throwsUnsupportedLookAndFeelException {

           // TODO Auto-generated method stub

           //ew SwingComponent().init();

           final JFrame f = new JFrame();

           f.setLayout(new FlowLayout());

           f.setBounds(30, 30, 200, 200);

           f.setVisible(true);

           f.setTitle("Hello,World!");

           f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

          

           JMenuBar mb = new JMenuBar();

           f.setJMenuBar(mb);

           JMenu m = newJMenu("File");

           mb.add(m);

           JMenuItem miOpen = newJMenuItem("Open");

           m.add(miOpen);

           miOpen.setAccelerator(KeyStroke.getKeyStroke('O',InputEvent.CTRL_MASK));

           miOpen.addActionListener(newActionListener() {

                

                 @Override

                 public voidactionPerformed(ActionEvent e) {

                      // TODO Auto-generatedmethod stub

                      System.out.println("Open");

                 }

           });

           f.pack();

      }

}

5.6 工具条:

5.7 示例参见http://blog.csdn.net/aeolus1019/article/details/7980950

6 方法:2D绘图

6.1 目标:绘制2D图形。

6.2 原理:AWT的升级版本,直接对组件绘制(不再使用单独的Canvas对象),默认使用双缓冲,分步绘制(双缓冲-》本身-》边框-》子组件)。

paint()实现双缓冲,并实现对组件本身(paintComponent()),边框(paintBorder()),子组件(paintChildren())的顺序调用。所以一般重写paintComponent()进行组件重绘,重写paint()将破坏双缓冲,并有可能错误使用三个绘制函数。

参考:http://bbs.csdn.net/topics/390585720、Swing源码

6.3 流程:创建组件子类,重写paintComponent,向容器添加组件对象。

6.3.1创建组件子类,重写paintComponet()。

class MyPanel extends JPanel{

      @Override

      protected void paintComponent(Graphics g) {

           // TODO Auto-generated method stub

           g.drawOval(0, 0, 100, 100);

           g.drawString("abc", 50,50);

           System.out.println("xx");

      }

6.3.2向容器添加组件对象

           MyPanel p = new MyPanel();

           p.setBounds(0, 0, 100, 100);

           p.setLayout(null);

           JButton btn1 = newJButton("xx");

           btn1.setBounds(50, 0, 50, 30);

           p.add(btn1);

           JButton btn2 = newJButton("xx");

           btn2.setBounds(0, 70, 50, 30);

           p.add(btn2);

           f.add(p);

6.3.3示例

//Main.java

package lee;

 

importjava.awt.Graphics;

 

importjavax.swing.JButton;

importjavax.swing.JFrame;

importjavax.swing.JPanel;

 

public class Main{

      public static void main(String[] args) {

           // TODO Auto-generated method stub

           JFrame f=new JFrame();

           f.setBounds(0, 0, 200, 200);

           f.setTitle("Hello,World!");

           f.setVisible(true);

           f.setLayout(null);

           f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

          

           MyPanel p = new MyPanel();

           p.setBounds(0, 0, 100, 100);

           p.setLayout(null);

           JButton btn1 = newJButton("xx");

           btn1.setBounds(50, 0, 50, 30);

           p.add(btn1);

           JButton btn2 = newJButton("xx");

           btn2.setBounds(0, 70, 50, 30);

           p.add(btn2);

           f.add(p);

      }

}

 

class MyPanel extends JPanel{

      @Override

      protected void paintComponent(Graphics g) {

           // TODO Auto-generated method stub

           g.drawOval(0, 0, 100, 100);

           g.drawString("abc", 50,50);

           System.out.println("xx");

      }

     

}

6.4 升级的画笔Graphics2D:扩展Graphics,提供更加细致和优化的控制。

参考:http://blog.csdn.net/caixiexin/article/details/6626772

http://akalius.iteye.com/blog/155207

http://www.xuebuyuan.com/447206.html

可以绘制2D图形,抗锯齿等。

使用时由Graphics转换得到。

示例

//Main.java

package lee;

 

importjava.awt.Graphics;

importjava.awt.Graphics2D;

importjava.awt.RenderingHints;

importjava.awt.geom.Rectangle2D;

 

importjavax.swing.JButton;

importjavax.swing.JFrame;

importjavax.swing.JPanel;

 

public class Main{

      public static void main(String[] args) {

           // TODO Auto-generated method stub

           JFrame f=new JFrame();

           f.setBounds(0, 0, 200, 200);

           f.setTitle("Hello,World!");

           f.setVisible(true);

           f.setLayout(null);

           f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

          

           MyPanel p = new MyPanel();

           p.setBounds(0, 0, 100, 100);

           p.setLayout(null);

           JButton btn1 = newJButton("xx");

           btn1.setBounds(50, 0, 50, 30);

           p.add(btn1);

           JButton btn2 = newJButton("xx");

           btn2.setBounds(0, 70, 50, 30);

           p.add(btn2);

           f.add(p);

      }

}

 

class MyPanelextends JPanel{

      @Override

      protected void paintComponent(Graphics g){

           // TODO Auto-generated method stub

           Graphics2D g2d = (Graphics2D)g;

           g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);

           g2d.drawOval(0, 0, 100, 100);

           g2d.drawString("abc", 50,50);

           Rectangle2D.Float rect=new Rectangle2D.Float(20, 20, 50,50);

           g2d.draw(rect);

           System.out.println("xx");

      }

}

7 示例