📄 jsapplet.java
字号:
/*
* JSearch - turns search Engines into FIND engines - Programming in JAVA
* Copyright (C) 1999-2002 Hunt Lin
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* Also add information on how to contact you by electronic and paper mail.
*/
import java.awt.*;
import java.awt.event.*;
import java.applet.*;
import java.io.*;
import java.net.*;
import java.util.Hashtable;
import java.util.Vector;
import java.util.Enumeration;
//搜索引擎详细信息
class EnginesDetails {
String name; //搜索引擎名称
String category; //搜索引擎类别
String srchChain; //搜索串
String srchBlkB; //信息块开始
String srchBlkE; //信息块结束
}
//搜索结果详细信息
class ResultsDetails {
String title; //主题
String preview; //预览
}
public class JSApplet extends Applet {
//公共全局量定义/JSApplet对外的接口
static Hashtable resultTable = new Hashtable(); //结果集,包括网址、{主题、预览},通过网址进行定位
static Vector resultIndex = new Vector(); //结果集,仅包括网址,但可以快速使用elementAt(int)进行定位,并确定网址
static boolean _stop = false; //用标志让线程结束,而不是用stop()!
static int actualSearchAllowed = 0; //实际应打开的线程数,并用于SearchThread的计数器
//SEARCH
static TextField containingTf = new TextField("");
static Button findNowBu = new Button("");
static Button stopBu = new Button("");
static Button newSearchBu = new Button("");
//RESULTS
static List resultLi = new List();
static Label totalNumLa = new Label("0");
//PSM
static TextArea previewTe = new TextArea("",0,0,TextArea.SCROLLBARS_VERTICAL_ONLY);
static List statusLi = new List();
static TextArea messageTe = new TextArea();
//OPTIONS
static Choice smcCh = new Choice();
static Choice smlCh = new Choice();
static Choice smsCh = new Choice();
static Choice valurlCh = new Choice();
static Choice languageCh = new Choice();
static Choice webBrowCh = new Choice();
static TextField webBrowPTf = new TextField();
//定义字体
Font tabStyleFo = new Font("Tab Style Font",Font.BOLD,14);
Font littleFo = new Font("Little Font",Font.PLAIN,10);
Font commonFo = new Font("Common Font",Font.PLAIN,12);
/*****定义控件*****/
//定义SEARCH区域
Panel searchPa = new Panel();
Label searchTLa = new Label("");
Label keyLogicLa = new Label("");
Label containingLa = new Label("");
//定义RESULTS区域
Label resultTLa = new Label("");
Label titleLa = new Label("");
Label urlLa = new Label("");
Label totalLa = new Label("");
//定义PREVIEW-STATUS-MESSAGES区域
//PREVIEW
Label previewTLa = new Label("");
//STATUS
Label statusTLa = new Label("");
//MESSAGES
Label messageTLa = new Label("");
//定义ENGINES&OPTIONS&ABOUT区域
CheckboxGroup eoaCbg = new CheckboxGroup(); //ENGINES&OPTIONS&ABOUT
Panel eoaCards = new Panel();
CardLayout eoaCl = new CardLayout();
//ENGINES
Checkbox enginesCb = new Checkbox("", eoaCbg, true);
Panel enginesPa = new Panel();
Label categoryLa = new Label("");
List categoryLi = new List();
Label searchEnginesLa = new Label("");
List searchEnginesLi = new List();
//OPTIONS
Checkbox optionsCb = new Checkbox("", eoaCbg, false);
Panel optionsPa = new Panel();
Label smcLa = new Label("");
Label smlLa = new Label("");
Label smsLa = new Label("");
Label valurlLa = new Label("");
Label languageLa = new Label("");
Label webBrowLa = new Label("");
Label webBrowPLa = new Label("");
//ABOUT
Checkbox aboutCb = new Checkbox("", eoaCbg, false);
Panel aboutPa = new Panel();
Label copyingLa = new Label("");
TextArea copyingTe = new TextArea();
Label creditsLa = new Label("");
TextArea creditsTe = new TextArea();
//存放搜索引擎的信息
Hashtable engDataTable; //搜索引擎信息
Vector engDataCateg; //搜索引擎类别信息
/*****初始化*****/
//JSApplet初始化
public void init() {
//取得搜索引擎信息
engDataTable = getEngData();
engDataCateg = getEngCateg(engDataTable);
//设置控件
controlSetting();
//加入事件监听器
//SEARCH
containingTf.addKeyListener(new ContainingTfKL());
findNowBu.addActionListener(new FindNowBuAL());
stopBu.addActionListener(new StopBuAL());
newSearchBu.addActionListener(new NewSearchBuAL());
//RESULTS
resultLi.addItemListener(new ResultLiIL());
resultLi.addActionListener(new ResultLiAL());
//PREVIEW-STATUS-MESSAGES
previewTLa.addMouseListener(new PreviewTLaML());
statusTLa.addMouseListener(new StatusTLaML());
messageTLa.addMouseListener(new MessageTLaML());
//ENGINES&OPTIONS&ABOUT
enginesCb.addItemListener(new EnginesCbIL());
optionsCb.addItemListener(new OptionsCbIL());
aboutCb.addItemListener(new AboutCbIL());
//ENGINES
categoryLi.addItemListener(new CategoryLiIL());
//OPTIONS
languageCh.addItemListener(new LanguageChIL());
webBrowCh.addItemListener(new WebBrowChIL());
}
/*****事件处理*****/
/****SEARCH****/
//containing Textbox Return
class ContainingTfKL implements KeyListener {
public void keyTyped(KeyEvent e) {}
public void keyPressed(KeyEvent e) {
//按下回车键的反应
if (e.getKeyCode() == e.VK_ENTER) {
startSearch();
}
}
public void keyReleased(KeyEvent e) {}
}
//FindNow
class FindNowBuAL implements ActionListener {
public void actionPerformed(ActionEvent e) {
startSearch();
}
}
//Stop
class StopBuAL implements ActionListener {
public void actionPerformed(ActionEvent e) {
stopSearch();
}
}
//New Search
class NewSearchBuAL implements ActionListener {
public void actionPerformed(ActionEvent e) {
newSearch();
}
}
/****RESULTS****/
//选中ResultLi中的结果条目时的处理,主要是将预览在PREVIEW中显示,这是最有可能发生死锁的地方!
class ResultLiIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
switchPSM(true, false, false);
previewTe.setText(((ResultsDetails)(resultTable.get((String)(resultIndex.elementAt(resultLi.getSelectedIndex()))))).preview);
}
}
//将ResultLi中的结果条目在浏览器中显示
class ResultLiAL implements ActionListener {
public void actionPerformed(ActionEvent e) {
try {
Runtime.getRuntime().exec(webBrowPTf.getText().trim() + " " + (String)(resultIndex.elementAt(resultLi.getSelectedIndex())));
} catch(Exception ex) {
messageTe.append("Exception: '" + ex.toString() + "' in JSApplet.ResultLiAL.actionPerformed().\n");
}
}
}
/****PREVIEW-STATUS-MESSAGES****/
//当鼠标移过PREVIEW选项卡时
class PreviewTLaML implements MouseListener {
public void mouseEntered(MouseEvent e) {
switchPSM(true, false, false);
}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
//当鼠标移过STATUS选项卡时
class StatusTLaML implements MouseListener {
public void mouseEntered(MouseEvent e) {
switchPSM(false, true, false);
}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
//当鼠标移过MESSAGES选项卡时
class MessageTLaML implements MouseListener {
public void mouseEntered(MouseEvent e) {
switchPSM(false, false, true);
}
public void mouseExited(MouseEvent e) {}
public void mouseClicked(MouseEvent e) {}
public void mousePressed(MouseEvent e) {}
public void mouseReleased(MouseEvent e) {}
}
/****ENGINES&OPTIONS&ABOUT****/
//当选择ENGINES选项卡时
class EnginesCbIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
if (enginesCb.getState()) {
eoaCl.show(eoaCards,"engines");
switchEOA(true, false, false);
}
}
}
//当选择OPTIONS选项卡时
class OptionsCbIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
if (optionsCb.getState()) {
eoaCl.show(eoaCards,"options");
switchEOA(false, true, false);
}
}
}
//当选择ABOUT选项卡时
class AboutCbIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
if (aboutCb.getState()) {
eoaCl.show(eoaCards,"about");
switchEOA(false, false, true);
}
}
}
/***ENGINES***/
//选择搜索引擎类别
class CategoryLiIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
categorySelect();
}
}
/***OPTIONS***/
//改变语言
class LanguageChIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
changeLanguage(languageCh.getSelectedIndex());
}
}
//改变浏览器
class WebBrowChIL implements ItemListener {
public void itemStateChanged(ItemEvent e) {
switch(webBrowCh.getSelectedIndex()) {
case 0:
webBrowPTf.setText("c:\\progra~1\\intern~1\\iexplore.exe");
webBrowPTf.setEditable(false);
break;
case 1:
webBrowPTf.setText("c:\\progra~1\\netscape\\commun~1\\program\\netscape.exe");
webBrowPTf.setEditable(false);
break;
case 2:
webBrowPTf.setText("/usr/bin/netscape-communicator");
webBrowPTf.setEditable(false);
break;
case 3:
webBrowPTf.setText("");
webBrowPTf.setEditable(true);
break;
}
}
}
/*****公共方法*****/
//设置按钮状态,在init()中使用。
void controlSetting() {
//设置背景
setBackground(new Color(6724095));
/*****设置控件*****/
//设置SEARCH区域
searchTLa.setBounds(6,6,80,20);
searchTLa.setAlignment(Label.CENTER);
searchTLa.setFont(tabStyleFo);
searchTLa.setForeground(Color.yellow);
searchTLa.setBackground(new Color(3355647));
searchPa.setBounds(6,26,350,80);
searchPa.setBackground(Color.cyan);
containingLa.setBounds(5,6,70,20);
containingLa.setAlignment(Label.RIGHT);
containingTf.setBounds(81,6,260,20);
containingTf.setBackground(Color.white);
keyLogicLa.setBounds(5,31,335,20);
keyLogicLa.setAlignment(Label.CENTER);
keyLogicLa.setForeground(new Color(25600));
findNowBu.setBounds(6,56,105,20);
findNowBu.setBackground(new Color(6724095));
stopBu.setBounds(121,56,105,20);
stopBu.setBackground(new Color(6724095));
newSearchBu.setBounds(236,56,105,20);
newSearchBu.setBackground(new Color(6724095));
//设置RESULTS区域
resultTLa.setBounds(6,116,80,20);
resultTLa.setAlignment(Label.CENTER);
resultTLa.setFont(tabStyleFo);
resultTLa.setForeground(Color.yellow);
resultTLa.setBackground(new Color(3355647));
titleLa.setBounds(6,136,265,20);
titleLa.setBackground(Color.cyan);
urlLa.setBounds(272,136,259,20);
urlLa.setBackground(Color.cyan);
resultLi.setBounds(6,156,525,240);
resultLi.setMultipleMode(false);
totalLa.setBounds(451,116,40,20);
totalLa.setForeground(new Color(25600));
totalNumLa.setBounds(491,116,40,20);
totalNumLa.setForeground(new Color(25600));
//设置PREVIEW-STATUS-MESSAGES区域
//PREVIEW
previewTLa.setBounds(361,6,81,20);
previewTLa.setAlignment(Label.CENTER);
previewTLa.setFont(tabStyleFo);
previewTLa.setForeground(Color.yellow);
previewTLa.setBackground(new Color(25600));
previewTe.setBounds(361,26,390,80);
previewTe.setBackground(Color.white);
previewTe.setEditable(false);
//STATUS
statusTLa.setBounds(449,6,80,20);
statusTLa.setAlignment(Label.CENTER);
statusTLa.setFont(tabStyleFo);
statusTLa.setForeground(Color.yellow);
statusTLa.setBackground(new Color(25600));
statusLi.setBounds(361,26,390,80);
statusLi.setFont(littleFo);
statusLi.setMultipleMode(false);
//MESSAGES
messageTLa.setBounds(536,6,80,20);
messageTLa.setAlignment(Label.CENTER);
messageTLa.setFont(tabStyleFo);
messageTLa.setForeground(Color.yellow);
messageTLa.setBackground(new Color(3355647));
messageTe.setBounds(361,26,390,80);
messageTe.setFont(littleFo);
messageTe.setBackground(Color.white);
messageTe.setEditable(false);
//设置ENGINES&OPTIONS&ABOUT区域
eoaCards.setBounds(536,136,215,260);
eoaCards.setLayout(eoaCl);
//ENGINES
enginesCb.setBounds(536,116,74,20);
enginesCb.setFont(tabStyleFo);
enginesCb.setForeground(Color.yellow);
enginesCb.setBackground(new Color(3355647));
enginesPa.setBackground(Color.cyan);
categoryLa.setBounds(8,4,60,15);
categoryLa.setAlignment(Label.CENTER);
categoryLa.setBackground(new Color(6724095));
categoryLi.setBounds(8,19,200,85);
categoryLi.setMultipleMode(false);
searchEnginesLa.setBounds(8,108,100,15);
searchEnginesLa.setAlignment(Label.CENTER);
searchEnginesLa.setBackground(new Color(6724095));
searchEnginesLi.setBounds(8,123,200,132);
searchEnginesLi.setMultipleMode(true);
//OPTIONS
optionsCb.setBounds(611,116,74,20);
optionsCb.setFont(tabStyleFo);
optionsCb.setForeground(Color.yellow);
optionsCb.setBackground(new Color(25600));
optionsPa.setBackground(Color.cyan);
smcLa.setBounds(8,26,140,20);
smcCh.setBounds(158,26,50,20);
for (int c=1;c<=16;c++) smcCh.addItem(String.valueOf(c));
smcCh.select(getParameter("smcCh"));
smlLa.setBounds(8,46,140,20);
smlCh.setBounds(158,46,50,20);
for (int c=1;c<=10;c++) smlCh.addItem(String.valueOf(c));
smlCh.select(getParameter("smlCh"));
smsLa.setBounds(8,66,140,20);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -