John Jiang

          a cup of Java, cheers!
          https://github.com/johnshajiang/blog

             :: 首頁 ::  :: 聯系 :: 聚合  :: 管理 ::
            131 隨筆 :: 1 文章 :: 530 評論 :: 0 Trackbacks
          構建不規則窗體
          在開發一個新浪微博Swing客戶端的過程中希望能展現不規則的窗體界面,原來JDK 6 update 10提供了創建指定形狀窗體的特性,簡單易用,記于此處。(2010.05.31最后更新)

          Java從JDK 6 update 10開始將內建支持構建指定形狀的窗體,類com.sun.awt.AWTUtilities中的方法setWindowShape會根據不同的Shape實現去構造相應形狀的窗體。AWTUtilities類是放在SUN的包中,在使用該方法時應該通過反射去進行調用,如下代碼所示,
          Class<?> clazz = Class.forName("com.sun.awt.AWTUtilities");
          Method method 
          = clazz.getMethod("setWindowShape", Window.class, Shape.class);

          1. 創建正常窗體
          先創建一個簡單的界面,它使用BorderLayout,在其中安放5個JButton,如下代碼所示,
          public class ShapedFrame extends JFrame {

              
          private static final long serialVersionUID = -2291343874280454383L;

              
          private JButton centerButton = new JButton("Center");

              
          public ShapedFrame() {
                  
          super("Shaped Frame");
                  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  initUI();
              }

              
          private void initUI() {
                  Container container 
          = getContentPane();
                  container.setLayout(
          new BorderLayout());

                  container.add(
          new JButton("TOP"), BorderLayout.PAGE_START);
                  container.add(
          new JButton("RIGHT"), BorderLayout.LINE_END);
                  container.add(
          new JButton("BOTTOM"), BorderLayout.PAGE_END);
                  container.add(
          new JButton("LEFT"), BorderLayout.LINE_START);
                  container.add(centerButton, BorderLayout.CENTER);
              }

              
          public static void main(String[] args) {
                  SwingUtilities.invokeLater(
          new Runnable() {

                      @Override
                      
          public void run() {
                          ShapedFrame frame 
          = new ShapedFrame();
                          frame.setSize(
          new Dimension(400300));
                          frame.setUndecorated(
          true);
                          setAtCenter(frame);
                          frame.setVisible(
          true);
                      }
                  });
              }

              
          // 將Window置于屏幕正中
              private static void setAtCenter(Window window) {
                  Dimension screenSize 
          = Toolkit.getDefaultToolkit().getScreenSize();
                  window.setLocation((screenSize.width 
          - window.getWidth()) / 2,
                          (screenSize.height 
          - window.getHeight()) / 2);
              }
          }

          執行上述程序的效果如下圖所示,


          2. 創建不規則窗體
          基于上述程序創建不規則窗體,使整個窗體正好缺失掉RIGHT JButton所在的區域,如下代碼所示,
          public class ShapedFrame extends JFrame {

              
          private static final long serialVersionUID = -2291343874280454383L;

              
          private static Method method = null;

              
          static {
                  
          try {
                      Class
          <?> clazz = Class.forName("com.sun.awt.AWTUtilities");
                      method 
          = clazz.getMethod("setWindowShape", Window.class, Shape.class);
                  } 
          catch (Exception e) {
                      e.printStackTrace();
                  }
              }

              
          private JButton centerButton = new JButton("Center");

              
          public ShapedFrame() {
                  
          super("Shaped Frame");
                  setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
                  initUI();
                  addComponentListener(componentListener);
              }

              
          private void initUI() {
                  Container container 
          = getContentPane();
                  container.setLayout(
          new BorderLayout());

                  container.add(
          new JButton("TOP"), BorderLayout.PAGE_START);
                  container.add(
          new JButton("RIGHT"), BorderLayout.LINE_END);
                  container.add(
          new JButton("BOTTOM"), BorderLayout.PAGE_END);
                  container.add(
          new JButton("LEFT"), BorderLayout.LINE_START);
                  container.add(centerButton, BorderLayout.CENTER);
              }

              
          private ComponentListener componentListener = new ComponentAdapter() {

                  @Override
                  
          public void componentResized(ComponentEvent evt) { // 當UI組件(JFrame)的尺寸發生改變時,調用該方法
                      Rectangle frameRect = getBounds();
                      Rectangle spaceRect 
          = centerButton.getBounds();

                      Point o1 
          = new Point(00);
                      Point o2 
          = new Point(frameRect.width, 0);
                      Point o3 
          = new Point(frameRect.width, frameRect.height);
                      Point o4 
          = new Point(0, frameRect.height);

                      Point i1 
          = new Point(spaceRect.x + spaceRect.width, spaceRect.y);
                      Point i2 
          = new Point(frameRect.width, spaceRect.y);
                      Point i3 
          = new Point(frameRect.width, spaceRect.y
                              
          + spaceRect.height);
                      Point i4 
          = new Point(spaceRect.x + spaceRect.width, spaceRect.y + spaceRect.height);

                      
          int[] xpoints = new int[] { o1.x, o2.x, i2.x, i1.x, i4.x, i3.x, o3.x, o4.x };
                      
          int[] ypoints = new int[] { o1.y, o2.y, i2.y, i1.y, i4.y, i3.y, o3.y, o4.y };
                      
          int npoints = 8
                      
          // 構建一個六邊形,將RIGHT JButton所處的位置空缺出來
                      Shape shape = new Polygon(xpoints, ypoints, npoints);

                      setWindowShape(ShapedFrame.
          this, shape);
                  }
              };

              
          // 設置Window的形狀
              private static void setWindowShape(Window window, Shape shape) {
                  
          try {
                      method.invoke(
          null, window, shape);
                  } 
          catch (Exception e) {
                      e.printStackTrace();
                  }
              }

              
          public static void main(String[] args) {
                  SwingUtilities.invokeLater(
          new Runnable() {

                      @Override
                      
          public void run() {
                          ShapedFrame frame 
          = new ShapedFrame();
                          frame.setSize(
          new Dimension(400300));
                          frame.setUndecorated(
          true);
                          setAtCenter(frame);
                          frame.setVisible(
          true);
                      }
                  });
              }

              
          // 將Window置于屏幕正中
              private static void setAtCenter(Window window) {
                  Dimension screenSize 
          = Toolkit.getDefaultToolkit().getScreenSize();
                  window.setLocation((screenSize.width 
          - window.getWidth()) / 2,
                          (screenSize.height 
          - window.getHeight()) / 2);
              }
          }

          執行上述程序后,會有如下圖所示的效果,


          posted on 2011-05-31 20:46 John Jiang 閱讀(1984) 評論(0)  編輯  收藏 所屬分類: JavaSEJavaSwingGUI原創
          主站蜘蛛池模板: 托克托县| 社旗县| 榕江县| 漳州市| 玛多县| 纳雍县| 石景山区| 汨罗市| 横山县| 周宁县| 仁怀市| 宽城| 临安市| 石狮市| 乐昌市| 石阡县| 安化县| 遵义市| 于都县| 辽宁省| 翁牛特旗| 秦皇岛市| 芮城县| 拜城县| 阳朔县| 许昌市| 辛集市| 隆昌县| 宿松县| 江孜县| 铜陵市| 临武县| 镇原县| 寻乌县| 镇平县| 高州市| 阳春市| 桑植县| 自贡市| 永登县| 华阴市|