前言:
之前一直打算寫一個模擬12306的工具,一直拖到現在,實在忍不了了,最近艱難的一步一步開始。由於想重新學習一下Java相關的知識,所以使用Java來進行開發,目前總算是有了一點進展,已經實現了登錄和查票功能,先記錄一下。下單以及其他搶票設置還在開發中。。。
界面:
本文主要是關注功能的實現,另外就是javaswing的排版也不是很擅長,所以界面比較醜陋,將就看一下就行,目前主要是主界面、登錄界面以及日期選擇界面,先看一下效果:
這裏說明一下,日期選擇控件是從網上找的一片文章拿過來用的,希望不要見怪。文章地址是:DateChooser日期選擇器sw
車站信息:
由於車站信息可能會有變化,包括新增車站或者車站改名之類的,所以要保證車站名稱及對應的車站編號是最新的。
static String getStationUrl = “https://kyfw.12306.cn/otn/resources/js/framework/station_name.js”;
getStationUrl:爲Get請求,沒有參數。用於獲取全國車站名稱信息,後續的查票操作中需要將中文車站名稱轉換爲對應的車站編號。。
登錄模塊:
登錄模塊主要是要解決驗證碼部分,其他都好說。目前已經實現完整的驗證碼選擇、提交以及驗證等功能。突然好像忘了加上驗證碼刷新功能了(後續補上)。當前每請求一次會保存一張驗證碼圖片在src同級的yzm目錄下(目錄需要自己創建),後續可以考慮用這些已有的驗證碼做自動識別,這是後話了。下面按請求順序說一下登錄過程中分別請求的幾個URL:
static String initUrl = “https://kyfw.12306.cn/otn/login/init”;
string String getJsUrl = "https://kyfw.12306.cn/otn/HttpZF/GetJS
static String getRailUrl = “https://kyfw.12306.cn/otn/HttpZF/logdevice”+
“?algID=XWptt1kXbs”+
“&hashCode=K7H-SogpeC4-tIYLqCXJabQWEnBXNROVnaPuQXU8Vec”+
“&FMQw=0”+
“&q4f3=zh-CN”+
“&VPIf=1”+
“&custID=133”+
“&VEek=unknown”+
“&dzuS=0”+
“&yD16=0”+
“&EOQP=89f60554e6cb588cf7dcc391a91488a1”+
“&lEnu=176525634”+
“&jp76=52d67b2a5aa5e031084733d5006cc664”+
“&hAqN=Win32”+
“&platform=WEB”+
“&ks0Q=d22ca0b81584fbea62237b14bd04c866”+
“&TeRS=1010x1680”+
“&tOHY=24xx1050x1680”+
“&Fvje=i1l1o1s1”+
“&q5aJ=-8”+
“&wNLf=99115dfb07133750ba677d055874de87”+
“&0aew=Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/76.0.3809.100%20Safari/537.36”+
“&E3gR=c0e12f6dc8fe327988a902df0d354cec”+
“×tamp=”+String.valueOf(System.currentTimeMillis());
static String getYzmUrl = “https://kyfw.12306.cn/passport/captcha/captcha-image64?”;
static String checkYzmUrl = “https://kyfw.12306.cn/passport/captcha/captcha-check?”;
static String loginUrl = “https://kyfw.12306.cn/passport/web/login”;
initUrl:爲Get請求,沒有參數。用於獲取後面請求中的一些cookie信息。
getJsUrl:爲Get請求,沒有參數。用於請求獲取一個js文件。
getRailUrl:爲Get請求,參數前面都列出來了。用於請求RAIL_DEVICEID和RAIL_EXPIRATION兩個參數,需要將這兩個參數獲取到,然後添加到cookie中,不然在登錄的時候會重定向到https://www.12306.cn/mormhweb/logFiles/error.html,該頁面顯示“網絡可能存在問題,請您重試一下!”。重點關注請求中的algID和hashCode兩個參數,algID可以從getJsUrl這個請求中返回的js文件中拿到,大概位置在:ab.getJSON("https://kyfw.12306.cn/otn/HttpZF/logdevice" + ("?algID\x3dXWptt1kXbs\x26hashCode\x3d" + e + a), null,
hashCode這個參數應該也是衝上述js代碼處獲取到的,但是博主對js文件看不太懂,所以直接用fiddler工具抓了個getRailUrl請求的包,直接從裏面拿出來的hashCode參數。但是這兩個參數應該過一段時間會失效,失效的表現就是在登錄的時候會提示重定向到https://www.12306.cn/mormhweb/logFiles/error.html這個頁面,此時需要重新獲取js文件,重新從js文件裏面獲取這兩個參數,或者通過fiddler工具抓包進行獲取,重新設置到cookie裏面。
getYzmUrl:爲Get請求,需要攜帶{“login_site”:“E”, “module”:“login”, “rand”:“sjrand”, “callback”:“xxx”, "":“xxx”}這五個參數,另外還有個隨機數。用於獲取驗證碼,返回的是一張圖片,圖片頂部爲點擊驗證碼提示語,下部爲8塊區域,分別顯示8張驗證碼。請求URL示例:https://kyfw.12306.cn/passport/captcha/captcha-image64?login_site=E&module=login&rand=sjrand&1565256427784&callback=jQuery19105951551454704869_1565256422938&=1565256422940
checkYzmUrl:爲Get請求,需要攜帶{“callback”:“xxx”, “answer”:“xxx”, “rand”:“sjrand”, “login_site”:“E”, “_”:“xxx”}這五個參數,用於校驗驗證碼。其中answer參數爲驗證碼圖片座標,如:194,54,48,48。返回的字符串中result_code爲4代表驗證成功。(目前返回的是jQuery開頭的一串字符串,其中()中間的部分爲json格式,後面12306可能會有變動)
loginUrl:爲Post請求,需要攜帶{“username”:“xxx”, “password”:“xxx”, “appid”:“otn”, “answer”:“xxx”}這四個參數。answer參數與校驗驗證碼中的answer參數一樣。返回的json中對象中result_code爲0代表登錄成功。(目前返回的爲json格式的數據,後面12306可能會有變動)
關於驗證碼座標的說明:
- 整張圖片的大小是:293*190 單位:像素
- 打字機這一排提示語所在行的寬度爲29
- 第一排第一張小圖片的範圍是(5,41)~(72,108) 長:67,寬:67 間距都是5px
- 第二排第一張小圖片的範圍是(5,41+5+67)~(72,41+5+67+67) 長:67,寬:67 間距都是5px
- 第一排第二張小圖片的範圍是(5+67+5,41)~(5+67+5+67,108) 長:67,寬:67 間距都是5px
查票模塊:
查票模塊目前不添加cookie中的JSESSIONID、RAIL_DEVICEID、RAIL_EXPIRATION也可以查詢成功,但是後續下單包括支付等操作就需要攜帶上述cookie參數。
static queryTicketsUrl = “https://kyfw.12306.cn/otn/leftTicket/query?”;
queryTicketsUrl 爲Get請求,需要攜帶{“leftTicketDTO.train_date”:“xxx”, “leftTicketDTO.from_station”:“xxx”, “leftTicketDTO.to_station”:“xxxx”, “purpose_codes”:“xxx”}這四個參數,分別是出發日期、起始站、終到站和類型。
結尾:
目前只是簡單的實現了登錄和查票功能。包括根據車次類型過濾等小功能都已實現。後續持續更新下單等其他功能模塊,包括界面優化等功能。
代碼:
完整代碼:Java實現12306登錄和查詢功能,在之前代碼之前需要在工程的src同級目錄下創建yzm文件夾,用來保存驗證碼圖片,另外sign.jpg文件爲30*30,可以隨便替換,保證大小一致就行。代碼中用到的第三方jar包主要有:
beangle-bundles-my97-4.8
commons-codec-1.12
commons-httpclient-3.1
commons-logging-1.2
fastjson-1.2.58
httpclient-4.5.5
httpcore-4.4.7
jcalendarbutton-1.4.5
ps:
package my12307;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.Font;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.Vector;
import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.JTextField;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.JTableHeader;
import javax.swing.table.TableModel;
import org.apache.commons.httpclient.HttpException;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
public class My12307 extends JFrame {
private static final long serialVersionUID = 1L;
private JTextField cfdField;
private JTextField mddField;
private DateChooser dc;
private ButtonGroup radioGroup;
private JRadioButton adultRadioButton;
private JRadioButton studentRadioButton;
private JTable table;
private JScrollPane scrollPane;
private String[] headers = {"車次","出發站","到達站","出發時間","到達時間",
"歷時","商務/特等座","一等座","二等座","高級軟臥",
"軟臥","動臥","硬臥","軟座","硬座",
"無座","其他","備註"};
private JCheckBox ck01,ck02,ck03,ck04,ck05,ck06;
private Set<String> ccName;
private Vector<String> tableHeaders;
private HashMap<String, String> cityMap;
private Vector<Vector<String>> gDatas;
public My12307() throws ClientProtocolException, IOException {
initEntity();
initFrame();
Utils.initLogin();
Utils.initRail();
}
//獲取車站信息
private void getStationInfo() {
HttpGet httpGet = new HttpGet(Utils.getStationUrl);
try {
CloseableHttpResponse cHttpResp = Utils.getHttpClient().execute(httpGet);
HttpEntity entity = cHttpResp.getEntity();
String result = EntityUtils.toString(entity,"utf-8");
Utils.putStation2Map(result, cityMap);
} catch (IOException e) {
e.printStackTrace();
}
}
private void initEntity(){
ccName = new HashSet<String>();
cityMap = new HashMap<String, String>();
gDatas = new Vector<Vector<String>>();
tableHeaders = new Vector<String>();
for (int i = 0; i < headers.length; i++) {
tableHeaders.add(i, headers[i]);
}
}
private void initFrame() {
this.setDefaultCloseOperation(EXIT_ON_CLOSE);
int width = 1000;
int height = 660;
Dimension d = Toolkit.getDefaultToolkit().getScreenSize();//獲得屏幕尺寸
setBounds((d.width - width)/2, (d.height - height)/2, width, height);
getContentPane().setLayout(new BorderLayout());
this.setTitle("12307票票");
this.setResizable(false);
this.setIconImage(new ImageIcon("src/icon.jpg").getImage());
JMenuBar menubar = new JMenuBar();
JMenu menuDL = new JMenu("登錄");
//JMenu menuTC = new JMenu("退出");
JMenu menuQueryM = new JMenu("查詢聯繫人");
menubar.add(menuDL);
//menubar.add(menuTC);
menubar.add(menuQueryM);
this.setJMenuBar(menubar);
addLoginListener(My12307.this, menuDL);
//addLogoutListener(menuTC);
addQueryMListener(menuQueryM);
JPanel topPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 2, 5));
topPanel.setPreferredSize(new Dimension(1000,70));
JPanel centerPanel = new JPanel();
centerPanel.setPreferredSize(new Dimension(1000,380));
JPanel bottomPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 1, 5));
bottomPanel.setPreferredSize(new Dimension(1000,210));
//出發地,目的地
JLabel label1 = new JLabel("出發地:");
JLabel label2 = new JLabel("目的地:");
cfdField = new JTextField();
cfdField.setPreferredSize(new Dimension(cfdField.getWidth(),25));
cfdField.setColumns(10);
mddField = new JTextField();
mddField.setPreferredSize(new Dimension(mddField.getWidth(),25));
mddField.setColumns(10);
//成人,學生
radioGroup = new ButtonGroup();
adultRadioButton = new JRadioButton("成人");
studentRadioButton = new JRadioButton("學生");
radioGroup.add(adultRadioButton);
radioGroup.add(studentRadioButton);
adultRadioButton.setSelected(true);
//出發日期
JLabel label3 = new JLabel("出發日期:");
dc = new DateChooser("yyyy-MM-dd");
//查詢
JButton queryBbutton = new JButton("查詢");
addButtonListener(queryBbutton);
//車次類型
JLabel label4 = new JLabel("車次類型:");
JPanel panel1 = new JPanel();
ck01 = new JCheckBox("GC-高鐵/城際");
ck02 = new JCheckBox("D-動車");
ck03 = new JCheckBox("Z-直達");
ck04 = new JCheckBox("T-特快");
ck05 = new JCheckBox("K-快速");
ck06 = new JCheckBox("其他");
ck01.setName("GC");
ck02.setName("D");
ck03.setName("Z");
ck04.setName("T");
ck05.setName("K");
addCheckboxListener(ck01);
addCheckboxListener(ck02);
addCheckboxListener(ck03);
addCheckboxListener(ck04);
addCheckboxListener(ck05);
addCheckboxListener(ck06);
panel1.add(ck01);
panel1.add(ck02);
panel1.add(ck03);
panel1.add(ck04);
panel1.add(ck05);
panel1.add(ck06);
JPanel panel2 = new JPanel();
panel2.add(label4);
panel2.add(panel1);
topPanel.add(label1);
topPanel.add(cfdField);
topPanel.add(label2);
topPanel.add(mddField);
topPanel.add(adultRadioButton);
topPanel.add(studentRadioButton);
topPanel.add(label3);
topPanel.add(dc);
topPanel.add(queryBbutton);
topPanel.add(panel2);
//查票查詢table
String[][] content = new String[0][18];
TableModel model = new DefaultTableModel(content, tableHeaders.toArray());
table = new JTable();
DefaultTableCellRenderer tcr = new DefaultTableCellRenderer();
tcr.setHorizontalAlignment(SwingConstants.CENTER);
table.setDefaultRenderer(Object.class, tcr);
table.setRowHeight(30); //設置行高
JTableHeader tableHeader = table.getTableHeader();
tableHeader.setResizingAllowed(false);
tableHeader.setReorderingAllowed(false);
tableHeader.setFont(new Font("宋體", 0, 12));
tableHeader.setForeground(new Color(255,255,255));//設置字體顏色
tableHeader.setBackground(new Color(33,132,199)); //設置背景顏色
tableHeader.setPreferredSize(new Dimension(tableHeader.getHeight(),40));
table.setModel(model);
Utils.setTableColumnWidth(tableHeaders, table);
scrollPane = new JScrollPane(table) {
private static final long serialVersionUID = 1L;
public Dimension getPreferredSize() {
return new Dimension(990, 312);
}
};
centerPanel.add(scrollPane);
//搶票條件設置區
JPanel passengerPanel = new JPanel();
JPanel seatTypePanel = new JPanel();
passengerPanel.setBorder(BorderFactory.createTitledBorder("聯繫人"));
seatTypePanel.setBorder(BorderFactory.createTitledBorder("席別"));
passengerPanel.setPreferredSize(new Dimension(100,200));
seatTypePanel.setPreferredSize(new Dimension(100,200));
bottomPanel.add(passengerPanel);
bottomPanel.add(seatTypePanel);
getContentPane().add(topPanel, BorderLayout.NORTH);
getContentPane().add(centerPanel, BorderLayout.CENTER);
getContentPane().add(bottomPanel, BorderLayout.SOUTH);
//獲取車站信息
getStationInfo();
}
private void addLoginListener(JFrame frame, JMenu menu) {
menu.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
System.out.println("點擊登錄");
LoginDialog loginDialog;
try {
loginDialog = new LoginDialog(My12307.this);
loginDialog.setVisible(true);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
private void addTableRowListener(JTable table) {
table.addMouseListener(new MouseAdapter() {
@Override
public void mouseClicked(MouseEvent e) {
table.setSelectionBackground(new Color(135,206,250));
int row = table.getSelectedRow();
int col = table.getSelectedColumn();
System.out.println("點擊第"+row+"行"+",第"+col+"列");
}
});
}
private void addCheckboxListener(JCheckBox checkbox) {
checkbox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
String chName = checkbox.getName();
if("GC".equals(chName)) {
if(checkbox.isSelected()) {
ccName.add("G");
ccName.add("C");
}else {
ccName.remove("G");
ccName.remove("C");
}
}else {
if(checkbox.isSelected()) {
ccName.add(chName);
}else {
ccName.remove(chName);
}
}
//過濾數據
if(!gDatas.isEmpty()) {
filterDataByCheckBox();
addTableRowListener(table);
}
}
});
}
private void addButtonListener(JButton button) {
button.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
//清空table
((DefaultTableModel)table.getModel()).getDataVector().clear();
table.updateUI();
//String trainDate = new SimpleDateFormat("yyyy-MM-dd").format(new Date()).toString();
String trainDate = dc.showDate.getText();
String fromStationName = cfdField.getText();
String toStationName = mddField.getText();
String fromStation = cityMap.get(fromStationName);
String toStation = cityMap.get(toStationName);
if ("".equals(fromStationName) || fromStation == null) {
System.out.println("出發車站名有誤,請重新輸入。");
return;
}
if ("".equals(toStationName) || toStation == null) {
System.out.println("目的車站名有誤,請重新輸入。");
return;
}
String type = "";
if(radioGroup.getSelection() == adultRadioButton.getModel()) {
type = "ADULT";
}else {
type = "0X00";
}
String queryTicketsUrl = Utils.queryTicketsUrl+"leftTicketDTO.train_date=" + trainDate
+ "&leftTicketDTO.from_station=" + fromStation + "&leftTicketDTO.to_station="
+ toStation + "&purpose_codes=" + type;
try {
System.out.println(queryTicketsUrl);
sendQueryTicketRequest(queryTicketsUrl);
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
private void colloctionData(Vector<String> row, String[] resultData) {
row.add(tableHeaders.indexOf("車次"), resultData[3]);
row.add(tableHeaders.indexOf("出發站"), Utils.getKeyFromMap(cityMap,resultData[6]));
row.add(tableHeaders.indexOf("到達站"), Utils.getKeyFromMap(cityMap,resultData[7]));
row.add(tableHeaders.indexOf("出發時間"), resultData[8]);
row.add(tableHeaders.indexOf("到達時間"), resultData[9]);
row.add(tableHeaders.indexOf("歷時"), resultData[10]);
if(resultData[32] != "") {
row.add(tableHeaders.indexOf("商務/特等座"), ("".equals(resultData[32]))?"--":resultData[32]);
}else {
row.add(tableHeaders.indexOf("商務/特等座"), ("".equals(resultData[25]))?"--":resultData[25]);
}
row.add(tableHeaders.indexOf("一等座"), ("".equals(resultData[31]))?"--":resultData[31]);
row.add(tableHeaders.indexOf("二等座"), ("".equals(resultData[30]))?"--":resultData[30]);
row.add(tableHeaders.indexOf("高級軟臥"), ("".equals(resultData[21]))?"--":resultData[21]);
row.add(tableHeaders.indexOf("軟臥"), ("".equals(resultData[23]))?"--":resultData[23]);
row.add(tableHeaders.indexOf("動臥"), ("".equals(resultData[27]))?"--":resultData[27]);
row.add(tableHeaders.indexOf("硬臥"), ("".equals(resultData[28]))?"--":resultData[28]);
row.add(tableHeaders.indexOf("軟座"), ("".equals(resultData[24]))?"--":resultData[24]);
row.add(tableHeaders.indexOf("硬座"), ("".equals(resultData[29]))?"--":resultData[29]);
row.add(tableHeaders.indexOf("無座"), ("".equals(resultData[26]))?"--":resultData[26]);
row.add(tableHeaders.indexOf("其他"), ("".equals(resultData[22]))?"--":resultData[22]);
//row.add(tableHeaders.indexOf("備註"), resultData[1]);
gDatas.add(row);
}
@SuppressWarnings("unchecked")
private void fillData2Table() {
if (!gDatas.isEmpty()) {
Vector<Vector<String>> datas = new Vector<Vector<String>>();
datas = (Vector<Vector<String>>) gDatas.clone();
DefaultTableModel model = new DefaultTableModel(){
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
model.setDataVector(datas, tableHeaders);
table.setModel(model);
Utils.setTableColumnWidth(tableHeaders, table);
}
}
@SuppressWarnings("unchecked")
private void filterDataByCheckBox() {
Vector<Vector<String>> ckData = new Vector<Vector<String>>();
for(Vector<String> v : gDatas) {
if(ccName.contains(v.get(0).toString().charAt(0)+"")) {
ckData.add(v);
}
}
if (ckData.isEmpty() &&
(!ck01.isSelected() && !ck02.isSelected() && !ck03.isSelected() &&
!ck04.isSelected() && !ck05.isSelected() && !ck06.isSelected())) {
ckData = (Vector<Vector<String>>) gDatas.clone();
}
((DefaultTableModel)table.getModel()).getDataVector().clear();
DefaultTableModel model = new DefaultTableModel(){
private static final long serialVersionUID = 1L;
@Override
public boolean isCellEditable(int row, int column) {
return false;
}
};
model.setDataVector(ckData, tableHeaders);
table.setModel(model);
Utils.setTableColumnWidth(tableHeaders, table);
}
private void sendQueryTicketRequest(String url) throws HttpException, IOException {
HttpGet get = new HttpGet(url);
CloseableHttpResponse response = Utils.getHttpClient().execute(get);
int statusCode = response.getStatusLine().getStatusCode();
String result = "";
if (statusCode == HttpStatus.SC_OK) {
System.out.println("查票成功.");
result = EntityUtils.toString(response.getEntity());
}else {
System.out.println("查票失敗,url="+url+",statusCode="+statusCode);
return;
}
JSONObject obj = JSON.parseObject(result);
JSONArray array = obj.getJSONObject("data").getJSONArray("result");
int len = array.size();
//獲取車次信息在3號位置,始發站信息在6號位置,終點站信息在7號位置,出發時間在8號位置,抵達時間在9號位置
//經歷時間在10號位置,特別注意,商務/特等座在32或25位置,一等座信息在31號位置,二等座信息在30號位置
//高級軟臥信息在21號位置,軟臥信息在23號位置,動臥信息在27號位置,硬臥信息在28號位置
//軟座信息在24號位置,硬座信息在29號位置,無座信息在26號位置,其他信息在22號位置,備註信息在1號位置
gDatas.clear();
for(int i = 0; i < len; i++) {
Vector<String> row = new Vector<String>();
String[] resultData = array.get(i).toString().split("\\|");
//收集數據
colloctionData(row, resultData);
}
//填充數據
fillData2Table();
//根據複選框過濾數據
if (ck01.isSelected() || ck02.isSelected() || ck03.isSelected() ||
ck04.isSelected() || ck05.isSelected() || ck06.isSelected()) {
filterDataByCheckBox();
}
//給數據添加背景色
Utils.setBackgoundColorForTable(table);
//添加行點擊監聽
addTableRowListener(table);
obj.clear();
}
private void addQueryMListener(JMenu menu) {
menu.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
try {
sendQueryPassengersRequest();
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
private void sendQueryPassengersRequest() throws ClientProtocolException, IOException {
HttpPost post = new HttpPost(Utils.queryPassengersUrl);
List<NameValuePair> formPair = new ArrayList<NameValuePair>();
formPair.add(new BasicNameValuePair("pageIndex", "1"));
formPair.add(new BasicNameValuePair("pageSize", "15"));
UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
post.setEntity(urlEntity);
Utils.setPostRequestHeaders(post);
CloseableHttpResponse response;
response = Utils.getHttpClient().execute(post);
int respCode = response.getStatusLine().getStatusCode();
if(respCode == HttpStatus.SC_OK) {
JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
if(Integer.parseInt(obj.getString("httpstatus")) == 200) {
System.out.println("獲取聯繫人成功");
System.out.println(obj.toString());
}else {
System.out.println("獲取聯繫人失敗");
}
}else {
System.out.println("獲取聯繫人失敗");
}
}
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
My12307 frame = new My12307();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
}
package my12307;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Base64;
import java.util.Base64.Decoder;
import java.util.List;
import javax.swing.BorderFactory;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
import javax.swing.JPasswordField;
import javax.swing.JTextField;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class LoginDialog extends JDialog{
private static final long serialVersionUID = 1L;
private JTextField userField;
private JPasswordField pswdField;
private JPanel imagePanel;
private JLabel imageLabel;
private Icon icon;
private int X = 10;
private int Y = 15;
private JLayeredPane layeredPane = new JLayeredPane();;
private StringBuffer callback = new StringBuffer("jQuery19107521990954709705_");
private String random = "";
private String random2 = "";
private String yzmAnswer;
private void initFrame(JFrame parent) throws ClientProtocolException, IOException{
userField = new JTextField(15);
pswdField = new JPasswordField(15);
JLabel userLabel = new JLabel("用戶名:");
JLabel pswdLabel = new JLabel("密 碼::");
JButton loginButton = new JButton("登錄");
JButton cancelButton = new JButton("取消");
addLoginButtonListener(loginButton);
addCancelButtonListener(cancelButton);
JPanel inputPanel = new JPanel(new GridLayout(2, 2, -90, 15));
JPanel buttonPanel = new JPanel(new GridLayout(1, 2, 10, 0));
imagePanel = new JPanel(new GridLayout(1, 1, 10, 0));
inputPanel.add(userLabel);
inputPanel.add(userField);
inputPanel.add(pswdLabel);
inputPanel.add(pswdField);
inputPanel.setBorder(BorderFactory.createEmptyBorder(X, Y, 10, 15));
buttonPanel.add(loginButton);
buttonPanel.add(cancelButton);
buttonPanel.setBorder(BorderFactory.createEmptyBorder(X, Y, 10, 15));
setLayout(new BorderLayout());
getContentPane().add(inputPanel, BorderLayout.NORTH);
getContentPane().add(buttonPanel, BorderLayout.CENTER);
getYzmBindListener();
int parentX = parent.getX();
int parentY = parent.getY();
int parentWidth = (int)parent.getWidth();
int parentHeight = (int)parent.getHeight();
int childWidth = 280;
int childHight = 300;
int childX = parentX + parentWidth/2 - childWidth/2;
int childY = parentY + parentHeight/2 - childHight/2;
setBounds(childX, childY, childWidth, childHight);
setTitle("登錄");
setResizable(false);
pack();
YzmUtils.initYzm(layeredPane);
}
public LoginDialog(JFrame parent) throws ClientProtocolException, IOException {
super(parent, true);
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
if(Utils.cookieStore.getCookies().size() == 0) {
try {
Utils.initLogin();
Utils.initRail();
} catch (IOException e1) {
e1.printStackTrace();
}
}
initFrame(parent);
}
private void clearYzmPanel(){
YzmUtils.yzm1 = 0;
YzmUtils.yzm2 = 0;
YzmUtils.yzm3 = 0;
YzmUtils.yzm4 = 0;
YzmUtils.yzm5 = 0;
YzmUtils.yzm6 = 0;
YzmUtils.yzm7 = 0;
YzmUtils.yzm8 = 0;
imagePanel.removeAll();
layeredPane.removeAll();
}
@SuppressWarnings("deprecation")
//獲取驗證碼圖片並綁定點擊驗證碼事件
private void getYzmBindListener() throws ClientProtocolException, IOException {
clearYzmPanel();
String image = getYzmImage();
imageLabel = new JLabel();
icon = new ImageIcon(image);
imageLabel.setIcon(icon);
addLabelListener(imageLabel);//監聽驗證碼點擊事件
imagePanel.add(imageLabel);
imagePanel.setBounds(0, 0, icon.getIconWidth(), icon.getIconHeight());
Dimension dimension = new Dimension(icon.getIconWidth(), icon.getIconHeight());
layeredPane.setPreferredSize(dimension);
layeredPane.add(imagePanel, new Integer(0));
getContentPane().add(layeredPane, BorderLayout.SOUTH);
YzmUtils.initYzm(layeredPane);
}
private void addLabelListener(JLabel imageLbel) {
imageLbel.addMouseListener(new MouseListener() {
@Override
public void mouseReleased(MouseEvent e) {
}
@Override
public void mousePressed(MouseEvent e) {
}
@Override
public void mouseExited(MouseEvent e) {
}
@Override
public void mouseEntered(MouseEvent e) {
}
@Override
public void mouseClicked(MouseEvent e) {
YzmUtils.addSign2Yzm(e);
}
});
}
private void addCancelButtonListener(JButton cancelButton) {
cancelButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
LoginDialog.this.dispose();
}
});
}
private String login12306(String username, String password) throws IOException {
String uamtk = "";
HttpPost post = new HttpPost(Utils.loginUrl);
List<NameValuePair> formPair = new ArrayList<NameValuePair>();
formPair.add(new BasicNameValuePair("username", username));
formPair.add(new BasicNameValuePair("password", password));
formPair.add(new BasicNameValuePair("appid", "otn"));
formPair.add(new BasicNameValuePair("answer", yzmAnswer));
UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
post.setEntity(urlEntity);
Utils.setPostRequestHeaders(post);
CloseableHttpResponse response;
int respCode = 0;
int loop = 5;
while(loop > 0) {
response = Utils.getHttpClient().execute(post);
respCode = response.getStatusLine().getStatusCode();
JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
if(respCode == HttpStatus.SC_OK) {
if("0".equals(obj.getString("result_code"))) {
System.out.println("登錄成功,result_code:"+respCode+"result_message:"+
obj.getString("result_message")+"uamtk:"+obj.getString("uamtk"));
uamtk = obj.getString("uamtk");
this.setVisible(false);
return uamtk;
}else {
System.out.println("登錄失敗,result_code="+obj.getString("result_code")+",result_message:"+obj.getString("result_message"));
//getYzmBindListener();
break;
}
}else if(respCode == HttpStatus.SC_MOVED_TEMPORARILY){
System.out.println("請求登錄重定向,Location:"+response.getFirstHeader("Location").getValue());
//getYzmBindListener();
loop--;
}else {
System.out.println("登錄失敗,respCode="+respCode+",result_message:"+obj.getString("result_message"));
//getYzmBindListener();
break;
}
}
getYzmBindListener();
return uamtk;
}
private void addLoginButtonListener(JButton loginButton) {
loginButton.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//校驗驗證碼url爲:https://kyfw.12306.cn/passport/captcha/captcha-check
yzmAnswer = YzmUtils.getYzmAnswer();
if ("".equals(yzmAnswer)) {
System.out.println("請先選擇驗證碼後再登錄");
return;
}
random2 = String.valueOf(Long.parseLong(random2)+1);
String checkYzmUrl = Utils.checkYzmUrl+"callback="+callback+
"&answer="+yzmAnswer+"&rand=sjrand&login_site=E&_="+random2;
System.out.println("校驗驗證碼的url:"+checkYzmUrl);
HttpGet get = new HttpGet(checkYzmUrl);
Utils.setGetRequestHeaders(get);
// 通過請求對象獲取響應對象
String[] res = null;
String result = "";
CloseableHttpResponse response;
try {
response = Utils.getHttpClient().execute(get);
int respCode = response.getStatusLine().getStatusCode();
HttpEntity entity = null;
if (respCode == HttpStatus.SC_OK) {
entity = response.getEntity();
result = EntityUtils.toString(entity);
System.out.println("result:"+result);
res = result.split("\"");
}else {
System.out.println("驗證失敗,statusCode="+respCode);
getYzmBindListener();
}
if ("4".contentEquals(res[7])) {
System.out.println("驗證成功,result_message="+res[3]);
String username = userField.getText();
String password = new String(pswdField.getPassword());
//saveCookies();
String uamtk = login12306(username, password);
if(!"".equals(uamtk)) {
sendGetUamTkRequest();
}
}else {
System.out.println("驗證失敗,result_message="+res[3]);
getYzmBindListener();
}
} catch (IOException e1) {
e1.printStackTrace();
}
}
});
}
private void sendGetUamTkRequest() throws ClientProtocolException, IOException {
HttpPost post = new HttpPost(Utils.getUamTk);
List<NameValuePair> formPair = new ArrayList<NameValuePair>();
formPair.add(new BasicNameValuePair("appid", "otn"));
UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
post.setEntity(urlEntity);
Utils.setPostRequestHeaders(post);
CloseableHttpResponse response;
response = Utils.getHttpClient().execute(post);
int respCode = response.getStatusLine().getStatusCode();
JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
if(respCode == HttpStatus.SC_OK) {
System.out.println("獲取uamtk成功,result_code:"+respCode+"result_message:"+
obj.getString("result_message")+"newapptk:"+obj.getString("newapptk"));
String newAppTk = obj.getString("newapptk");
sendUamAuthClientRequest(newAppTk);
}else {
System.out.println("獲取uamtk失敗,respCode="+respCode+"result_message:"+obj.getString("result_message"));
}
}
private void sendUamAuthClientRequest(String newAppTk) throws ClientProtocolException, IOException {
HttpPost post = new HttpPost(Utils.uamAuthClient);
List<NameValuePair> formPair = new ArrayList<NameValuePair>();
formPair.add(new BasicNameValuePair("tk", newAppTk));
UrlEncodedFormEntity urlEntity = new UrlEncodedFormEntity(formPair, "UTF-8");
post.setEntity(urlEntity);
Utils.setPostRequestHeaders(post);
CloseableHttpResponse response;
response = Utils.getHttpClient().execute(post);
int respCode = response.getStatusLine().getStatusCode();
JSONObject obj = JSONObject.parseObject(EntityUtils.toString(response.getEntity()));
if(respCode == HttpStatus.SC_OK) {
System.out.println("uamAuth成功,result_code:"+respCode+"result_message:"+obj.getString("result_message")+
"newapptk:"+obj.getString("newapptk")+"username:"+obj.getString("username"));
//saveCookies();
}else {
System.out.println("uamAuth失敗,respCode="+respCode+"result_message:"+obj.getString("result_message"));
}
}
private String getYzmImage() throws ClientProtocolException, IOException {
random = String.valueOf(System.currentTimeMillis());
random2 = random;
random2 = String.valueOf(Long.parseLong(random2)+1);
callback.append(random);
String getYzmUrl = Utils.getYzmUrl+"login_site=E&module=login&rand=sjrand&"
+random+"callback="+callback+"&_="+random2;
System.out.println("請求驗證碼的url:"+getYzmUrl);
HttpGet getMethod = new HttpGet(getYzmUrl);
Utils.setGetRequestHeaders(getMethod);
CloseableHttpClient client = Utils.getHttpClient();
Utils.printCookies();
CloseableHttpResponse response = client.execute(getMethod);
HttpEntity entity = null;
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
entity = response.getEntity();
System.out.println("獲取驗證碼成功.");
}else {
System.out.println("獲取驗證碼失敗,url="+getYzmUrl+",statusCode="+statusCode);
return "";
}
JSONObject obj = JSON.parseObject(EntityUtils.toString(entity));
Decoder decoder = Base64.getDecoder();
try {
//Base64解碼
byte[] b = decoder.decode(obj.getString("image"));
for(int i = 0; i < b.length; ++i){
if(b[i] < 0){//調整異常數據
b[i] += 256;
}
}
//生成jpg圖片
String imgFilePath = "yzm/yzm_"+random+".jpg";//新生成的圖片
OutputStream out = new FileOutputStream(imgFilePath);
out.write(b);
out.flush();
out.close();
return imgFilePath;
} catch (Exception e){
}
obj.clear();
return "";
}
}
package my12307;
import java.awt.Color;
import java.awt.Component;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JPanel;
import javax.swing.JTable;
import javax.swing.SwingConstants;
import javax.swing.table.DefaultTableCellRenderer;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.CookieStore;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.BasicCookieStore;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.impl.cookie.BasicClientCookie;
import org.apache.http.util.EntityUtils;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
public class Utils {
static CookieStore cookieStore = new BasicCookieStore();
static CloseableHttpClient httpClient = HttpClients.custom().setDefaultCookieStore(cookieStore).build();
static String accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
static String acceptEncoding = "gzip, deflate, br";
static String acceptLanguage = "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2";
static String userAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:68.0) Gecko/20100101 Firefox/68.0";
//url
static String getStationUrl = "https://kyfw.12306.cn/otn/resources/js/framework/station_name.js";
static String queryTicketsUrl = "https://kyfw.12306.cn/otn/leftTicket/query?";
static String getRailUrl = "https://kyfw.12306.cn/otn/HttpZF/logdevice"+
//"?algID=8iIPwpB28l"+
"?algID=XWptt1kXbs"+
//"&hashCode=XQTW18RSf_dOYnqpGaj_yA-WKSsKbH77QE7zN-cCdB0"+
"&hashCode=K7H-SogpeC4-tIYLqCXJabQWEnBXNROVnaPuQXU8Vec"+
"&FMQw=0"+
"&q4f3=zh-CN"+
"&VPIf=1"+
"&custID=133"+
"&VEek=unknown"+
"&dzuS=0"+
"&yD16=0"+
"&EOQP=89f60554e6cb588cf7dcc391a91488a1"+
"&lEnu=176525634"+
"&jp76=52d67b2a5aa5e031084733d5006cc664"+
"&hAqN=Win32"+
"&platform=WEB"+
"&ks0Q=d22ca0b81584fbea62237b14bd04c866"+
"&TeRS=1010x1680"+
"&tOHY=24xx1050x1680"+
"&Fvje=i1l1o1s1"+
"&q5aJ=-8"+
"&wNLf=99115dfb07133750ba677d055874de87"+
"&0aew=Mozilla/5.0%20(Windows%20NT%2010.0;%20Win64;%20x64)%20AppleWebKit/537.36%20(KHTML,%20like%20Gecko)%20Chrome/76.0.3809.100%20Safari/537.36"+
"&E3gR=a54e6d6499e595ae2cfaf80eda685cc2"+
"×tamp="+String.valueOf(System.currentTimeMillis());
static String initUrl = "https://kyfw.12306.cn/otn/login/init";
static String loginUrl = "https://kyfw.12306.cn/passport/web/login";
static String logoutUrl = "https://kyfw.12306.cn/otn/login/conf";
static String logoutUamtk = "https://kyfw.12306.cn/passport/web/auth/uamtk-static";
static String getYzmUrl = "https://kyfw.12306.cn/passport/captcha/captcha-image64?";
static String checkYzmUrl = "https://kyfw.12306.cn/passport/captcha/captcha-check?";
static String getUamTk = "https://kyfw.12306.cn/passport/web/auth/uamtk";
static String uamAuthClient = "https://kyfw.12306.cn/otn/uamauthclient";
static String queryPassengersUrl = "https://kyfw.12306.cn/otn/passengers/query";
static CloseableHttpClient getHttpClient() {
return httpClient;
}
static CookieStore getCookieStore() {
return cookieStore;
}
static void addRailCookies(String exp, String dfp) {
BasicClientCookie expCookie = new BasicClientCookie("RAIL_EXPIRATION", exp);
expCookie.setDomain("kyfw.12306.cn");
expCookie.setPath("/");
cookieStore.addCookie(expCookie);
BasicClientCookie dfpCookie = new BasicClientCookie("RAIL_DEVICEID", dfp);
dfpCookie.setDomain("kyfw.12306.cn");
dfpCookie.setPath("/");
cookieStore.addCookie(dfpCookie);
}
static void setGetRequestHeaders(HttpGet get) {
get.addHeader("Accept",Utils.accept);
get.addHeader("Accept-Encoding", Utils.acceptEncoding);
get.addHeader("Accept-Language", Utils.acceptLanguage);
get.addHeader("User-Agent",Utils.userAgent);
}
static void setPostRequestHeaders(HttpPost post) {
post.addHeader("Accept",Utils.accept);
post.addHeader("Accept-Encoding", Utils.acceptEncoding);
post.addHeader("Accept-Language", Utils.acceptLanguage);
post.addHeader("User-Agent",Utils.userAgent);
}
static void initLogin() throws ClientProtocolException, IOException {
HttpGet getMethod = new HttpGet(Utils.initUrl);
Utils.setGetRequestHeaders(getMethod);
CloseableHttpResponse response = Utils.getHttpClient().execute(getMethod);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
System.out.println("初始化12306成功.");
Utils.printCookies();
}else {
System.out.println("初始化12306失敗,url="+Utils.initUrl+",statusCode="+statusCode);
return;
}
}
static void initRail() throws ClientProtocolException, IOException {
//獲取RAIL_DEVICEID和RAIL_EXPIRATION
//String getJsUrl = "https://kyfw.12306.cn/otn/HttpZF/GetJS";
HttpGet get = new HttpGet(Utils.getRailUrl);
Utils.setGetRequestHeaders(get);
CloseableHttpResponse response = Utils.getHttpClient().execute(get);
int statusCode = response.getStatusLine().getStatusCode();
if (statusCode == HttpStatus.SC_OK) {
System.out.println("GetJS成功.");
Utils.printCookies();
String resStr = EntityUtils.toString(response.getEntity());
String str = resStr.substring(resStr.indexOf("{"),resStr.indexOf("}")+1);
System.out.println(str);
JSONObject obj = JSON.parseObject(str);
Utils.addRailCookies(obj.getString("exp"), obj.getString("dfp"));
obj.clear();
}else {
System.out.println("GetJS失敗,url="+Utils.getRailUrl+",statusCode="+statusCode);
return;
}
}
static void printCookies() {
System.out.println("打印cookie信息:");
List<org.apache.http.cookie.Cookie> cs = Utils.getCookieStore().getCookies();
for (int i = 0; i < cs.size(); i++) {
System.out.println(cs.get(i).getName()+":"+cs.get(i).getValue());
}
}
static void clearCookies() {
System.out.println("清空cookie信息");
cookieStore.clear();
}
static void putStation2Map(String result, HashMap<String, String> cityMap) {
int startIdx = result.indexOf("'");
int endIdx = result.length();
String city = result.substring(startIdx, endIdx);
String[] c = city.split("@");
for(int i = 1; i < c.length; i++) {
String[] cc = c[i].split("\\|");
cityMap.put(cc[1], cc[2]);
}
}
static String getKeyFromMap(HashMap<String, String> map, String value) {
for(String getKey: map.keySet()) {
if(map.get(getKey).equals(value)) {
return getKey;
}
}
return "";
}
static void setTableColumnWidth(Vector<String> tableHeaders, JTable table) {
table.getColumn(tableHeaders.get(1)).setPreferredWidth(55);
table.getColumn(tableHeaders.get(2)).setPreferredWidth(55);
table.getColumn(tableHeaders.get(7)).setPreferredWidth(55);
table.getColumn(tableHeaders.get(8)).setPreferredWidth(55);
table.getColumn(tableHeaders.get(9)).setPreferredWidth(60);
table.getColumn(tableHeaders.get(10)).setPreferredWidth(45);
table.getColumn(tableHeaders.get(11)).setPreferredWidth(45);
table.getColumn(tableHeaders.get(12)).setPreferredWidth(45);
table.getColumn(tableHeaders.get(13)).setPreferredWidth(45);
table.getColumn(tableHeaders.get(14)).setPreferredWidth(45);
table.getColumn(tableHeaders.get(15)).setPreferredWidth(45);
table.getColumn(tableHeaders.get(16)).setPreferredWidth(45);
}
static void setBackgoundColorForTable(JTable table) {
DefaultTableCellRenderer tcr = new DefaultTableCellRenderer() {
private static final long serialVersionUID = 1L;
@Override
public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected,
boolean hasFocus, int row, int column) {
//return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
JButton button;
JPanel panel;
Component cell = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
if (row % 2 == 0) {
setBackground(Color.white); //設置奇數行底色
}
else if (row % 2 == 1) {
setBackground(new Color(238,241,248)); //設置偶數行底色
}
//設置'有'和'無'的顏色
if (value != null && column >= 6 && column <= 16) {
if("--".equals(value.toString()) || "無".equals(value.toString())) {
setForeground(new Color(153,153,153));
}else if("有".equals(value.toString())) {
setForeground(new Color(38,163,6));
}else { //數字
setForeground(Color.black);
}
}else {
setForeground(Color.black);
}
//添加預定按鈕
if (column == 17) {
Object obj6 = table.getModel().getValueAt(row, 6);
Object obj7 = table.getModel().getValueAt(row, 7);
Object obj8 = table.getModel().getValueAt(row, 8);
Object obj9 = table.getModel().getValueAt(row, 9);
Object obj10 = table.getModel().getValueAt(row, 10);
Object obj11 = table.getModel().getValueAt(row, 11);
Object obj12 = table.getModel().getValueAt(row, 12);
Object obj13 = table.getModel().getValueAt(row, 13);
Object obj14 = table.getModel().getValueAt(row, 14);
Object obj15 = table.getModel().getValueAt(row, 15);
if ( (obj6 != null) && (!"--".equals(obj6.toString())) && (!"無".equals(obj6.toString())) &&
(("有".equals(obj6.toString())) || (Integer.parseInt(obj6.toString()) > 0)) ||
(obj7 != null) && (!"--".equals(obj7.toString())) && (!"無".equals(obj7.toString())) &&
(("有".equals(obj7.toString())) || (Integer.parseInt(obj7.toString()) > 0)) ||
(obj8 != null) && (!"--".equals(obj8.toString())) && (!"無".equals(obj8.toString())) &&
(("有".equals(obj8.toString())) || (Integer.parseInt(obj8.toString()) > 0)) ||
(obj9 != null) && (!"--".equals(obj9.toString())) && (!"無".equals(obj9.toString())) &&
(("有".equals(obj9.toString())) || (Integer.parseInt(obj9.toString()) > 0)) ||
(obj10 != null) && (!"--".equals(obj10.toString())) && (!"無".equals(obj10.toString())) &&
(("有".equals(obj10.toString())) || (Integer.parseInt(obj10.toString()) > 0)) ||
(obj11 != null) && (!"--".equals(obj11.toString())) && (!"無".equals(obj11.toString())) &&
(("有".equals(obj11.toString())) || (Integer.parseInt(obj11.toString()) > 0)) ||
(obj12 != null) && (!"--".equals(obj12.toString())) && (!"無".equals(obj12.toString())) &&
(("有".equals(obj12.toString())) || (Integer.parseInt(obj12.toString()) > 0)) ||
(obj13 != null) && (!"--".equals(obj13.toString())) && (!"無".equals(obj13.toString())) &&
(("有".equals(obj13.toString())) || (Integer.parseInt(obj13.toString()) > 0)) ||
(obj14 != null) && (!"--".equals(obj14.toString())) && (!"無".equals(obj14.toString())) &&
(("有".equals(obj14.toString())) || (Integer.parseInt(obj14.toString()) > 0)) ||
(obj15 != null) && (!"--".equals(obj15.toString())) && (!"無".equals(obj15.toString())) &&
(("有".equals(obj15.toString())) || (Integer.parseInt(obj15.toString()) > 0)) ){
panel = new JPanel();
button = new JButton();
button.setText("預定");
button.setForeground(Color.white);
button.setBackground(new Color(0,119,255));
panel.add(button, SwingConstants.CENTER);
return panel;
}else {
setForeground(new Color(153,153,153));
setValue("預定");
}
}
return cell;
}
};
tcr.setHorizontalAlignment(SwingConstants.CENTER);
table.setDefaultRenderer(Object.class, tcr);
}
}
package my12307;
import java.awt.event.MouseEvent;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JLabel;
import javax.swing.JLayeredPane;
import javax.swing.JPanel;
public class YzmUtils {
private static String signImage = "src//sign.png";
public static int yzm1 = 0;
public static int yzm2 = 0;
public static int yzm3 = 0;
public static int yzm4 = 0;
public static int yzm5 = 0;
public static int yzm6 = 0;
public static int yzm7 = 0;
public static int yzm8 = 0;
private final static int YZM_1 = 1;
private final static int YZM_2 = 2;
private final static int YZM_3 = 3;
private final static int YZM_4 = 4;
private final static int YZM_5 = 5;
private final static int YZM_6 = 6;
private final static int YZM_7 = 7;
private final static int YZM_8 = 8;
private static JPanel yzmPanel1;
private static JPanel yzmPanel2;
private static JPanel yzmPanel3;
private static JPanel yzmPanel4;
private static JPanel yzmPanel5;
private static JPanel yzmPanel6;
private static JPanel yzmPanel7;
private static JPanel yzmPanel8;
private static String yzm1Point = "35,72,";
private static String yzm2Point = "111,72,";
private static String yzm3Point = "181,72,";
private static String yzm4Point = "250,72,";
private static String yzm5Point = "35,148,";
private static String yzm6Point = "111,148,";
private static String yzm7Point = "181,148,";
private static String yzm8Point = "250,148,";
@SuppressWarnings("deprecation")
static void initYzm(JLayeredPane layeredPane){
yzmPanel1 = initSignImage(24, 55);
yzmPanel2 = initSignImage(94, 55);
yzmPanel3 = initSignImage(164, 55);
yzmPanel4 = initSignImage(240, 55);
yzmPanel5 = initSignImage(24, 130);
yzmPanel6 = initSignImage(94, 130);
yzmPanel7 = initSignImage(164, 130);
yzmPanel8 = initSignImage(240, 130);
layeredPane.add(yzmPanel1, new Integer(1));
layeredPane.add(yzmPanel2, new Integer(1));
layeredPane.add(yzmPanel3, new Integer(1));
layeredPane.add(yzmPanel4, new Integer(1));
layeredPane.add(yzmPanel5, new Integer(1));
layeredPane.add(yzmPanel6, new Integer(1));
layeredPane.add(yzmPanel7, new Integer(1));
layeredPane.add(yzmPanel8, new Integer(1));
yzmPanel1.setVisible(false);//表示驗證碼沒有選中
yzmPanel2.setVisible(false);
yzmPanel3.setVisible(false);
yzmPanel4.setVisible(false);
yzmPanel5.setVisible(false);
yzmPanel6.setVisible(false);
yzmPanel7.setVisible(false);
yzmPanel8.setVisible(false);
}
static JPanel initSignImage(int x, int y) {
JPanel panel = new JPanel();
JLabel signLabel = new JLabel();
Icon signIcon = new ImageIcon(signImage);
signLabel.setIcon(signIcon);
panel.setOpaque(false);
panel.add(signLabel);
panel.setBounds(x, y, signIcon.getIconWidth(), signIcon.getIconHeight());
return panel;
}
static void setYzmIndexVisiable(JPanel panel, int yzm) {
if(yzm%2 == 0) { //表示驗證碼沒有選中
panel.setVisible(true);
} else {
panel.setVisible(false);
}
}
static void setYzmsVisiable(int index) {
switch (index) {
case YZM_1:
setYzmIndexVisiable(yzmPanel1, yzm1);
yzm1++;
break;
case YZM_2:
setYzmIndexVisiable(yzmPanel2, yzm2);
yzm2++;
break;
case YZM_3:
setYzmIndexVisiable(yzmPanel3, yzm3);
yzm3++;
break;
case YZM_4:
setYzmIndexVisiable(yzmPanel4, yzm4);
yzm4++;
break;
case YZM_5:
setYzmIndexVisiable(yzmPanel5, yzm5);
yzm5++;
break;
case YZM_6:
setYzmIndexVisiable(yzmPanel6, yzm6);
yzm6++;
break;
case YZM_7:
setYzmIndexVisiable(yzmPanel7, yzm7);
yzm7++;
break;
case YZM_8:
setYzmIndexVisiable(yzmPanel8, yzm8);
yzm8++;
break;
default:
break;
}
}
static String getYzmAnswer() {
StringBuffer yzmAnswer = new StringBuffer();
if (yzm1%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm1Point);
}
if (yzm2%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm2Point);
}
if (yzm3%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm3Point);
}
if (yzm4%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm4Point);
}
if (yzm5%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm5Point);
}
if (yzm6%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm6Point);
}
if (yzm7%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm7Point);
}
if (yzm8%2 == 1) { //該驗證碼被選中
yzmAnswer.append(yzm8Point);
}
if (yzmAnswer.length() == 0) {
System.out.println("請選擇驗證碼");
return "";
}
return (yzmAnswer.deleteCharAt(yzmAnswer.length() - 1)).toString();
}
static void addSign2Yzm(MouseEvent e) {
//(5,41) 第一張驗證碼座標
int top = 41;
int gap = 5;
int xUnit = 67; //每一個小圖寬
int yUnit = 67; //每一個小圖寬
int xPoint = e.getX();
int yPoint = e.getY();
if(gap <= xPoint && xPoint < (gap + xUnit)) {
if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
setYzmsVisiable(YZM_1);
}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
setYzmsVisiable(YZM_5);
}
}else if((gap + xUnit) <= xPoint && xPoint < (2*(gap + xUnit))) {
if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
setYzmsVisiable(YZM_2);
}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
setYzmsVisiable(YZM_6);
}
}else if((2*(gap + xUnit)) <= xPoint && xPoint < (3*(gap + xUnit))) {
if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
setYzmsVisiable(YZM_3);
}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
setYzmsVisiable(YZM_7);
}
}else if((3*(gap + xUnit)) <= xPoint && xPoint < (4*(gap + xUnit))){
if ((gap + top) <= yPoint && yPoint < (gap + yUnit + top)) {
setYzmsVisiable(YZM_4);
}else if ((gap + yUnit + top) <= yPoint && yPoint < (2*(gap + yUnit) + top)){
setYzmsVisiable(YZM_8);
}
}
}
}