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

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

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

    java something

    不要以為......很遙遠
    隨筆 - 23, 文章 - 1, 評論 - 2, 引用 - 0
    數據加載中……

    GridBagLayout

    下面的是這個界面的一個原始草圖:

     

    正如你所看到的,最終的結果看上去和計劃的想法完全一樣。

         你應該能看到在草圖里有一些線,這些線是用來把總界面分成若干行和列的,這樣你就很清楚每一個組件放置的格子位置。這就是GridBagLayout里"格"的那一部分,而圖上的數字就是格的號碼。

    在某種意義上說, 我們可以把GridBagLayout想象成為早些年的HTML3和4,它們都是基于表的布局,Grid的概念就類似rowspan和colspan的意思,只不過換了個名字罷了。

    隨著我們的界面和表格的設置完成,是時候該進行界面布局并開始寫代碼了。

    工作過程

    這一節我假定你已經了解了基本的窗口和組件創建知識。

    通過這篇文章我們最終能在一個frame中布局組件,我們將在以后的文章對界面進行改進使它更適用。因此,為了了解這整個工作的過程,我們列出了所有的目標代碼。

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class GridBagWindow extends JFrame {
    private JButton searchBtn;
    private JComboBox modeCombo;
    private JLabel tagLbl;
    private JLabel tagModeLbl;
    private JLabel previewLbl;
    private JTable resTable;
    private JTextField tagTxt;
    public GridBagWindow() {
    Container contentPane = getContentPane();
    GridBagLayout gridbag = new GridBagLayout();
    contentPane.setLayout(gridbag);
    GridBagConstraints c = new GridBagConstraints();
    //setting a default constraint value
    c.fill =GridBagConstraints.HORIZONTAL;
    tagLbl = new JLabel("Tags");
    c.gridx = 0; //x grid position
    c.gridy = 0; //y grid position
    gridbag.setConstraints(tagLbl, c); //associate the label with a constraint object
    contentPane.add(tagLbl); //add it to content pane
    tagModeLbl = new JLabel("Tag Mode");
    c.gridx = 0;
    c.gridy = 1;
    gridbag.setConstraints(tagModeLbl, c);
    contentPane.add(tagModeLbl);
    tagTxt = new JTextField("plinth");
    c.gridx = 1;
    c.gridy = 0;
    c.gridwidth = 2;
    gridbag.setConstraints(tagTxt, c);
    contentPane.add(tagTxt);
    String[] options = {"all", "any"};
    modeCombo = new JComboBox(options);
    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    gridbag.setConstraints(modeCombo, c);
    contentPane.add(modeCombo);
    searchBtn = new JButton("Search");
    c.gridx = 1;
    c.gridy = 2;
    gridbag.setConstraints(searchBtn, c);
    contentPane.add(searchBtn);
    resTable = new JTable(5,3);
    c.gridx = 0;
    c.gridy = 3;
    c.gridwidth = 3;
    gridbag.setConstraints(resTable, c);
    contentPane.add(resTable);
    previewLbl = new JLabel("Preview goes here");
    c.gridx = 0;
    c.gridy = 4;
    gridbag.setConstraints(previewLbl, c);
    contentPane.add(previewLbl);
    addWindowListener(new WindowAdapter() {
    public void windowClosing(WindowEvent e) {
    System.exit(0);
    }
    });
    }
    public static void main(String args[]) {
    GridBagWindow window = new GridBagWindow();
    window.setTitle("GridBagWindow");
    window.pack();
    window.setVisible(true);
    }
    }

     

    構造方法前的代碼都不是很特殊,都是一些相當標準的import和變量定義。但是進入構造方法后,事情就變得有趣了。

    Container contentPane = getContentPane();

    GridBagLayout gridbag = new GridBagLayout();

    contentPane.setLayout(gridbag);

         我們以GridBagWindow的內容面板作為開始來創建一個GridBagLayout對象,準確地說,這個方法與過去我們所創建 GridLayout對象和BorderLayout對象的方法是一樣的。那么,現在我們就開始來設置GridBagLayout對象使它作為內容面板的 布局。

    GridBagConstraints c = new GridBagConstraints();

         然后我要提到這整個進程中的一個獨特的對象,那就是GridBagConstraints。這個對象在GridBagLayout中控制所 有被安置在其中組件的約束。為了把一個組件增加到你的GridBagLayout中去,你首先必須將它與一個GridBagConstraints對象建 立連接。

    GridBagConstraints可以從11個方面來進行控制和操縱,也可以給你提供一些幫助。這些內容是:

    • Gridx——組件的橫向坐標
    • Girdy——組件的縱向坐標
    • Gridwidth——組件的橫向寬度,也就是指組件占用的列數,這與HTML的colspan類似
    • Gridheight——組件的縱向長度,也就是指組件占用的行數,這與HTML的rowspan類似
    • Weightx——指行的權重,告訴布局管理器如何分配額外的水平空間
    • Weighty——指列的權重,告訴布局管理器如何分配額外的垂直空間
    • Anchor——告訴布局管理器組件在表格空間中的位置
    • Fill——如果顯示區域比組件的區域大的時候,可以用來控制組件的行為。控制組件是垂直填充,還是水平填充,或者兩個方向一起填充
    • Insets——指組件與表格空間四周邊緣的空白區域的大小
    • Ipadx—— 組件間的橫向間距,組件的寬度就是這個組件的最小寬度加上ipadx值
    • ipady—— 組件間的縱向間距,組件的高度就是這個組件的最小高度加上ipady值

         可能對于一個組件的每一個實例你都需要為它建立一個單獨的GridBagConstraints;然而,這種方法我們并不推薦使用。最好的方法是,當你調用它的時候把對象設置為默認值,然后針對于每一個組件改變其相應的域。

         這個方法具有通用性,因為在一些域中,比如insets、padx、pady和fill這些域,對于每一個組件來說一般都是相同的,因此這樣對一個域進行設置就會更輕松了,也能更輕松的在另外的組件中改變某些域的值。

         如果在改變了某些域值之后,你想回到原始的域值的話,你應該在增加下一個組件之前進行改變。這種方法使你更容易明白你正在修改的內容,也能使你更容易明白在一連串對象中的這11個參數的作用。

         也許你現在對這些內容還是一知半解,不過事實上一旦你理解了GridBagConstraints,值得安慰的是你以后做再困難的工作都會游刃有余了。

    所以,如果我們已經明白了GridBagConstraints的詳細用法了,那么現在就讓我們來看看在實際應用中應該如何來實現它:

    tagLbl = new JLabel("Tags");
    c.gridx = 0; //x grid position
    c.gridy = 0; //y grid position
    gridbag.setConstraints(tagLbl, c); //設置標簽的限制

    contentPane.add(tagLbl); //增加到內容面板

    我們所做的是示例我們的標簽、分配給它一個格位置,將它與一個約束對象聯系起來并把它增加到我們的內容面板中。

    tagModeLbl = new JLabel("Tag Mode");
    c.gridx = 0;
    c.gridy = 1;
    gridbag.setConstraints(tagModeLbl, c);

    contentPane.add(tagModeLbl);

       請注意,雖然我們已經在我們的約束對象中把gridx的值設置為0,但是在這里我們仍然要對它進行重新設置——這樣做沒有其它原因,只是為了增加可讀性。

         下面,我們增加一個文本域以便能存儲我們希望能搜索到的關鍵字,再增加一個組合框以便用來搜索多個關鍵字。除了我們希望的文本域有兩列之外,這個概念其他的方面都與上面所說的是相同的,所以,我們需要在增加組合框之前重新設置文本域的值。

    tagTxt = new JTextField("plinth");
    c.gridx = 1;
    c.gridy = 0;
    c.gridwidth = 2;
    gridbag.setConstraints(tagTxt, c);
    contentPane.add(tagTxt);

    String[] options = {"all", "any"};
    modeCombo = new JComboBox(options);
    c.gridx = 1;
    c.gridy = 1;
    c.gridwidth = 1;
    gridbag.setConstraints(modeCombo, c);
    contentPane.add(modeCombo);

           做了這些之后,我們再在內容面板中增加一些其余的簡單組件,這時候我們就能夠瀏覽它了;其余的代碼應該不會出現任何問題了。

    到這個階段,我們應該已經得到了一個類似于我們先前所設計的界面了。

    posted @ 2011-02-24 10:32 Jamie 閱讀(481) | 評論 (0)編輯 收藏

    JComboBox

    7-4:JComboBox的使用:
    類層次結構圖:
       java.lang.Object
        --java.awt.Component
         --java.awt.Container
          --javax.swing.JComponent
           --javax.swing.JComboBox
       構造函數:
        JComboBox():建立一個新的JComboBox組件。
        JComboBox(ComboBoxModel aModel):用ListModel建立一個新的JComboBox組件。
        JComboBox(Object[] items):利用Array對象建立一個新的JComboBox組件。
        JComboBox(Vector items):利用Vector對象建立一個新的JComboBox組件。
    7-4-1:建立一般的JComboBox:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    import java.util.Vector;

    public class JComboBox1{
    public static void main(String[] args){
    JFrame f=new JFrame("JComboBox1");
    Container contentPane=f.getContentPane();
    contentPane.setLayout(new GridLayout(1,2));
    String[] s = {"美國","日本","大陸","英國","法國","意大利","澳洲","韓國"};
    Vector v=new Vector();
    v.addElement("Nokia 8850");
    v.addElement("Nokia 8250");
    v.addElement("Motorola v8088");
    v.addElement("Motorola v3850");
    v.addElement("Panasonic 8850");
        v.addElement("其它");
       
        JComboBox combo1=new JComboBox(s);
        combo1.addItem("中國");//利用JComboBox類所提供的addItem()方法,加入一個項目到此JComboBox中。
        combo1.setBorder(BorderFactory.createTitledBorder("你最喜歡到哪個國家玩呢?"));
        JComboBox combo2=new JComboBox(v);
        combo2.setBorder(BorderFactory.createTitledBorder("你最喜歡哪一種手機呢?"));  
        contentPane.add(combo1);
        contentPane.add(combo2);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent e){
        System.exit(0);
        }
        });
    }
    }
    7-4-2:利用ComboModel構造JComboBox:
        如同JList一般,在JComboBox中也有一個構造函數是利用某種Model來構造。如下所示:
          JComboBox(COmboBoxModel aModel)
       ComboBoxModel是一個interface,里面定義了兩個方法,分別是setSelectedItem()與getSelectedItem().這兩個方法目的是讓用
    戶選取某個項目后,可正確地顯示出用戶所選取的項目。下面是這兩個方法的詳細定義:
    ComboBoxModel interface定義的方法:
       Object    getSelectedItem():返回所選取的項目值。
       Void      setSelectedItem(Object anItem):設置所選取的項目值.

    與JList不同的是,JComboBox是利用ComboBoxModel,而不是ListModel.不過ComboBoxModel interface是繼承ListModel interface
    ,因此若我們要利用ComboBoxModel來構造JComboBox,除了要實作ComboBoxModel的兩個方法外,還必須實作ListModel的所定義的4個
    方法,這樣的做法可說相當麻煩。
       在介紹JList時我們曾經提到AbstractListModel這個抽象類。這個抽象類實作了ListModel interface中的addListDataListener
    ()、removeListDataListener()這兩個方法。因此若我們繼承AbstractListModel,則可少掉實作這兩個方法,只需要實作
    getElementAt()、getSize()、setSelectedItem()與getSelectedItem()這4個方法。這樣的作法就顯得比較簡單一點.

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class JComboBox2{
    String[] s= {"美國","日本","大陸","英國","法國","意大利","澳洲","韓國"};
    public JComboBox2(){
        JFrame f=new JFrame("JComboBox2");
        Container contentPane=f.getContentPane();
       
        ComboBoxModel mode=new UserDefineComboBoxModel();
        JComboBox combo=new JComboBox(mode);
        combo.setBorder(BorderFactory.createTitledBorder("你最喜歡到哪個國家去玩?"));
        contentPane.add(combo);
        f.pack();
        f.show();
        f.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent e){
        System.exit(0);
        }
        });  
    }
    public static void main(String[] args){
    new JComboBox2();
    }

    class UserDefineComboBoxModel extends AbstractListModel implements ComboBoxModel{
    String item=null;
    public Object getElementAt(int index){
       return s[index++];
    }
         //由于繼承AbstractListModel抽象類。因此我們分別在程序中實作了getElementAt()與getSize()方法。
    public int getSize(){
        return s.length;
    }
         //由于我們實現了ComboBoxModel interface.因此我們必須在程序中實作setSelectedItem()與getSelectedItem()方法.
    public void setSelectedItem(Object anItem){
          item=(String)anItem;
         }
         public Object getSelectedItem(){
            return item;
         }
    }
    }
       當程序要show出JComboBox時,系統會先自動調用getSize()方法,看看這個JComboBox長度有多少,然后再調用getElementAt()
    方法,將String Array s中的值填入JComboBox中。當用戶選擇項目時,系統會調用getSelectedItem()方法,返回所選取的項目,并
    利用setSelectedItem()方法,將選取項目放在JComboBox最前端。
       getElementAt()方法中的“index”參數,系統會自動由0計算,不過要自己作累加的操作,如程序中:
        return s[index++];
    如同JList一般,java對于JComboBox也提供了另一個類,DefaultComboBoxModel實體類。此類繼承了AbstractListModel抽象類,也
    實作了ComboBoxModel interface.因此你不需要再實作getSize()、getElementAt()、setSelectedItem()與getSelectedItem()方法。
    利用DefaultComboBoxModel這個類我們可以很方便地做到動態更改JComboBox的項目值。當你沒有必要自己定義特殊的ComboBoxModel
    時,使用DefaultComboBoxModel就顯得非常的方便,我們來看下面的例子:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class JComboBox3{
       String[] s = {"美國","日本","大陸","英國","法國","意大利","澳洲","韓國"};
       public JComboBox3(){
          JFrame f=new JFrame("JComboBox3");
          Container contentPane=f.getContentPane();
         
          ComboBoxModel mode=new AModel();
          JComboBox combo=new JComboBox(mode);
          combo.setBorder(BorderFactory.createTitledBorder("您最喜歡到哪個國家玩呢?"));
          contentPane.add(combo);
          f.pack();
          f.show();
          f.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent e){
        System.exit(0);
        }
          });  
       }
       public static void main(String[] args){
          new JComboBox3();
       }
       class AModel extends DefaultComboBoxModel{
       AModel(){
       for (int i=0;i<s.length;i++)
       addElement(s[i]);
       }
       }
    }
        1.由于AModel繼承DefaultComboBoxModel實體類,由AModel可得到一個ComboBoxModel實體對象。
        2.我們使AModel繼承DefaultComboBoxModel實體類,因此就不需要再實作getElementAt()、getSize()、setSelectedItem()與
          getSelectedItem()這4個方法,直接將所要的項目用addElement()方法加入即可。系統會自動將所加入的項目放進一個Vector
          中,并在輸出JComboBox時自動調用getSize()與getElementAt()方法。
    7-4-3:建立有圖像的JComboBox:
        在上一節中我們利用ListCellRenderer interface在JList中加入Icon圖像,而要在JComboBox中加入圖像的方法也是一樣的。
    我們必須實作ListCellRenderer interface所定義的方法getListCellRendererComponent.以下為這個方法的定義:
    要先了解ListCellRenderer interface.我們必須由這個interface所定義的方法,將圖像畫在JComboBox中的每個項目。
    ListCellRenderer interface里只定義了一個方法,那就是getListCellRendererComponent,不過這個參數有點多,我們把它列出來
    看看:
    public Component getListCellRendererComponent(JList list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus)
    list:即所要畫上的圖像的JComboBox組件。
    value:JComboBox項目值,如JComboBox.getModel().getElementAt(index)所返回的值。
    index:為JComboBox項目的索引值,由0開始。
    isSelected與cellHasFocus:判斷JComboBox中的項目是否有被選取或是有焦點置入。
    上面這4個參數會在你設置JComboBox的繪圖樣式(setCellRenderer())時自動的由JComboBox組件提供,你只要關心怎么控制
    getListCellRendererComponent()方法中的4個參數,而無需擔心怎么參數傳入。
       要在JList中加入Icon圖像的技巧就是將JComboBox中的每一個項目當作是JLabel,因為JLabel在使用文字與圖像上非常的方便,要設置JComboBox的圖像,
    必須使用setRenderer(ListCellRenderer cellRenderer){注:我們在JList中畫上圖像是利用JList所提供的setCellRenderer(ListCellRenderer
    cellRenderer)方法,讀者請小心}這個方法。我們來看下面這個范例,你就能明白了!

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class JComboBox4{
    String[] s={"西瓜","蘋果","草莓","香蕉","葡萄"};
    public JComboBox4(){
    JFrame f=new JFrame("JComboBox");
    Container contentPane=f.getContentPane();

    JComboBox combo=new JComboBox(s);
    combo.setBorder(BorderFactory.createTitledBorder("你最喜歡吃哪些水果?"));
    combo.setRenderer(new ACellRenderer());
    combo.setMaximumRowCount(3);

    contentPane.add(combo);
          f.pack();
          f.show();
          f.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent e){
        System.exit(0);
        }
          });    
    }
    public static void main(String[] args){
    new JComboBox4();
    }
    }
    class ACellRenderer extends JLabel implements ListCellRenderer{
    ACellRenderer(){
       setOpaque(true);
    }
    public Component getListCellRendererComponent(JList list,
                                                  Object value,
                                                  int index,
                                                  boolean isSelected,
                                                  boolean cellHasFocus){
        if (value!=null){
          setText(value.toString());
          setIcon(new ImageIcon(".\\icons\\fruit"+(index+1)+".jpg"));
        }
        if (isSelected){
           setBackground(list.getSelectionBackground());
           setForeground(list.getSelectionForeground());
        }else{
           setBackground(list.getBackground());
           setForeground(list.getForeground());
        }                                   
        return this;      
        }                                             
    }
        各們讀者在運行這個程序時會發現,即使JComboBox的選項中有圖標,但在選后圖標卻不會顯示在顯示列中,原因是在上面程序中
    我們以String Array s建立JComboBox:
          JComboBox combo=new JComboBox(s);
          String Array s里面放的只是水果名稱,而并沒有圖標。當我們使用setRenderer()方法來JComboBox時,只會繪制JComboBox的
    選項部份,而最后顯示在JComboBox上的值還是以String Array s為依據。因此JComboBox顯示列就只會顯示文字而已,而不會顯示出
    圖形。要解決這個問題,我們必須改變JComboBox所傳入的參數內容,也就是將原來的String Array s更改成具有圖形的數據項。在
    此我們是利用JComboBox(Object[] items)來建立有圖像的JComboBox,我們所傳進去的Object Array不應該只有文字,而必須連圖標一
    并傳入。我們修改上個范例修改如下:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class JComboBox5
    {
        String[] s = {"西瓜","蘋果","草莓","香蕉","葡萄"};
        ImageIcon[] icons = new ImageIcon[5];;
       
        public JComboBox5()
        {
            JFrame f = new JFrame("JComboBox");
            Container contentPane = f.getContentPane();
            ItemObj[] obj = new ItemObj[5];
           
            for(int i=0; i < 5; i++)
            {
                icons[i] = new ImageIcon(".\\icons\\fruit"+(i+1)+".jpg");
                obj[i] = new ItemObj(s[i],icons[i]);
            }
           
            JComboBox combo = new JComboBox(obj);//利用ItemObj Array obj當作是JComboBox的參數傳入,構造出JComboBox.
            combo.setBorder(BorderFactory.createTitledBorder("您喜歡吃哪些水果?"));
            combo.setRenderer(new ACellRenderer());
            combo.setMaximumRowCount(3);
           
            contentPane.add(combo);
            f.pack();
            f.show();
            f.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                        System.exit(0);
                }
            });
        }
       
        public static void main(String args[])
        {
            new JComboBox5();
        }
    }

    class ItemObj
    {
        String name;
        ImageIcon icon;
       
        public ItemObj(String name, ImageIcon icon){
            this.name = name;
            this.icon = icon;
        }
    }
       
    class ACellRenderer extends JLabel implements ListCellRenderer
    {
        ACellRenderer()
        {
            setOpaque(true);
        }
       
        public Component getListCellRendererComponent(JList list,
                                                      Object value,
                                                      int index,
                                                      boolean isSelected,
                                                      boolean cellHasFocus)
        {
            if (value != null)
            {
                setText(((ItemObj)value).name);
                setIcon(((ItemObj)value).icon);
            }

            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            }
            else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

            return this;
        }   
    }

       你可以發現,第一欄顯示有圖標顯示出來了。當然你也可以利用ComboBoxModel方式來構造出有圖標的JComboBox.我們來看下面
    的例子:

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class JComboBox6{
    String[] s={"西瓜","蘋果","草莓","香蕉","葡萄"};
    ImageIcon[] icons=new ImageIcon[5];
    public JComboBox6(){
        JFrame f=new JFrame("JComboBox");
        Container contentPane=f.getContentPane();
            for(int i=0; i < 5; i++)
            {
                icons[i] = new ImageIcon(".\\icons\\fruit"+(i+1)+".jpg");
            }
            ComboBoxModel mode=new AModel();
            JComboBox combo=new JComboBox(mode);
            combo.setBorder(BorderFactory.createTitledBorder("您喜歡吃哪些水果?"));
            combo.setRenderer(new ACellRenderer());
            combo.setMaximumRowCount(3);
           
            contentPane.add(combo);
            f.pack();
            f.show();
            f.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                        System.exit(0);
                }
            });
    }
    public static void main(String[] args){
    new JComboBox6();
    }
    /*我們用JComboBox(ComboBoxModel aModel)來構造圖標的JComboBox,因此我們在程序中編寫一個繼承DefaultComboBoxModel的
    ComboBoxModel.
    */
    class AModel extends DefaultComboBoxModel{
    AModel(){
       for (int i=0;i<s.length;i++){
          ItemObj obj=new ItemObj(s[i],icons[i]);
          addElement(obj);
       }
    }
    }
    }
    class ItemObj
    {
        String name;
        ImageIcon icon;
       
        public ItemObj(String name, ImageIcon icon){
            this.name = name;
            this.icon = icon;
        }
    }
       
    class ACellRenderer extends JLabel implements ListCellRenderer
    {
        ACellRenderer()
        {
            setOpaque(true);
        }
       
        public Component getListCellRendererComponent(JList list,
                                                      Object value,
                                                      int index,
                                                      boolean isSelected,
                                                      boolean cellHasFocus)
        {
            if (value != null)
            {
                setText(((ItemObj)value).name);
                setIcon(((ItemObj)value).icon);
            }

            if (isSelected) {
                setBackground(list.getSelectionBackground());
                setForeground(list.getSelectionForeground());
            }
            else {
                setBackground(list.getBackground());
                setForeground(list.getForeground());
            }

            return this;
        }   
    }

       我們用JComboBox(ComboBoxModel aModel)來構造圖標的JComboBox,因此我們在程序中編寫一個繼承DefaultComboBoxModel的
    ComboBoxModel.

    7-4-4:建立可自行輸入的JComboBox:
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class JComboBox7
    {
        String[] fontsize = {"12","14","16","18","20","22","24","26","28"};
        String defaultMessage = "請選擇或直接輸入文字大小!";
       
        public JComboBox7()
        {
            JFrame f = new JFrame("JComboBox");
            Container contentPane = f.getContentPane();
           
            JComboBox combo = new JComboBox(fontsize);
            combo.setBorder(BorderFactory.createTitledBorder("請選擇你要的文字大小"));
            combo.setEditable(true);//將JComboBox設成是可編輯的.
            ComboBoxEditor editor = combo.getEditor();//getEditor()方法返回ComboBoxEditor對象,如果你查看手冊,你就會發
             //現ComboBoxEditor是個接口(interface),因此你可以自行實作這個接口,制作自己想要的ComboBoxEditor組件。但通常
             //我們不需要這么做,因為默認的ComboBoxEditor是使用JTextField,這已經足夠應付大部份的情況了。
           
            //configureEditor()方法會初始化JComboBox的顯示項目。例如例子中一開始就出現:"請選擇或直接輸入文字大小!"這個
            //字符串。
            combo.configureEditor(editor, defaultMessage);
           
            contentPane.add(combo);
            f.pack();
            f.show();
            f.addWindowListener(new WindowAdapter() {
                public void windowClosing(WindowEvent e) {
                        System.exit(0);
                }
            });
        }
       
        public static void main(String args[])
        {
            new JComboBox7();
        }
    }


    7-4-5:JComboBox的事件處理:
        JComboBox的事件處理亦可分為兩種,一種是取得用戶選取的項目;另一種是用戶在JComboBox上自行輸入完畢后按下[Enter]鍵,
    運作相對應的工作。對于第一種事件的處理,我們使用ItemListener.對于第二種事件的處理,我們使用ActionListener.
        這個范例用戶可以選取所要的字號,字號的變化會呈現在JLabel上,并可讓用戶自行輸入字體的大小。當用戶按下[Enter]鍵后
    ,若用戶輸入的值不在選項上時,此輸入值會增加至JComboBox中,并將輸入字體的大小顯示在JLabel上。

    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;

    public class JComboBox8 implements ItemListener,ActionListener{
    String[] fontsize={"12","14","16","18","20","22","24","26","28"};
    String defaultMessage="請選擇或直接輸入文字大小!";
    Font font=null;
    JComboBox combo=null;
    JLabel label=null;

    public JComboBox8(){
    JFrame f=new JFrame("JComboBox");
    Container contentPane=f.getContentPane();
    contentPane.setLayout(new GridLayout(2,1));
    label=new JLabel("Swing",JLabel.CENTER);
    font=new Font("SansSerif",Font.PLAIN,12);
    label.setFont(font);

    combo=new JComboBox(fontsize);
    combo.setBorder(BorderFactory.createTitledBorder("請選擇你要的文字大小:"));
    combo.setEditable(true);
    ComboBoxEditor editor=combo.getEditor();
    combo.configureEditor(editor,defaultMessage);
    combo.addItemListener(this);0
    combo.addActionListener(this);

    contentPane.add(label);
    contentPane.add(combo);
          f.pack();
          f.show();
          f.addWindowListener(new WindowAdapter(){
        public void windowClosing(WindowEvent e){
        System.exit(0);
        }
          });  
    }
       public static void main(String[] args){
       new JComboBox8();
       }
       public void actionPerformed(ActionEvent e){
       boolean isaddItem=true;
       int fontsize=0;
       String tmp=(String)combo.getSelectedItem();
       //判斷用戶所輸入的項目是否有重復,若有重復則不增加到JComboBox中。
       try{
       fontsize=Integer.parseInt(tmp);
       for(int i=0;i<combo.getItemCount();i++){
       if (combo.getItemAt(i).equals(tmp)){
       isaddItem=false;
       break;
       }
       }
       if (isaddItem){
       combo.insertItemAt(tmp,0);//插入項目tmp到0索引位置(第一列中).
       }
       font=new Font("SansSerif",Font.PLAIN,fontsize);
       label.setFont(font);  
       }catch(NumberFormatException ne){
       combo.getEditor().setItem("你輸入的值不是整數值,請重新輸入!");
       }
       }
       public void itemStateChanged(ItemEvent e){//ItemListener界面只有itemStateChanged()一個方法,在此實作它。
       if (e.getStateChange()==ItemEvent.SELECTED){//當用戶的選擇改變時,則在JLabel上會顯示出Swing目前字形大小信息.
       int fontsize=0;
       try{
       fontsize=Integer.parseInt((String)e.getItem());
       label.setText("Swing 目前字形大小:"+fontsize);  
       }catch(NumberFormatException ne){//若所輸入的值不是整數,則不作任何的操作.
      
       }
       }
       }
    }

    posted @ 2011-02-17 08:24 Jamie 閱讀(2782) | 評論 (0)編輯 收藏

    httpclient

     

    HttpClient 是 Apache Jakarta Common 下的子項目,可以用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。本文首先介紹 HTTPClient,然后根據作者實際工作經驗給出了一些常見問題的解決方法。 HttpClient簡介 HTTP 協議可能是現在 Internet 上使用得最多、最重要的協議了,越來越多的 Java 應用程序需要直接通過 HTTP 協議來訪問網絡資源。雖然在 JDK 的 java.net 包中已經提供了訪問 HTTP 協議的基本功能,但是對于大部分應用程序來說,JDK 庫本身提供的功能還不夠豐富和靈活。HttpClient 是 Apache Jakarta Common 下的子項目,用來提供高效的、最新的、功能豐富的支持 HTTP 協議的客戶端編程工具包,并且它支持 HTTP 協議最新的版本和建議。HttpClient 已經應用在很多的項目中,比如 Apache Jakarta 上很著名的另外兩個開源項目 Cactus 和 HTMLUnit 都使用了 HttpClient,更多使用 HttpClient 的應用可以參見http://wiki.apache.org/jakarta-httpclient/HttpClientPowered。HttpClient 項目非常活躍,使用的人還是非常多的。目前 HttpClient 版本是在 2005.10.11 發布的 3.0 RC4 。 

    HttpClient 功能介紹
    以下列出的是 HttpClient 提供的主要的功能,要知道更多詳細的功能可以參見 HttpClient 的主頁。
    
    • 實現了所有 HTTP 的方法(GET,POST,PUT,HEAD 等)
      
    • 支持自動轉向
      
    • 支持 HTTPS 協議
      
    • 支持代理服務器等

    下面將逐一介紹怎樣使用這些功能。首先,我們必須安裝好 HttpClient。

    HttpClient 基本功能的使用  

    GET 方法 

    使用 HttpClient 需要以下 6 個步驟:

    1. 創建 HttpClient 的實例
     
    2. 創建某種連接方法的實例,在這里是 GetMethod。在 GetMethod 的構造函數中傳入待連接的地址

    3. 調用第一步中創建好的實例的 execute 方法來執行第二步中創建好的 method 實例

    4. 讀 response

    5. 釋放連接。無論執行方法是否成功,都必須釋放連接

    6. 對得到后的內容進行處理

    根據以上步驟,我們來編寫用GET方法來取得某網頁內容的代碼。
    大部分情況下 HttpClient 默認的構造函數已經足夠使用。
    HttpClient httpClient = new HttpClient();
     
    創建GET方法的實例。在GET方法的構造函數中傳入待連接的地址即可。用GetMethod將會自動處理轉發過程,如果想要把自動處理轉發過程去掉的話,可以調用方法setFollowRedirects(false)。
    GetMethod getMethod = new GetMethod("http://www.ibm.com/");
     
    調用實例httpClient的executeMethod方法來執行getMethod。由于是執行在網絡上的程序,在運行executeMethod方法的時候,需要處理兩個異常,分別是HttpException和IOException。引起第一種異常的原因主要可能是在構造getMethod的時候傳入的協議不對,比如不小心將"http"寫成"htp",或者服務器端返回的內容不正常等,并且該異常發生是不可恢復的;第二種異常一般是由于網絡原因引起的異常,對于這種異常 (IOException),HttpClient會根據你指定的恢復策略自動試著重新執行executeMethod方法。HttpClient的恢復策略可以自定義(通過實現接口HttpMethodRetryHandler來實現)。通過httpClient的方法setParameter設置你實現的恢復策略,本文中使用的是系統提供的默認恢復策略,該策略在碰到第二類異常的時候將自動重試3次。executeMethod返回值是一個整數,表示了執行該方法后服務器返回的狀態碼,該狀態碼能表示出該方法執行是否成功、需要認證或者頁面發生了跳轉(默認狀態下GetMethod的實例是自動處理跳轉的)等。
    //設置成了默認的恢復策略,在發生異常時候將自動重試3次,在這里你也可以設置成自定義的恢復策略
    getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
        new DefaultHttpMethodRetryHandler());
    //執行getMethod
    int statusCode = client.executeMethod(getMethod);
    if (statusCode != HttpStatus.SC_OK) {
      System.err.println("Method failed: " + getMethod.getStatusLine());
    }

    在返回的狀態碼正確后,即可取得內容。取得目標地址的內容有三種方法:第一種,getResponseBody,該方法返回的是目標的二進制的byte流;第二種,getResponseBodyAsString,這個方法返回的是String類型,值得注意的是該方法返回的String的編碼是根據系統默認的編碼方式,所以返回的String值可能編碼類型有誤,在本文的"字符編碼"部分中將對此做詳細介紹;第三種,getResponseBodyAsStream,這個方法對于目標地址中有大量數據需要傳輸是最佳的。在這里我們使用了最簡單的getResponseBody方法。
     
    byte[] responseBody = method.getResponseBody();
     
     釋放連接。無論執行方法是否成功,都必須釋放連接
     method.releaseConnection();
     
    處理內容。在這一步中根據你的需要處理內容,在例子中只是簡單的將內容打印到控制臺
     System.out.println(new String(responseBody));
     
     import java.io.IOException;
    import org.apache.commons.httpclient.*;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.params.HttpMethodParams;
    public class GetSample{
      public static void main(String[] args) {
      //構造HttpClient的實例
      HttpClient httpClient = new HttpClient();
      //創建GET方法的實例
      GetMethod getMethod = new GetMethod("http://www.ibm.com");
      //使用系統提供的默認的恢復策略
      getMethod.getParams().setParameter(HttpMethodParams.RETRY_HANDLER,
        new DefaultHttpMethodRetryHandler());
      try {
       //執行getMethod
       int statusCode = httpClient.executeMethod(getMethod);
       if (statusCode != HttpStatus.SC_OK) {
        System.err.println("Method failed: "
          + getMethod.getStatusLine());
       }
       //讀取內容
       byte[] responseBody = getMethod.getResponseBody();
       //處理內容
       System.out.println(new String(responseBody));
      } catch (HttpException e) {
       //發生致命的異常,可能是協議不對或者返回的內容有問題
       System.out.println("Please check your provided http address!");
       e.printStackTrace();
      } catch (IOException e) {
       //發生網絡異常
       e.printStackTrace();
      } finally {
       //釋放連接
       getMethod.releaseConnection();
      }
     }
    }

     
     

    POST方法

    根據RFC2616,對POST的解釋如下:POST方法用來向目的服務器發出請求,要求它接受被附在請求后的實體,并把它當作請求隊列(Request-Line)中請求URI所指定資源的附加新子項。POST被設計成用統一的方法實現下列功能:

    • 對現有資源的注釋(Annotation of existing resources)
      
    • 向電子公告欄、新聞組,郵件列表或類似討論組發送消息
      
    • 提交數據塊,如將表單的結果提交給數據處理過程
      
    • 通過附加操作來擴展數據庫
    調用HttpClient中的PostMethod與GetMethod類似,除了設置PostMethod的實例與GetMethod有些不同之外,剩下的步驟都差不多。在下面的例子中,省去了與GetMethod相同的步驟,只說明與上面不同的地方,并以登錄清華大學BBS為例子進行說明。
     構造PostMethod之前的步驟都相同,與GetMethod一樣,構造PostMethod也需要一個URI參數,在本例中,登錄的地址是http://www.newsmth.net/bbslogin2.php。在創建了PostMethod的實例之后,需要給method實例填充表單的值,在BBS的登錄表單中需要有兩個域,第一個是用戶名(域名叫id),第二個是密碼(域名叫passwd)。表單中的域用類NameValuePair來表示,該類的構造函數第一個參數是域名,第二參數是該域的值;將表單所有的值設置到PostMethod中用方法setRequestBody。另外由于BBS登錄成功后會轉向另外一個頁面,但是HttpClient對于要求接受后繼服務的請求,比如POST和PUT,不支持自動轉發,因此需要自己對頁面轉向做處理。具體的頁面轉向處理請參見下面的"自動轉向"部分。代碼如下
     
    String url = "http://www.newsmth.net/bbslogin2.php";
    PostMethod postMethod = new PostMethod(url);
    // 填入各個表單域的值
    NameValuePair[] data = { new NameValuePair("id", "youUserName"),
    new NameValuePair("passwd", "yourPwd") };
    // 將表單的值放入postMethod中
    postMethod.setRequestBody(data);
    // 執行postMethod
    int statusCode = httpClient.executeMethod(postMethod);
    // HttpClient對于要求接受后繼服務的請求,象POST和PUT等不能自動處理轉發
    // 301或者302
    if (statusCode == HttpStatus.SC_MOVED_PERMANENTLY ||
    statusCode == HttpStatus.SC_MOVED_TEMPORARILY) {
        // 從頭中取出轉向的地址
     Header locationHeader = postMethod.getResponseHeader("location");
        String location = null;
        if (locationHeader != null) {
         location = locationHeader.getValue();
         System.out.println("The page was redirected to:" + location);
        } else {
         System.err.println("Location field value is null.");
        }
        return;
    }

     
     
     

    字符編碼 

    某目標頁的編碼可能出現在兩個地方,第一個地方是服務器返回的http頭中,另外一個地方是得到的html/xml頁面中。

     
  • 在http頭的Content-Type字段可能會包含字符編碼信息。例如可能返回的頭會包含這樣子的信息:Content-Type: text/html; charset=UTF-8。這個頭信息表明該頁的編碼是UTF-8,但是服務器返回的頭信息未必與內容能匹配上。比如對于一些雙字節語言國家,可能服務器返回的編碼類型是UTF-8,但真正的內容卻不是UTF-8編碼的,因此需要在另外的地方去得到頁面的編碼信息;但是如果服務器返回的編碼不是UTF-8,而是具體的一些編碼,比如gb2312等,那服務器返回的可能是正確的編碼信息。通過method對象的getResponseCharSet()方法就可以得到http頭中的編碼信息。
    
  • 對于象xml或者html這樣的文件,允許作者在頁面中直接指定編碼類型。比如在html中會有<meta http-equiv="Content-Type" content="text/html; charset=gb2312"/>這樣的標簽;或者在xml中會有<?xml version="1.0" encoding="gb2312"?>這樣的標簽,在這些情況下,可能與http頭中返回的編碼信息沖突,需要用戶自己判斷到底那種編碼類型應該是真正的編碼。
  • 自動轉向

    根據RFC2616中對自動轉向的定義,主要有兩種:301和302。301表示永久的移走(Moved Permanently),當返回的是301,則表示請求的資源已經被移到一個固定的新地方,任何向該地址發起請求都會被轉到新的地址上。302表示暫時的轉向,比如在服務器端的servlet程序調用了sendRedirect方法,則在客戶端就會得到一個302的代碼,這時服務器返回的頭信息中location的值就是sendRedirect轉向的目標地址。

    HttpClient支持自動轉向處理,但是象POST和PUT方式這種要求接受后繼服務的請求方式,暫時不支持自動轉向,因此如果碰到POST方式提交后返回的是301或者302的話需要自己處理。就像剛才在POSTMethod中舉的例子:如果想進入登錄BBS后的頁面,必須重新發起登錄的請求,請求的地址可以在頭字段location中得到。不過需要注意的是,有時候location返回的可能是相對路徑,因此需要對location返回的值做一些處理才可以發起向新地址的請求。

    另外除了在頭中包含的信息可能使頁面發生重定向外,在頁面中也有可能會發生頁面的重定向。引起頁面自動轉發的標簽是:<meta http-equiv="refresh" content="5; url=http://www.ibm.com/us">。如果你想在程序中也處理這種情況的話得自己分析頁面來實現轉向。需要注意的是,在上面那個標簽中url的值也可以是一個相對地址,如果是這樣的話,需要對它做一些處理后才可以轉發


       

    處理HTTPS協議

    HttpClient提供了對SSL的支持,在使用SSL之前必須安裝JSSE。在Sun提供的1.4以后的版本中,JSSE已經集成到JDK中,如果你使用的是JDK1.4以前的版本則必須安裝JSSE。JSSE不同的廠家有不同的實現。下面介紹怎么使用HttpClient來打開Https連接。這里有兩種方法可以打開https連接,第一種就是得到服務器頒發的證書,然后導入到本地的keystore中;另外一種辦法就是通過擴展HttpClient的類來實現自動接受證書。

    方法1,取得證書,并導入本地的keystore:

    • 安裝JSSE (如果你使用的JDK版本是1.4或者1.4以上就可以跳過這一步)。本文以IBM的JSSE為例子說明。先到IBM網站上下載JSSE的安裝包。然后解壓開之后將ibmjsse.jar包拷貝到<java-home>\lib\ext\目錄下。
      
    • 取得并且導入證書。證書可以通過IE來獲得: 

      1. 用IE打開需要連接的https網址,會彈出如下對話框:

      2. 單擊"View Certificate",在彈出的對話框中選擇"Details",然后再單擊"Copy to File",根據提供的向導生成待訪問網頁的證書文件



      3. 向導第一步,歡迎界面,直接單擊"Next",

      4. 向導第二步,選擇導出的文件格式,默認,單擊"Next",



      5. 向導第三步,輸入導出的文件名,輸入后,單擊"Next",

      6. 向導第四步,單擊"Finish",完成向導

      7. 最后彈出一個對話框,顯示導出成功


    • 用keytool工具把剛才導出的證書倒入本地keystore。Keytool命令在<java-home>\bin\下,打開命令行窗口,并到<java-home>\lib\security\目錄下,運行下面的命令:

    • keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer
      

      其中參數alias后跟的值是當前證書在keystore中的唯一標識符,但是大小寫不區分;參數file后跟的是剛才通過IE導出的證書所在的路徑和文件名;如果你想刪除剛才導入到keystore的證書,可以用命令:

    • keytool -delete -keystore cacerts -storepass changeit -alias yourEntry1
       
    • 寫程序訪問https地址。如果想測試是否能連上https,只需要稍改一下GetSample例子,把請求的目標變成一個https地址。
      GetMethod getMethod = new GetMethod(https://www.yourdomain.com);

     

    運行該程序可能出現的問題:

    • 1. 拋出異常java.net.SocketException: Algorithm SSL not available。出現這個異常可能是因為沒有加JSSEProvider,如果用的是IBM的JSSE Provider,在程序中加入這樣的一行:
       if(Security.getProvider("com.ibm.jsse.IBMJSSEProvider") == null)
       Security.addProvider(new IBMJSSEProvider());

      

      或者也可以打開<java-home>\lib\security\java.security,在行

    • security.provider.1=sun.security.provider.Sun
      security.provider.2=com.ibm.crypto.provider.IBMJCE

    后面加入security.provider.3=com.ibm.jsse.IBMJSSEProvider

    2. 拋出異常java.net.SocketException: SSL implementation not available。出現這個異常可能是你沒有把ibmjsse.jar拷貝到<java-home>\lib\ext\目錄下。

    3. 拋出異常javax.net.ssl.SSLHandshakeException: unknown certificate。出現這個異常表明你的JSSE應該已經安裝正確,但是可能因為你沒有把證書導入到當前運行JRE的keystore中,請按照前面介紹的步驟來導入你的證書。

    方法2,擴展HttpClient類實現自動接受證書

    因為這種方法自動接收所有證書,因此存在一定的安全問題,所以在使用這種方法前請仔細考慮您的系統的安全需求。具體的步驟如下:

    • 提供一個自定義的socket factory(test.MySecureProtocolSocketFactory)。這個自定義的類必須實現接口org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory,在實現接口的類中調用自定義的X509TrustManager(test.MyX509TrustManager),這兩個類可以在隨本文帶的附件中得到
      
    • 創建一個org.apache.commons.httpclient.protocol.Protocol的實例,指定協議名稱和默認的端口號
      Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);
      
    • 注冊剛才創建的https協議對象 
      Protocol.registerProtocol("https ", myhttps);
    • 
    • 然后按照普通編程方式打開https的目標地址,代碼請參見test.NoCertificationHttpsGetSample

    處理代理服務器

    HttpClient中使用代理服務器非常簡單,調用HttpClient中setProxy方法就可以,方法的第一個參數是代理服務器地址,第二個參數是端口號。另外HttpClient也支持SOCKS代理。
    
    httpClient.getHostConfiguration().setProxy(hostName,port);

    結論 

    從上面的介紹中,可以知道HttpClient對http協議支持非常好,使用起來很簡單,版本更新快,功能也很強大,具有足夠的靈活性和擴展性。對于想在Java應用中直接訪問http資源的編程人員來說,HttpClient是一個不可多得的好工具。

    posted @ 2011-02-15 12:13 Jamie 閱讀(336) | 評論 (0)編輯 收藏

    test

    package client.test;

    import java.io.BufferedWriter;
    import java.io.FileWriter;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;

    import org.apache.commons.httpclient.HostConfiguration;
    import org.apache.commons.httpclient.HttpClient;
    import org.apache.commons.httpclient.HttpMethod;
    import org.apache.commons.httpclient.NameValuePair;
    import org.apache.commons.httpclient.methods.GetMethod;
    import org.apache.commons.httpclient.methods.PostMethod;
    import org.htmlparser.Node;
    import org.htmlparser.NodeFilter;
    import org.htmlparser.Parser;
    import org.htmlparser.filters.AndFilter;
    import org.htmlparser.filters.HasAttributeFilter;
    import org.htmlparser.filters.TagNameFilter;
    import org.htmlparser.nodes.TagNode;
    import org.htmlparser.util.NodeList;
    import org.htmlparser.util.ParserException;

    public class TIPOTest {

     private static String mainPageUrl = "http://twpat.tipo.gov.tw/twcgi/ttsweb?@0:0:1:twpat2@@"
       + Math.random();
     public static String strEncoding = "utf-8"; //strEncoding = "iso-8859-1";
     final static String userAgent = "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0; .NET CLR 1.0.3705)";

     public static void main(String[] args) throws Exception {
    //  HttpClient client = new HttpClient();
    //  client.getHostConfiguration().setProxy("10.41.16.98", 808);
    //  client.getHostConfiguration().setHost(
    //    "http://twpat3.tipo.gov.tw/tipotwoc", 80, "http");

    //  String strLegalStatus = null;
      String mainPage = doGetMethod(mainPageUrl);

      String searchPageUrl = parserMainPage(mainPage);

      String searchPage = doGetMethod(searchPageUrl);

      String queryPageUrl = getQueryPageUrl(searchPage);

      String queryPage = doGetMethod(queryPageUrl);

      String searchResultUrl = parserPageForPostURL(queryPage);
      Map parameterMap = parseParameters(queryPage);

      System.out.println("searchResultUrl : " + searchResultUrl);

      String response = getResultPage(searchResultUrl, "087121847",
        parameterMap);

      // HttpMethod method = getPostMethod(); // 使用 POST 方式提交數據
      // // HttpMethod method = getGetMethod(); // 使用 GET 方式提交數據
      // client.executeMethod(method); // 打印服務器返回的狀態
      // System.out.println(method.getStatusLine()); // 打印結果頁面
      // String response = new
      // String(method.getResponseBodyAsString().getBytes(
      // "8859_1"));

      // 打印返回的信息
      System.out.println(response);
      // 釋放連接
      // method.releaseConnection();
     }

     private static String doGetMethod(String url) throws Exception {
      try {
       HttpClient httpClient = new HttpClient();
       HostConfiguration hc = httpClient.getHostConfiguration();

       hc.setProxy("10.41.16.98", 808);
       httpClient.getState().setAuthenticationPreemptive(true);

       GetMethod getMethod = new GetMethod(url);

       getMethod.setRequestCharSet(strEncoding);
       getMethod.setResponseCharSet(strEncoding);
       getMethod.setRequestHeader("User-Agent", userAgent);
       getMethod.setTimeout(1000 * 60 * 2);
       int StatusCode = httpClient.executeMethod(getMethod);
       if (StatusCode >= 400) {
        getMethod.getConnection().close();
        throw new Exception("Can't get information.");
       }
       String str = getMethod.getResponseBodyAsString();
       getMethod.releaseConnection();

       writeStrToTxt(str);// wuwen add for test

       return str;
      } catch (Exception e) {
       e.printStackTrace();
       throw e;
      }
     }

     static int i = 1;

     // wuwen add for test
     public static void writeStrToTxt(String str) {
      i++;
      BufferedWriter output;
      try {
       output = new BufferedWriter(new FileWriter(
         "C:\\Documents and Settings\\F3223114\\桌面\\" + i + ".txt"));

       output.write(str);
       output.close();

      } catch (IOException e) {
       e.printStackTrace();
      }
     }

     private static String parserMainPage(String body) {
      String parserSearchUrl = "";
      /*
       * String regEx = "href=(.+?)\\s*class=menu"; Pattern pattern =
       * Pattern.compile(regEx, Pattern.CASE_INSENSITIVE); Matcher matcher =
       * pattern.matcher(body); while (matcher.find()) { if
       * (matcher.group(1).contains(":80:::0")) { parserSearchUrl =
       * matcher.group(1); } }
       */
      int i = body.indexOf("http");
      if (i != -1) {
       parserSearchUrl = body.substring(i, body.indexOf(">", i));
      }
      return parserSearchUrl;
     }

     public String getMidString(String sInput, String sStartTag, String sEndTag) {
      int i, j = -1;
      if ((i = sInput.indexOf(sStartTag)) < 0) {
       return null;
      } else {
       if ((j = sInput.indexOf(sEndTag, i + sStartTag.length())) < 0) {
        return null;
       } else {
        if (i + sStartTag.length() == j) {
         return null;
        } else {
         return sInput.substring(i + sStartTag.length(), j);
        }
       }
      }
     }

     private static String doPostMethod(String url, NameValuePair[] nameValuePair)
       throws Exception {
      try {
       HttpClient httpClient = new HttpClient();
       HostConfiguration hc = httpClient.getHostConfiguration();
       hc.setProxy("10.41.16.98", 808);
       httpClient.getState().setAuthenticationPreemptive(true);

       PostMethod postMethod = new PostMethod(url);
       postMethod.setRequestCharSet(strEncoding);
       postMethod.setResponseCharSet(strEncoding);
       postMethod.setRequestHeader("User-Agent", userAgent);
       postMethod.setTimeout(1000 * 60 * 2);
       postMethod.setRequestBody(nameValuePair);
       int StatusCode = httpClient.executeMethod(postMethod);
       if (StatusCode >= 400) {
        postMethod.getConnection().close();
        throw new Exception("Can't get information.");
       }
       String str = postMethod.getResponseBodyAsString();

       postMethod.releaseConnection();
       return str;
      } catch (Exception e) {
       e.printStackTrace();
       throw e;
      }
     }

     // modify by zhuoluo 2008.12.09
     private static String getResultPage(String url, String strAppNo,
       Map parameterMap) throws Exception {
      try {
       NameValuePair _0_1_T = new NameValuePair("@_0_1_T", "T_UID");
       _0_1_T.setHeadNeedEncode(false);
       NameValuePair _0_1_T_1 = new NameValuePair("_0_1_T", "");
       _0_1_T_1.setHeadNeedEncode(false);
       NameValuePair _0_2_P = new NameValuePair("@_0_2_P", "P_PWD");
       _0_2_P.setHeadNeedEncode(false);
       NameValuePair _0_2_P_1 = new NameValuePair("_0_2_P", "");
       _0_2_P_1.setHeadNeedEncode(false);
       NameValuePair _20_0_T = new NameValuePair("@_20_0_T", "T_AN");
       _20_0_T.setHeadNeedEncode(false);
       NameValuePair appNo = new NameValuePair("_20_0_T", strAppNo);
       appNo.setHeadNeedEncode(false);
       NameValuePair _20_1_K = new NameValuePair("@_20_1_K", "K_NE");
       _20_1_K.setHeadNeedEncode(false);
       NameValuePair _20_1_K_1 = new NameValuePair("_20_1_K", "");
       _20_1_K_1.setHeadNeedEncode(false);
       NameValuePair JPAGE = new NameValuePair("JPAGE", "");
       JPAGE.setHeadNeedEncode(false);

       NameValuePair INFO = new NameValuePair("INFO", parameterMap.get(
         "INFO").toString());
       INFO.setHeadNeedEncode(false);

    //   NameValuePair x = new NameValuePair("_IMG_%E6%AA%A2%E7%B4%A2.x",
    //     "39");
    //   x.setHeadNeedEncode(false);
    //   NameValuePair y = new NameValuePair("_IMG_%E6%AA%A2%E7%B4%A2.y",
    //     "10");
    //   y.setHeadNeedEncode(false);
       NameValuePair x = new NameValuePair("_IMG_%E6%AA%A2%E7%B4%A2%25z.x",
       "39");
       x.setHeadNeedEncode(false);
       NameValuePair y = new NameValuePair("_IMG_%E6%AA%A2%E7%B4%A2%25z.y",
       "10");
       y.setHeadNeedEncode(false);

       NameValuePair[] nameValuePair = new NameValuePair[] { _0_1_T,
         _0_1_T_1, _0_2_P, _0_2_P_1, _20_0_T, appNo, _20_1_K,
         _20_1_K_1, x, y , INFO };
    //   NameValuePair[] nameValuePair = new NameValuePair[] { _0_1_T,
    //     _0_1_T_1, _0_2_P, _0_2_P_1, _20_0_T, appNo, _20_1_K,
    //     _20_1_K_1, JPAGE, INFO };//x, y ,
       String str = doPostMethod(url, nameValuePair);

       writeStrToTxt(str);// wuwen add for test

       return str;
      } catch (Exception e) {
       e.printStackTrace();
       throw e;
      }
     }

     private static String getQueryPageUrl(String body) {
      Parser parser = Parser.createParser(body, "utf-8");
      NodeFilter filter_constellation_summart = new AndFilter(
        (new TagNameFilter("a")), (new HasAttributeFilter("class",
          "menu")));
      NodeList nodeList = null;
      String href = "";
      try {
       nodeList = parser
         .extractAllNodesThatMatch(filter_constellation_summart);
       Node node = null;
       node = nodeList.elementAt(3);
       href = ((TagNode) node).getAttribute("href");
      } catch (ParserException ex) {
      }

      return href;
     }

     private static String parserPageForPostURL(String body)
       throws ParserException {
      String searchResultUrl = "";
      NodeFilter tagFilter = new TagNameFilter("FORM");
      Parser parser = Parser.createParser(body, "UTF-8");
      NodeList list = parser.extractAllNodesThatMatch(tagFilter);
      for (int i = 0; i < list.size(); i++) {
       Node node = list.elementAt(i);
       if (node instanceof TagNode) {
        String methodValue = ((TagNode) node).getAttribute("METHOD");
        if (methodValue != null) {
         String actionPath = ((TagNode) node).getAttribute("ACTION");
         searchResultUrl = actionPath;
        }
       }
      }
      return searchResultUrl;
     }

     private static Map<String, String> parseParameters(String pageBody)
       throws ParserException {
      Map<String, String> parameterMap = new HashMap<String, String>();
      NodeFilter tagFilter = new TagNameFilter("input");
      Parser parser = Parser.createParser(pageBody, "UTF-8");
      NodeList list = parser.extractAllNodesThatMatch(tagFilter);
      for (int i = 0; i < list.size(); i++) {
       Node node = list.elementAt(i);
       if (node instanceof TagNode) {
        String nodeName = ((TagNode) node).getAttribute("name");
        String nodeValue = ((TagNode) node).getAttribute("value");

        if (nodeName != null) {
         if (nodeName.equals("INFO")) {
          if (nodeValue == null) {
           nodeValue = "";
          }
          parameterMap.put(nodeName, nodeValue);
         }
        }
       }
      }
      return parameterMap;
     }
    }

    posted @ 2011-01-11 17:42 Jamie 閱讀(249) | 評論 (0)編輯 收藏

    TRUNC函數的用法

     

    TRUNC函數用于對值進行截斷。

    用法有兩種:TRUNC(NUMBER)表示截斷數字,TRUNC(date)表示截斷日期。

    (1)截斷數字:

    格式:TRUNC(n1,n2),n1表示被截斷的數字,n2表示要截斷到那一位。n2可以是負數,表示截斷小數點前。注意,TRUNC截斷不是四舍五入。

    SQL> select TRUNC(15.79) from dual;

    TRUNC(15.79)
    ------------
              15

    SQL> select TRUNC(15.79,1) from dual;

    TRUNC(15.79,1)
    --------------
              15.7

    SQL> select trunc(15.79,-1) from dual;

    TRUNC(15.79,-1)
    ---------------
                 10

    (2)截斷日期:

    先執行命令:alter session set nls_date_format='yyyy-mm-dd hh24:mi:hh';

    截取今天:

    SQL> select sysdate,trunc(sysdate,'dd') from dual;

    SYSDATE             TRUNC(SYSDATE,'DD')
    ------------------- -------------------
    2009-03-24 21:31:17 2009-03-24 00:00:00

    截取本周第一天:

    SQL> select sysdate,trunc(sysdate,'d') from dual;

    SYSDATE             TRUNC(SYSDATE,'D')
    ------------------- -------------------
    2009-03-24 21:29:32 2009-03-22 00:00:00

    截取本月第一天:

    SQL> select sysdate,trunc(sysdate,'mm') from dual;

    SYSDATE             TRUNC(SYSDATE,'MM')
    ------------------- -------------------
    2009-03-24 21:30:30 2009-03-01 00:00:00

    截取本年第一天:

    SQL> select sysdate,trunc(sysdate,'y') from dual;

    SYSDATE             TRUNC(SYSDATE,'Y')
    ------------------- -------------------
    2009-03-24 21:31:57 2009-01-01 00:00:00

    截取到小時:

    SQL> select sysdate,trunc(sysdate,'hh') from dual;

    SYSDATE             TRUNC(SYSDATE,'HH')
    ------------------- -------------------
    2009-03-24 21:32:59 2009-03-24 21:00:00

    截取到分鐘:

    SQL> select sysdate,trunc(sysdate,'mi') from dual;

    SYSDATE             TRUNC(SYSDATE,'MI')
    ------------------- -------------------
    2009-03-24 21:33:32 2009-03-24 21:33:00


    獲取上月第一天:
    SQL> select TRUNC(add_months(SYSDATE,-1),'MM') from dual



    posted @ 2010-12-21 14:55 Jamie 閱讀(23726) | 評論 (0)編輯 收藏

    RMI原理及實現

    RMI原理及實現
    簡介
      RMI是遠程方法調用的簡稱,象其名稱暗示的那樣,它能夠幫助我們查找并執行遠程對象的方法。通俗地說,遠程調用就象將一個class放在A機器上,然后在B機器中調用這

    個class的方法。
      我個人認為,盡管RMI不是唯一的企業級遠程對象訪問方案,但它卻是最容易實現的。與能夠使不同編程語言開發的CORBA不同的是,RMI是一種純Java解決方案。在RMI

    中,程序的所有部分都由Java編寫。
      在看本篇文章時,我假定讀者都已經具備了較扎實的Java基礎知識,在這方面有欠缺的讀者請自行閱讀有關資料。
      概念
      我在前面已經提到,RMI是一種遠程方法調用機制,其過程對于最終用戶是透明的:在進行現場演示時,如果我不說它使用了RNI,其他人不可能知道調用的方法存儲在其他

    機器上。當然了,二臺機器上必須都安裝有Java虛擬機(JVM)。
      其他機器需要調用的對象必須被導出到遠程注冊服務器,這樣才能被其他機器調用。因此,如果機器A要調用機器B上的方法,則機器B必須將該對象導出到其遠程注冊服務器

    。注冊服務器是服務器上運行的一種服務,它幫助客戶端遠程地查找和訪問服務器上的對象。一個對象只有導出來后,然后才能實現RMI包中的遠程接口。例如,如果想使機器A

    中的Xyz對象能夠被遠程調用,它就必須實現遠程接口。
      RMI需要使用占位程序和框架,占位程序在客戶端,框架在服務器端。在調用遠程方法時,我們無需直接面對存儲有該方法的機器。
      在進行數據通訊前,還必須做一些準備工作。占位程序就象客戶端機器上的一個本機對象,它就象服務器上的對象的代理,向客戶端提供能夠被服務器調用的方法。然

    后,Stub就會向服務器端的Skeleton發送方法調用,Skeleton就會在服務器端執行接收到的方法。
      Stub和Skeleton之間通過遠程調用層進行相互通訊,遠程調用層遵循TCP/IP協議收發數據。下面我們來大致了解一種稱為為“綁定”的技術。
      客戶端無論何時要調用服務器端的對象,你可曾想過他是如何告訴服務器他想創建什么樣的對象嗎?這正是“綁定”的的用武之地。在服務器端,我們將一個字符串變量與一個

    對象聯系在一起(可以通過方法來實現),客戶端通過將那個字符串傳遞給服務器來告訴服務器它要創建的對象,這樣服務器就可以準確地知道客戶端需要使用哪一個對象了。所

    有這些字符串和對象都存儲在的遠程注冊服務器中。
      在編程中需要解決的問題
      在研究代碼之前,我們來看看必須編寫哪些代碼:
      遠程對象:這個接口只定義了一個方法。我們應當明白的是,這個接口并非總是不包括方法的代碼而只包括方法的定義。遠程對象包含要導出的每個方法的定義,它還實

    現Java.rmi中的遠程接口。
      遠程對象實現:這是一個實現遠程對象的類。如果實現了遠程對象,就能夠覆蓋該對象中的所有方法,因此,遠程對象的實現類將真正包含我們希望導出的方法的代碼。
      遠程服務器:這是一個作為服務器使用的類,它是相對于要訪問遠程方法的客戶端而言的。它存儲著綁定的字符串和對象。
      遠程客戶端:這是一個幫助我們訪問遠程方法提供幫助的類,它也是最終用戶。我們將使用查找和調用遠程方法的方法在該類中調用遠程方法。
      編程
      我們將首先編寫遠程對象,并將代碼保存為名字為AddServer.Java的文件:
      import Java.rmi.*;
      public interface AddServer extends Remote {
      public int AddNumbers(int firstnumber,int secondnumber) throws RemoteException;
      }
      我們來看看上面的代碼。首先,為了使用其內容,我們導入rmi包。然后,我們創建一個擴展了Java.rmi中遠程接口的接口。所有的遠程對象必須擴展該遠程接口,我們將該

    遠程接口稱為AddServer。在該遠程對象中,有一個名字為AddNumbers的方法,客戶端可以調用這一方法。我們必須記住的是,所有的遠程方法都需要啟

    動RemoteException方法,有錯誤發生時就會調用該方法。
      下面我們開始編寫遠程對象的實現。這是一個實現遠程對象并包含有所有方法代碼的類,將下面的代碼保存為名字為AddServerImpl.Java的文件:
      import Java.rmi.*;
      public class AddServerImpl extends UnicastRemoteObject implements AddServer {
      public AddServerImpl() {
      super();
      }
      public int AddNumbers(int firstnumber,int secondnumber) throws RemoteException {
      return firstnumber + secondnumber;
      }
      }
      首先,我們導入rmi包,然后創建一個擴展UnicastRemoteObject和實現創建的遠程對象的類;其次,我們可以為類創建一個缺省的構建器。我們還了解了AddNumbers方

    法的代碼,它啟動RemoteException。這樣我們就覆蓋了創建的遠程對象中的方法。AddNumbers方法的代碼非常好理解,它接受2個整型參數,然后相加并返回它們的和。
      至此,我們已經有了二個Java文件:遠程對象和遠程對象的實現。下面我們將使用Javac命令編譯這二個文件:
      編譯遠程對象:
      C:\jdk\bin\Javac workingdir\AddServer.Java
      編譯遠程對象實現:
      C:\jdk\bin\Javac workingdir\AddServerImpl.Java 這樣,就會達到二個Java文件和二個類文件,下面我們將創建stub和skeleton。為了創建stub和skeleton文件,

    我們必須使用rmic編譯器編譯遠程對象實現文件。
      用Rmic編譯遠程對象實現文件:
      C:\jdk\bin\rmic workingdir\AddServerImpl.Java 然后,我們就會發現多了2個新建的類文件,它們分別是AddServerImpl_Stub.class

    和AddServerImpl_Skel.class 。
      The Coding (Contd.)
      我們已經編譯了所有的源代碼,下面我們來創建客戶端和服務器端,將下面的代碼保存為名字為RmiServer.Java的文件:
      import Java.rmi.*;
      import Java.net.*;
      public class RmiServer {
      public static void main (String args[]) throws RemoteException, MalformedURLException {
      AddServerImpl add = new AddServerImpl();
      Naming.rebind("addnumbers",add);
      }
      }
      首先,我們導入Java.rmi包和Java.net包。另外,我們還使用throws從句捕獲任何異常。我們從對象中得出遠程對象實現,使用rebind方法將字符串addnumbers與該對

    象綁定。下面的例子顯示了綁定的含義:
      從現在開始,無論何時客戶端要調用遠程對象,使用字符串addnumbers就可以實現。rebind方法有二個參數:第一個參數是字符串變量,第二個參數是遠程對象實現類的

    對象。
      下面我們來創建客戶端,將下面的代碼保存為名字為RmiClient.Java的文件:
      import Java.rmi.*;
      import Java.net.*;
      public class RmiClient {
      public static void main(String args[]) throws RemoteException, MalformedURLException {
      String url="rmi://127.0.0.1/addnumbers";
      AddServer add;
      add = (AddServer)Naming.lookup(url);
      int result = add.AddNumbers(10,5);
      System.out.println(result);
      }
      }
      首先,我們導入Java.rmi包和Java.net包,并使用throws從句捕獲所有必要的異常。然后通過利用Naming類中的靜態lookup方法從遠程對象中得到一個對象。(這也是我

    們無需從Naming類中得到一個對象并調用它。而只使用類名字的原因。)
      lookup方法接受遠程對象的完整的URL名字,該URL由完整的機器IP地址以及與對象綁定的字符串(也誻對象的綁定名)組成。在調用遠程對象時,我們使用了RMI協

    議。lookup方法向我們返回一個對象,在能夠使用它前,我們必須將它的數據類型轉換為與遠程對象的數據類型一致。
      Since we have both our server and client source ready, let's compile them both:
      至此,我們已經有了服務器端和客戶端的源代碼,下面我們來編譯這二個源文件:
      編譯遠程服務器:
      C:\jdk\bin\Javac workingdir\RmiServer.Java
      編譯遠程客戶端:
      C:\jdk\bin\Javac workingdir\RmiClient.Java
      在對我們的代碼進行測試前,還必須首先啟動RMI Registry。RMI Registry存儲有所有綁定的數據,沒有它,RMI就不能正常地運行!
      啟動Rmi Registry服務器:
      C:\jdk\bin\start rmiregistry
      我們會注意到,這時會出現一個空白的DOS提示符窗口,這表明Rmi Registry服務器在運行,注意不要關閉該窗口。然后,我們首先在一個DOS提示符窗口中運行Rmi服務

    器,然后在另一個DOS提示符窗口中運行Rmi客戶端。
      啟動RMI服務器:
      C:\jdk\bin\Java workingdir\RmiServer
      啟動RMI客戶端:
      C:\jdk\bin\Java workingdir\RmiClient
      如果一切正常,我們應該能夠得到15這個輸出。我們向AddNumbers方法輸入10和5二個數字,該方法將這二者加起來,并將其和15返回給我們。如果得到了15這個輸出,

    說明我們已經成功地執行了一個遠程方法。當然,在這里,我們并沒有執行真正意義上的遠程方法,因為我們的計算機既是服務器,又是客戶機。如果有計算機網絡,我們就可以

    方便地進行執行遠程方法的試驗了。

    posted @ 2010-12-18 15:57 Jamie 閱讀(2932) | 評論 (0)編輯 收藏

    設置JTable不可編輯

    將JTable的單元格設置為不可編輯,有兩種方法。
    一種是自己寫一個MyTable類繼承DefaultTableModel,重寫其中的isCellEditable方法;
    還有一種是在創建JTable對象時, JTable treeTable = new JTable(tableModel){ public boolean isCellEditable(int row, int column) { return false; }};

    posted @ 2010-10-08 09:34 Jamie 閱讀(2451) | 評論 (0)編輯 收藏

    JTable

    一.創建表格控件的各種方式:
    1) 調用無參構造函數.
    JTable table = new JTable();
    2) 以表頭和表數據創建表格.
    Object[][] cellData = {{"row1-col1", "row1-col2"},{"row2-col1", "row2-col2"}};
    String[] columnNames = {"col1", "col2"};
       
    JTable table = new JTable(cellData, columnNames);
    3) 以表頭和表數據創建表格,并且讓表單元格不可改.
    String[] headers = { "表頭一", "表頭二", "表頭三" };
    Object[][] cellData = null; 
    DefaultTableModel model = new DefaultTableModel(cellData, headers) {
    public boolean isCellEditable(int row, int column) {
        return false;
    }
    };
    table = new JTable(model);
    
    二.對表格列的控制
    0)獲取JTable中特定單元格的位置
    table.addMouseListener(new MouseListener() {
            public void mouseClicked(MouseEvent e) {
                       int row = jt.rowAtPoint(e.getPoint());
                       int col = jt.columnAtPoint(e.getPoint());
    }
    });
       
    1) 設置列不可隨容器組件大小變化自動調整寬度.
    table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
    2) 限制某列的寬度.
    TableColumn firsetColumn = table.getColumnModel().getColumn(0);
    firsetColumn.setPreferredWidth(30);
    firsetColumn.setMaxWidth(30);
    firsetColumn.setMinWidth(30);
    3) 設置當前列數.
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    int count=5;
    tableModel.setColumnCount(count);
    4) 取得表格列數
    int cols = table.getColumnCount();
    5) 添加列
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    tableModel.addColumn("新列名");
    6) 刪除列
    table.removeColumn(table.getColumnModel().getColumn(columnIndex));// columnIndex是要刪除的列序號
    三.對表格行的控制
    1) 設置行高
    table.setRowHeight(20);
    2) 設置當前航數
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    int n=5;
    tableModel.setRowCount(n);
    3) 取得表格行數
    int rows = table.getRowCount();
    4) 添加表格行
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    tableModel.addRow(new Object[]{"sitinspring", "35", "Boss"});
    5) 刪除表格行
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    model.removeRow(rowIndex);// rowIndex是要刪除的行序號
    四.存取表格單元格的數據
    1) 取單元格數據
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    String cellValue=(String) tableModel.getValueAt(row, column);// 取單元格數據,row是行號,column是列號
    2) 填充數據到表格.
    注:數據是Member類型的鏈表,Member類如下:
    public class Member{
        // 名稱
        private String name;
       
        // 年齡
        private String age;
       
        // 職務
        private String title;
    }
    填充數據的代碼:
    public void fillTable(List<Member> members){
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    tableModel.setRowCount(0);// 清除原有行
    // 填充數據
    for(Member member:members){
        String[] arr=new String[3];
        arr[0]=member.getName();
        arr[1]=member.getAge();
        arr[2]=member.getTitle();
       
        // 添加數據到表格
        tableModel.addRow(arr);
    }
    // 更新表格
    table.invalidate();
    }
    2) 取得表格中的數據
    public List<Member> getShowMembers(){
    List<Member> members=new ArrayList<Member>();
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    int rowCount=tableModel.getRowCount();
    for(int i=0;i<rowCount;i++){
        Member member=new Member();
       
        member.setName((String)tableModel.getValueAt(i, 0));// 取得第i行第一列的數據
        member.setAge((String)tableModel.getValueAt(i, 1));// 取得第i行第二列的數據
        member.setTitle((String)tableModel.getValueAt(i, 2));// 取得第i行第三列的數據
       
        members.add(member);
    }
    return members;
    }
    五.取得用戶所選的行
    1) 取得用戶所選的單行
    int selectRows=table.getSelectedRows().length;// 取得用戶所選行的行數
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    if(selectRows==1){
    int selectedRowIndex = table.getSelectedRow(); // 取得用戶所選單行
    .// 進行相關處理
    }
    2) 取得用戶所選的多行
    int selectRows=table.getSelectedRows().length;// 取得用戶所選行的行數
    DefaultTableModel tableModel = (DefaultTableModel) table.getModel();
    if(selectRows>1)
    int[] selRowIndexs=table.getSelectedRows();// 用戶所選行的序列
    for(int i=0;i<selRowIndexs.length;i++){
        // 用tableModel.getValueAt(row, column)取單元格數據
        String cellValue=(String) tableModel.getValueAt(i, 1);
    }
    }
    六.添加表格的事件處理
    view.getTable().addMouseListener(new MouseListener() {
    public void mousePressed(MouseEvent e) {
        // 鼠標按下時的處理
    }
    public void mouseReleased(MouseEvent e) {
        // 鼠標松開時的處理
    }
    public void mouseEntered(MouseEvent e) {
        // 鼠標進入表格時的處理
    }
    public void mouseExited(MouseEvent e) {
        // 鼠標退出表格時的處理
    }
    public void mouseClicked(MouseEvent e) {
        // 鼠標點擊時的處理
    }
    });

    posted @ 2010-10-08 08:37 Jamie 閱讀(298) | 評論 (0)編輯 收藏

    Java 獲得本月一日、本星期星期一、昨天的date對象的方法

    GregorianCalendar cal = new GregorianCalendar();
    Date now = new Date();
    cal.setTime(now);
    cal.setFirstDayOfWeek(GregorianCalendar.MONDAY);   // 設置一個星期的第一天為星期1,默認是星期日

    SimpleDateFormat dateutil = new SimpleDateFormat("yyyy-MM-dd");
    System.out.println("now=" + dateutil.format(cal.getTime()));  // 今天

    cal.add(GregorianCalendar.DATE,- 1);
    System.out.println("now=" + dateutil.format(cal.getTime())); // 昨天       

    cal.set(GregorianCalendar.DAY_OF_WEEK,GregorianCalendar.MONDAY);
    System.out.println("now=" + dateutil.format(cal.getTime()));   // 本周1

    cal.set(GregorianCalendar.DAY_OF_MONTH,1);
    System.out.println("now=" + dateutil.format(cal.getTime())); // 本月1日在此鍵入內容

    posted @ 2010-09-21 11:32 Jamie 閱讀(173) | 評論 (0)編輯 收藏

    獲取字符串像素

    Pixel length of String
    import java.awt.FontMetrics;
    import java.awt.geom.Rectangle2D;

    1. awt
     Font font = new Font("Verdana", Font.PLAIN, 10); 
     FontMetrics metrics = new FontMetrics(font) { 
     }; 
     Rectangle2D bounds = metrics.getStringBounds("string", null); 
     int widthInPixels = (int) bounds.getWidth(); 

    文章出處:飛諾網(www.firnow.com):http://dev.firnow.com/course/3_program/java/javajs/20091214/184739.html

    posted @ 2010-09-10 08:26 Jamie 閱讀(535) | 評論 (0)編輯 收藏

    僅列出標題
    共2頁: 上一頁 1 2 
    主站蜘蛛池模板: 久久成人a毛片免费观看网站| 亚洲av日韩专区在线观看| 一级A毛片免费观看久久精品| 日本成人在线免费观看| 色老板亚洲视频免在线观| 成人毛片18岁女人毛片免费看| 亚洲人成网站色在线观看| 无限动漫网在线观看免费| 在线a亚洲老鸭窝天堂av高清| 日产乱码一卡二卡三免费| 午夜亚洲国产理论片二级港台二级| 日本无吗免费一二区| 男男gay做爽爽的视频免费| 亚洲AV无码之日韩精品| 中文字幕高清免费不卡视频| 精品亚洲永久免费精品| 91视频免费网址| 激情综合亚洲色婷婷五月APP| 成人A级毛片免费观看AV网站| 涩涩色中文综合亚洲| 亚洲第一区精品观看| a毛片成人免费全部播放| 久久精品亚洲中文字幕无码网站| 老司机69精品成免费视频| 亚洲日韩在线视频| 在线免费视频一区| 五月天婷婷免费视频| 亚洲AV无码成人精品区天堂| 99久久综合国产精品免费| 美女黄频视频大全免费的| 久久亚洲精品中文字幕三区| 青春禁区视频在线观看直播免费| 精品国产亚洲第一区二区三区| 亚洲乱色熟女一区二区三区丝袜| 麻豆高清免费国产一区| 国产精品观看在线亚洲人成网| 亚洲国产高清人在线| 日韩a级毛片免费观看| 久久国产乱子伦精品免费看| 亚洲a∨国产av综合av下载| 亚洲s色大片在线观看|