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

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

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

    zeyuphoenix

    愿我愛(ài)的人快樂(lè),愿愛(ài)我的人快樂(lè),為了這些,我愿意不快樂(lè).

    JBorder組件邊框

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

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

    對(duì)于普通的BorderJavaBorderFactory已經(jīng)滿足我們的要求了,但是如果我們需要的是特殊的Border,比如Border的標(biāo)題是一個(gè)單選框,就必須使用我們自己的類來(lái)實(shí)現(xiàn)了.這里我們可以把我們需要繪制的Border也想象成一個(gè)容器,在它的基礎(chǔ)上繪制出自己的邊緣,需要填充的組件在放置在它的上面就可以了.

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

    圖如下:

    依次創(chuàng)建了

         實(shí)現(xiàn)單色、任意厚度線邊框

    BorderFactory.createLineBorder(Color.black);

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

    BorderFactory.createEtchedBorder(EtchedBorder.RAISED);

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

    BorderFactory.createEtchedBorder(EtchedBorder.LOWERED);

         具有凸出斜面邊緣的邊框

    BorderFactory.createRaisedBevelBorder();

         具有凹入斜面邊緣的邊框

    BorderFactory.createLoweredBevelBorder();

         不占用空間的空邊框

    BorderFactory.createEmptyBorder();

          多層指定圖標(biāo)組成的、類似襯邊的邊框

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

         純色創(chuàng)建一個(gè)類似襯邊的邊框

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

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

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

         創(chuàng)建一個(gè)空標(biāo)題的新標(biāo)題邊框,使其具有指定的邊框?qū)ο蟆⒛J(rèn)的文本位置(位于頂線上)、默認(rèn)的調(diào)整 (leading),以及默認(rèn)的字體和文本顏色(由當(dāng)前外觀確定)

    BorderFactory.createTitledBorder("title");

         向現(xiàn)有邊框添加一個(gè)標(biāo)題,使其具有默認(rèn)的位置(位于頂線上)、默認(rèn)的調(diào)整 (leading),以及默認(rèn)的字體和文本顏色(由當(dāng)前外觀確定)

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

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

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

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

    然后通過(guò)Border的方法設(shè)置它們的位置和顯示屬性:

    border.setTitleJustification(TitledBorder.CENTER);

           border.setTitlePosition(TitledBorder.ABOVE_TOP);

         當(dāng)然也可以再構(gòu)造時(shí)給出這些屬性.

    向現(xiàn)有邊框添加一個(gè)標(biāo)題,使其具有指定的位置、字體和顏色

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

    創(chuàng)建一個(gè)合成邊框,指定了用于外部和內(nèi)部邊緣的 border 對(duì)象

    BorderFactory.createCompoundBorder(raisedbevel, loweredbevel);

    內(nèi)外Border可以任意組合,也可以為Null.



    接下來(lái)就是自己實(shí)現(xiàn)一個(gè)有特殊表現(xiàn)形式的Border,最基礎(chǔ)的方法是實(shí)現(xiàn)Border接口,實(shí)現(xiàn)paintBordergetBorderInsetsisBorderOpaque三個(gè)方法,這樣比較復(fù)雜,因?yàn)槲覀円薷牡氖?/span>BorderTitle,所以這里我繼承TitledBorder:

    /**

     * the title border that override it.

    */

    publicclass MyTitledBorder extends TitledBorder {

    它有一個(gè)屬性:

        /**

         * the component in the border.

         */

        protected JComponent component = null;

    代表放置在Border上的組件.

    再看它的構(gòu)造函數(shù):

        /**

         * 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上的組件傳入,并設(shè)置初始位置.

    然后是實(shí)現(xiàn)Border的部分方法,設(shè)置JComponet的位置,大小和布局等.

        /**

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

         */

        @Override

        public Insets getBorderInsets(Component c, Insets insets) {

    用此邊框的當(dāng)前 Insets 重新初始化 insets 參數(shù).

    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;

    然后在根據(jù)Border的位置設(shè)置它的準(zhǔn)確邊界:

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

    if (component != null) {

        compHeight = component.getPreferredSize().height;

    }

    然后根據(jù)位置計(jì)算邊:

    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) {

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

    先得出沒(méi)有邊框的容器的大小:

    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);

    然后根據(jù)Border上組件的位置,計(jì)算哪兒應(yīng)該加上這個(gè)大小:

    例如在下面,意味著下面的Border會(huì)寬一點(diǎn):

        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();

    最后一個(gè)方法是根據(jù)Border上組件和BorderInsets計(jì)算現(xiàn)在組件的寬度和最終組件要占據(jù)的位置大小:

        /**

         * 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);

    然后根據(jù)位置進(jìn)行換算,比如組件位于Border的下-右:

        caseBELOW_TOP:

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

    caseRIGHT:

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

                      - compR.width;

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

    接著是一個(gè)接口,用處主要是標(biāo)示Border內(nèi)的所有組件是否可用,當(dāng)然以后也可以添加新的接口:

    /**

     * set the panel enable or not.

    */

    publicinterface StateTransmitter {

    它只有一個(gè)需要實(shí)現(xiàn)的方法:

        /**

         * set panel enable.

         */

        publicvoid setChildrenEnabled(boolean enable);

    用來(lái)管理Border內(nèi)的所有組件是否可用的.

    然后是這個(gè)接口的一個(gè)簡(jiǎn)單實(shí)現(xiàn),我們所有的組建需要放置在它的上面,當(dāng)然你也可以自己實(shí)現(xiàn),只需要實(shí)現(xiàn)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 {

    它只有一個(gè)實(shí)現(xiàn)方法,其它和Jpanel相同:

        @Override

        publicvoid setChildrenEnabled(boolean enable) {

           Component[] children = this.getComponents();

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

               children[i].setEnabled(enable);

           }

        }

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

    publicclass MyTitledPane extends JPanel {

    它就是一個(gè)普通的JPanel,我們?cè)谒纳厦娣胖昧俗约憾x的特殊Border和我們以后需要放置的其他組件根容器,然后通過(guò)調(diào)整它的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;

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

    public MyTitledPane(JComponent component) {

           border = new MyTitledBorder(component);

           setBorder(border);

           panel = new JPanel();

             add(component);

           add(panel);

    設(shè)置可用與否的初始值:

           transmittingAllowed = false;

           transmitter = null;

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

        /**

         * remove old component and add new one.

         */

        publicvoid setTitleComponent(JComponent newComponent) {

           remove(component);

           add(newComponent);

           border.setTitleComponent(newComponent);

           component = newComponent;

        }

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

        @Override

        publicvoid setEnabled(boolean enable) {

           super.setEnabled(enable);

           if (transmittingAllowed && transmitter != null) {

               transmitter.setChildrenEnabled(enable);

           }

        }

    最后是重寫(xiě)JPaneldoLayout方法,使布局自適應(yīng):

        /**

         * 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;

    最后設(shè)置新的Layout的邊:

    panel.setBounds(rect);

    到此為止,一個(gè)我們自定義的特殊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 閱讀(4473) 評(píng)論(0)  編輯  收藏 所屬分類: Java基本組件的使用

    導(dǎo)航

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

    統(tǒng)計(jì)

    常用鏈接

    留言簿(52)

    隨筆分類

    隨筆檔案

    搜索

    最新評(píng)論

    閱讀排行榜

    評(píng)論排行榜

    主站蜘蛛池模板: 在线看片无码永久免费视频| 久久久高清免费视频| 成视频年人黄网站免费视频| 午夜国产大片免费观看| 亚洲图片一区二区| 国产亚洲人成在线影院| 99在线观看精品免费99| 日韩精品电影一区亚洲| 亚洲美女自拍视频| 日韩免费码中文在线观看| 亚洲免费电影网站| 亚洲一级黄色视频| 亚洲精品国产日韩| 免费国产在线视频| 俄罗斯极品美女毛片免费播放| 久久亚洲熟女cc98cm| 三级片免费观看久久| 在人线av无码免费高潮喷水| 亚洲一区二区三区香蕉| jzzijzzij在线观看亚洲熟妇| 亚洲精品免费视频| 亚洲午夜国产片在线观看| 亚洲国产视频久久| 四虎成人精品永久免费AV| 亚洲成av人片天堂网老年人| 色噜噜亚洲男人的天堂| 黄网站免费在线观看| 亚洲av无码成人精品区在线播放 | 亚洲乱码一二三四区乱码| 两个人看的www免费| 免费v片在线观看品善网| 亚洲一区二区三区无码国产 | 国产精品久久久久免费a∨| 精品久久香蕉国产线看观看亚洲| 亚洲av日韩精品久久久久久a| 亚洲免费一级视频| 亚洲AV无码不卡无码| 好猛好深好爽好硬免费视频| 国产女高清在线看免费观看| 亚洲人6666成人观看| 四虎影视成人永久免费观看视频 |