<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    zeyuphoenix

    愿我愛的人快樂,愿愛我的人快樂,為了這些,我愿意不快樂.

    JBorder組件邊框

    JavaBorder是用來呈現圍繞Swing組件邊緣邊框的對象,它本身是一個接口,里面定義了paintBordergetBorderInsetsisBorderOpaque三個需要實現的方法.如果想用自己的Border類來繪制組件的邊框,必須實現這三個方法,里面有很多布局和繪制的問題,比較麻煩.

    Java為了方便使用,提供了虛擬類AbstractBorder,繼承它就可以比較簡單的實現自己的邊框了,但還是有布局和重繪以及組件位置的問題需要自己實現,為此Java又提供了EmptyBorderCompoundBorderEtchedBorderLineBorderMatteBorderTitledBorder為我們可以使用的大部分Border提供了實現,并且創立了工廠類BorderFactory為各種Border實現提供實例.

    對于普通的BorderJavaBorderFactory已經滿足我們的要求了,但是如果我們需要的是特殊的Border,比如Border的標題是一個單選框,就必須使用我們自己的類來實現了.這里我們可以把我們需要繪制的Border也想象成一個容器,在它的基礎上繪制出自己的邊緣,需要填充的組件在放置在它的上面就可以了.

    先看比較簡單的例子,Sun官方給出了使用的普通例子:

    圖如下:

    依次創建了

         實現單色、任意厚度線邊框

    BorderFactory.createLineBorder(Color.black);

         具有浮雕化外觀效果的邊框(效果為凸起)

    BorderFactory.createEtchedBorder(EtchedBorder.RAISED);

         具有浮雕化外觀效果的邊框(效果為凹陷)

    BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);

         具有凸出斜面邊緣的邊框

    BorderFactory.createRaisedBevelBorder();

         具有凹入斜面邊緣的邊框

    BorderFactory.createLoweredBevelBorder();

         不占用空間的空邊框

    BorderFactory.createEmptyBorder();

          多層指定圖標組成的、類似襯邊的邊框

    BorderFactory.createMatteBorder(-1, -1, -1, -1, icon)

         純色創建一個類似襯邊的邊框

    BorderFactory.createMatteBorder(1, 5, 1, 1, Color.red);

         多層指定圖標組成的、類似襯邊的邊框(只有一個邊有框)

    BorderFactory.createMatteBorder(0, 20, 0, 0, icon);

         創建一個空標題的新標題邊框,使其具有指定的邊框對象、默認的文本位置(位于頂線上)、默認的調整 (leading),以及默認的字體和文本顏色(由當前外觀確定)

    BorderFactory.createTitledBorder("title");

         向現有邊框添加一個標題,使其具有默認的位置(位于頂線上)、默認的調整 (leading),以及默認的字體和文本顏色(由當前外觀確定)

    BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "title");

    BorderFactory.createTitledBorder(BorderFactory.createEtchedBorder(EtchedBorder.LOWERED), "title");

    BorderFactory.createTitledBorder(BorderFactory.createLoweredBevelBorder(), "title");

    BorderFactory.createTitledBorder(BorderFactory.createEmptyBorder(), "title");

    然后通過Border的方法設置它們的位置和顯示屬性:

    border.setTitleJustification(TitledBorder.CENTER);

           border.setTitlePosition(TitledBorder.ABOVE_TOP);

         當然也可以再構造時給出這些屬性.

    向現有邊框添加一個標題,使其具有指定的位置、字體和顏色

    BorderFactory.createTitledBorder(BorderFactory.createLineBorder(Color.black), "title", TitledBorder.CENTER, TitledBorder.ABOVE_TOP, new Font("宋體", Font.BOLD, 12);,Color.Red);

    創建一個合成邊框,指定了用于外部和內部邊緣的 border 對象

    BorderFactory.createCompoundBorder(raisedbevel, loweredbevel);

    內外Border可以任意組合,也可以為Null.



    接下來就是自己實現一個有特殊表現形式的Border,最基礎的方法是實現Border接口,實現paintBordergetBorderInsetsisBorderOpaque三個方法,這樣比較復雜,因為我們要修改的是BorderTitle,所以這里我繼承TitledBorder:

    /**

     * the title border that override it.

    */

    publicclass MyTitledBorder extends TitledBorder {

    它有一個屬性:

        /**

         * the component in the border.

         */

        protected JComponent component = null;

    代表放置在Border上的組件.

    再看它的構造函數:

        /**

         * Creates a TitledBorder instance.

         */

        public MyTitledBorder(JComponent component) {

           this(null, component, LEFT, TOP);

        }

        public MyTitledBorder(Border border, JComponent component,

               int titleJustification, int titlePosition) {

     super(border, null, titleJustification, titlePosition, null, null);

           this.component = component;

           if (border == null) {

               this.border = super.getBorder();

           }

        }

    它把Border上的組件傳入,并設置初始位置.

    然后是實現Border的部分方法,設置JComponet的位置,大小和布局等.

        /**

         * Reinitialize the insets parameter with this Border's current Insets.

         */

        @Override

        public Insets getBorderInsets(Component c, Insets insets) {

    用此邊框的當前 Insets 重新初始化 insets 參數.

    insets.top = EDGE_SPACING + TEXT_SPACING + borderInsets.top;

    insets.right = EDGE_SPACING + TEXT_SPACING + borderInsets.right;

    insets.bottom = EDGE_SPACING + TEXT_SPACING + borderInsets.bottom;

    insets.left = EDGE_SPACING + TEXT_SPACING + borderInsets.left;

    然后在根據Border的位置設置它的準確邊界:

    先是得出Border上組件的大小:

    if (component != null) {

        compHeight = component.getPreferredSize().height;

    }

    然后根據位置計算邊:

    caseBELOW_TOP:

        insets.top += compHeight + TEXT_SPACING;

    然后是

        /**

         * Paints the border for the specified component with the specified * position  and size.

         */

        @Override

       publicvoid paintBorder(Component c, Graphics g, int x, int y, int width, int height) {

    按照指定的位置和大小為指定的組件繪制邊框.

    先得出沒有邊框的容器的大小:

    Rectangle borderR = new Rectangle(x + EDGE_SPACING, y + EDGE_SPACING,

        width - (EDGE_SPACING * 2), height - (EDGE_SPACING * 2));

    然后得出邊框的大小和邊框上組件的大小:

    Insets insets = getBorderInsets(c);

    Rectangle compR = getComponentRect(rect, insets);

    然后根據Border上組件的位置,計算哪兒應該加上這個大小:

    例如在下面,意味著下面的Border會寬一點:

        caseBOTTOM:

               diff = insets.bottom / 2 - borderInsets.bottom - EDGE_SPACING;

               borderR.height -= diff;

    最后是繪制:

    border.paintBorder(c, g, borderR.x, borderR.y, borderR.width,

                  borderR.height);

           Color col = g.getColor();

           g.setColor(c.getBackground());

           g.fillRect(compR.x, compR.y, compR.width, compR.height);

           g.setColor(col);

           component.repaint();

    最后一個方法是根據Border上組件和BorderInsets計算現在組件的寬度和最終組件要占據的位置大小:

        /**

         * get component Rectangle.

         */

    public Rectangle getComponentRect(Rectangle rect, Insets borderInsets) {

    先得出不算BoderInsets組件的大小:

    Dimension compD = component.getPreferredSize();

    Rectangle compR = new Rectangle(0, 0, compD.width, compD.height);

    然后根據位置進行換算,比如組件位于Border的下-右:

        caseBELOW_TOP:

               compR.y = borderInsets.top - compD.height - TEXT_SPACING;

    caseRIGHT:

               compR.x = rect.width - borderInsets.right - TEXT_INSET_H

                      - compR.width;

    最后把算好的compR返回就可以了.

    接著是一個接口,用處主要是標示Border內的所有組件是否可用,當然以后也可以添加新的接口:

    /**

     * set the panel enable or not.

    */

    publicinterface StateTransmitter {

    它只有一個需要實現的方法:

        /**

         * set panel enable.

         */

        publicvoid setChildrenEnabled(boolean enable);

    用來管理Border內的所有組件是否可用的.

    然后是這個接口的一個簡單實現,我們所有的組建需要放置在它的上面,當然你也可以自己實現,只需要實現StateTransmitter接口就可以了:

    /**

     * the panel that you can override it.<br>

     * if you want your panel title can change the panel state,you must override

    */

    publicclass MyPanel extends JPanel implements StateTransmitter {

    它只有一個實現方法,其它和Jpanel相同:

        @Override

        publicvoid setChildrenEnabled(boolean enable) {

           Component[] children = this.getComponents();

           for (int i = 0; i < children.length; i++) {

               children[i].setEnabled(enable);

           }

        }

    最后就是把自己寫好的MyTitledBorder類放置到指定JPanel組合成最終我們可以使用的特殊Border類了.

    publicclass MyTitledPane extends JPanel {

    它就是一個普通的JPanel,我們在它的上面放置了自己定義的特殊Border和我們以后需要放置的其他組件根容器,然后通過調整它的doLayout方法和setEnabled方法使它滿足我們的要求.

    它的屬性如下:

        /**

         * panel border.

         */

        private MyTitledBorder border = null;

        /**

         * the component in the title pane.

         */

        private JComponent component = null;

        /**

         * the title pane.

         */

        private JPanel panel = null;

        /**

         * is enable allow.

         */

        privatebooleantransmittingAllowed = false;

        /**

         * enable or not.

         */

        private StateTransmitter transmitter = null;

    然后是它的構造函數,在構造函數里我們需要初始化我的定制的特殊的Border和可以放置其它組件的根容器.

    public MyTitledPane(JComponent component) {

           border = new MyTitledBorder(component);

           setBorder(border);

           panel = new JPanel();

             add(component);

           add(panel);

    設置可用與否的初始值:

           transmittingAllowed = false;

           transmitter = null;

    然后提供一個可以換Border上容器的方法:

        /**

         * remove old component and add new one.

         */

        publicvoid setTitleComponent(JComponent newComponent) {

           remove(component);

           add(newComponent);

           border.setTitleComponent(newComponent);

           component = newComponent;

        }

    接著重寫JPanelsetEnabled方法使它的子組件也不可用:

        @Override

        publicvoid setEnabled(boolean enable) {

           super.setEnabled(enable);

           if (transmittingAllowed && transmitter != null) {

               transmitter.setChildrenEnabled(enable);

           }

        }

    最后是重寫JPaneldoLayout方法,使布局自適應:

        /**

         * reset the pane layout.

         */

        @Override

        publicvoid doLayout() {

    先取得它的邊:

    Rectangle rect = getBounds();

    再去的Border的邊:

           Rectangle compR = border.getComponentRect(rect, insets);

           component.setBounds(compR);

    兩者去做合并:

           rect.x += insets.left;

           rect.y += insets.top;

           rect.width -= insets.left + insets.right;

           rect.height -= insets.top + insets.bottom;

    最后設置新的Layout的邊:

    panel.setBounds(rect);

    到此為止,一個我們自定義的特殊Border就完成了,我們可以如下使用它:

    final MyTitledPane mypane = new MyTitledPane(mycheBox);

    然后定義我們的JPanel,把它放置在Bordr面板上.

        MyPanel userPanel = new MyPanel();

        userPanel.add(new JButton("you add"));

        mypane.setTransmittingAllowed(true);

        mypane.setTransmitter(userPanel);

        mypane.getContentPane().add(userPanel);

    到此完成.

    posted on 2010-05-04 22:52 zeyuphoenix 閱讀(4481) 評論(0)  編輯  收藏 所屬分類: Java基本組件的使用

    導航

    <2010年5月>
    2526272829301
    2345678
    9101112131415
    16171819202122
    23242526272829
    303112345

    統計

    常用鏈接

    留言簿(52)

    隨筆分類

    隨筆檔案

    搜索

    最新評論

    閱讀排行榜

    評論排行榜

    主站蜘蛛池模板: 免费看黄网站在线看| 亚洲香蕉网久久综合影视| 亚洲欧洲日韩综合| 91av免费观看| 亚洲毛片在线免费观看| 最近中文字幕免费完整| 亚洲国产福利精品一区二区| 四虎在线免费视频| 亚洲欧洲日韩极速播放| 日本免费人成黄页在线观看视频| 色五月五月丁香亚洲综合网| 免费国内精品久久久久影院| 亚洲AV日韩AV一区二区三曲| 无码不卡亚洲成?人片| 日本激情猛烈在线看免费观看| 亚洲精品国产自在久久| 久久一区二区免费播放| 亚洲AV成人片色在线观看| 亚洲啪啪免费视频| 亚洲乱码日产精品一二三| 亚洲精品在线播放视频| 无码少妇一区二区浪潮免费| 日本亚洲高清乱码中文在线观看| 国产zzjjzzjj视频全免费 | 好吊色永久免费视频大全| 国产亚洲精品一品区99热| 成人免费视频网站www| 风间由美在线亚洲一区| 亚洲精品亚洲人成在线观看| 18pao国产成视频永久免费| 亚洲国产欧洲综合997久久| 久久亚洲av无码精品浪潮| 在线免费观看你懂的| 精品亚洲成A人在线观看青青| 亚洲人成网亚洲欧洲无码久久| 国产精品成人免费福利| 免费一级做a爰片久久毛片潮| 99ri精品国产亚洲| 深夜国产福利99亚洲视频| 久久久久久精品免费看SSS| 日韩毛片在线免费观看|