Java课程设计

1. 题目及要求

基于学校的搜索引擎

  • 负责部分:Java GUI设计

2.界面调查

1)调查界面:百度

2)思考:

根据我的调查,我认为我需要完成三个界面的设计:

  • 第一个是调查主界面,里面有一个集美大学的logo,一个搜索框用文本字段,因为需要在里面写入搜索内容,一个搜索按钮用button,这个按钮完成的功能就是输入搜索内容后,点击搜索按钮,可以跳转到下一个界面,并且返回结果。

  • 第二个界面是搜索结果界面:需要的是一个再次搜索框,用文本字段;一个再次搜索按钮,用button;一个面板JPanel,用来盛放我搜索到的结果;在界面的最底下还有三个按钮,一个文本框,分别是:上一页,下一页,跳转,和相应页面表示,当数据量过大需要分页时,就是用来实现页面的跳转的。

  • 第三个就是结果展示界面:一个jLabel,展示标题;一个文本区域展示内容;一个按钮,点击能够跳转到原网页浏览。

3.我的代码

1.EsGuiSearch.java

package edu.net.itsearch.gui;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.builder.SearchSourceBuilder;

import crawler.SearchResultEntry;
import edu.net.itsearch.elasticsearch.EsClient;
import io.searchbox.client.JestClient;
import io.searchbox.core.Search;
import io.searchbox.core.SearchResult;

/**
 * 
 * @author xingkyh
 */
public class EsGuiSearch {
	private JestClient jestClient;
	
	public EsGuiSearch() {
		this.jestClient=EsClient.getJestClient();
	}
	
	/**
	 * 全文检索
	 * 
	 * @param queryString 搜索字符串
	 * @return 检索结果
	 */
	public List<SearchResultEntry> fullTextSerch(String queryString) {
		// 声明一个搜索请求体
		SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();

		BoolQueryBuilder boolQueryBuilder = QueryBuilders.boolQuery();
		boolQueryBuilder.must(QueryBuilders.queryStringQuery(queryString));

		searchSourceBuilder.query(boolQueryBuilder);
		// 设置分页
		searchSourceBuilder.from(0);
		searchSourceBuilder.size(800);

		// 构建Search对象
		Search search = new Search.Builder(searchSourceBuilder.toString()).addIndex(EsClient.indexName)
				.addType(EsClient.typeName).build();
		SearchResult searchResult = null;
		try {
			searchResult = jestClient.execute(search);
		} catch (IOException e) {
			e.printStackTrace();
		}
		List<SearchResultEntry> list=new ArrayList<SearchResultEntry>();
		List<SearchResult.Hit<SearchResultEntry, Void>> hits = searchResult.getHits(SearchResultEntry.class);
		for (SearchResult.Hit<SearchResultEntry, Void> hit : hits) {
			list.add(hit.source);
		}
		return list;
	}
	
	public void close() throws IOException {
		EsClient.closeJestClient();
	}
}

2.SearchMainPage.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.net.itsearch.gui;

import java.util.List;

import javax.swing.JOptionPane;

import crawler.SearchResultEntry;

/**
 *
 * @author 格格
 */
public class SearchMainPage extends javax.swing.JFrame {

    /**
     * Creates new form searchMainPage
     */
    public SearchMainPage() {
        initComponents();
        esGuiSearch=new EsGuiSearch();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")                         
    private void initComponents() {

        searchBox = new javax.swing.JTextField();
        searchButton = new javax.swing.JButton();
        picture = new javax.swing.JLabel();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        searchButton.setText("搜索");
        searchButton.addActionListener(new java.awt.event.ActionListener() {
        	@Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                searchButtonActionPerformed(evt);
            }
        });

        picture.setIcon(new javax.swing.ImageIcon(getClass().getResource("jmu.png"))); 
        picture.setText("jLabel2");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGap(68, 68, 68)
                .addComponent(searchBox, javax.swing.GroupLayout.PREFERRED_SIZE, 516, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(searchButton, javax.swing.GroupLayout.DEFAULT_SIZE, 78, Short.MAX_VALUE)
                .addContainerGap())
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(picture, javax.swing.GroupLayout.PREFERRED_SIZE, 168, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(256, 256, 256))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addGap(46, 46, 46)
                .addComponent(picture)
                .addGap(36, 36, 36)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchBox, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(searchButton, javax.swing.GroupLayout.PREFERRED_SIZE, 54, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap(140, Short.MAX_VALUE))
        );

        pack();
    }// </editor-fold>                        

    private void searchButtonActionPerformed(java.awt.event.ActionEvent evt) {                                             
        String queryString=searchBox.getText();
        List<SearchResultEntry> list = esGuiSearch.fullTextSerch(queryString);
        if(list.isEmpty()) {
        	JOptionPane.showMessageDialog(null, "未搜索到相关内容!");
        }else {
        	 SearchResult searchResult = new SearchResult(list); 
        	 searchResult.setVisible(true);
        	 dispose();
        }
       
    }                                            

    private EsGuiSearch esGuiSearch;             
    private javax.swing.JLabel picture;
    private javax.swing.JTextField searchBox;
    private javax.swing.JButton searchButton;
    // End of variables declaration                   
}

3.SearchResult.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.net.itsearch.gui;

import java.awt.GridLayout;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JOptionPane;
import javax.swing.JPanel;

import crawler.SearchResultEntry;

/**
 *
 * @author 格格
 */
public class SearchResult extends javax.swing.JFrame {

    /**
     * Creates new form searchResult
     */
    public SearchResult() {
        initComponents();
    }
    
public SearchResult(List<SearchResultEntry> list){
     initComponents();
     esGuiSearch=new EsGuiSearch();
     resultList = getJpanelList(list);
     resultNum = list.size();
     pageNum = (resultList.size()+1)/2;
     currentPage = 1;
     displayResult();
}

   private void displayResult(){
       resultJpanel.removeAll();
       resultJpanel.setLayout(new GridLayout(2, 1));
       resultJpanel.add(resultList.get(currentPage*2-2));
       if(currentPage+currentPage <= resultNum){
           resultJpanel.add(resultList.get(currentPage*2-1));
       }
       resultJpanel.revalidate();
       resultJpanel.repaint();
       page.setText(currentPage+"/"+pageNum);
   }
    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")                         
    private void initComponents() {

        searchAgainButton = new javax.swing.JButton();
        resultJpanel = new javax.swing.JPanel();
        jumpLastPage = new javax.swing.JButton();
        jumpNextPage = new javax.swing.JButton();
        jumpChoosePage = new javax.swing.JButton();
        searchAgainBox = new javax.swing.JTextField();
        page = new javax.swing.JTextField();

        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

        searchAgainButton.setText("搜索");
        searchAgainButton.addActionListener(new java.awt.event.ActionListener() {
        	@Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
            	searchAgainButtonPerformed(evt);
            }
        });

        javax.swing.GroupLayout resultJpanelLayout = new javax.swing.GroupLayout(resultJpanel);
        resultJpanel.setLayout(resultJpanelLayout);
        resultJpanelLayout.setHorizontalGroup(
            resultJpanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 0, Short.MAX_VALUE)
        );
        resultJpanelLayout.setVerticalGroup(
            resultJpanelLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGap(0, 276, Short.MAX_VALUE)
        );

        jumpLastPage.setText("上一页");
        jumpLastPage.addActionListener(new java.awt.event.ActionListener() {
        	@Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jumpLastPageActionPerformed(evt);
            }
        });

        jumpNextPage.setText("下一页");
        jumpNextPage.addActionListener(new java.awt.event.ActionListener() {
        	@Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jumpNextPageActionPerformed(evt);
            }
        });

        jumpChoosePage.setText("页数跳转");
        jumpChoosePage.addActionListener(new java.awt.event.ActionListener() {
        	@Override
            public void actionPerformed(java.awt.event.ActionEvent evt) {
                jumpChoosePageActionPerformed(evt);
            }
        });

        searchAgainBox.setText("");

        page.setText("1");

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
        getContentPane().setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                .addContainerGap(javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                .addComponent(page, javax.swing.GroupLayout.PREFERRED_SIZE, 42, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addGap(18, 18, 18)
                .addComponent(jumpLastPage)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jumpNextPage)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jumpChoosePage)
                .addGap(12, 12, 12))
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addComponent(resultJpanel, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE)
                    .addGroup(layout.createSequentialGroup()
                        .addComponent(searchAgainBox, javax.swing.GroupLayout.PREFERRED_SIZE, 584, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(18, 18, 18)
                        .addComponent(searchAgainButton, javax.swing.GroupLayout.PREFERRED_SIZE, 72, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(0, 26, Short.MAX_VALUE)))
                .addContainerGap())
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(searchAgainBox, javax.swing.GroupLayout.PREFERRED_SIZE, 48, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(searchAgainButton, javax.swing.GroupLayout.DEFAULT_SIZE, 48, Short.MAX_VALUE))
                .addGap(27, 27, 27)
                .addComponent(resultJpanel, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE)
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED, 33, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(jumpLastPage)
                    .addComponent(jumpNextPage)
                    .addComponent(jumpChoosePage)
                    .addComponent(page, javax.swing.GroupLayout.PREFERRED_SIZE, javax.swing.GroupLayout.DEFAULT_SIZE, javax.swing.GroupLayout.PREFERRED_SIZE))
                .addContainerGap())
        );

        pack();
    }// </editor-fold>                        

    private void searchAgainButtonPerformed(java.awt.event.ActionEvent evt) {                                               
    	String queryString=searchAgainBox.getText();
    	List<SearchResultEntry> list=esGuiSearch.fullTextSerch(queryString);
    	if(list.isEmpty()) {
    		JOptionPane.showMessageDialog(null, "未搜索到相关内容!");
    	}else {
			resultList = getJpanelList(list);
			resultNum = list.size();
			pageNum = (resultList.size()+1)/2;
			currentPage = 1;
			displayResult();
		}
    	
    }                                              

    private void jumpLastPageActionPerformed(java.awt.event.ActionEvent evt) {                                             
      if(currentPage == 1){
          JOptionPane.showMessageDialog(null, "当前已为第一页,无法进入上一页!");
      }else{
          currentPage--;
          displayResult();
      }
    }                                            

    private void jumpNextPageActionPerformed(java.awt.event.ActionEvent evt) {                                             
 if(currentPage == pageNum){
          JOptionPane.showMessageDialog(null, "当前已为最后一页,无法进入下一页!");
      }else{
          currentPage++;
          displayResult();
      }
    }                                            

    private void jumpChoosePageActionPerformed(java.awt.event.ActionEvent evt) {                                               
         int jumpPage = Integer.valueOf(page.getText());
         if(jumpPage >= 1 && jumpPage <= pageNum){
             currentPage = jumpPage;
             displayResult();
         }else{
             JOptionPane.showMessageDialog(null, "输入页数不合法,请输入1-"+pageNum+"中的数字");
         }
    }                                              
    
  private List<JPanel> getJpanelList(List<SearchResultEntry> list) { 
       List<JPanel> resultList = new ArrayList<>();
       for(SearchResultEntry e:list){
           JPanel jPanel=new SearchLook(e);
           resultList.add(jPanel);
       }
       return resultList;
   }

   private List<JPanel> resultList;
   private int pageNum;
   private int currentPage;
   private int resultNum;
   private EsGuiSearch esGuiSearch;
                
    private javax.swing.JButton jumpChoosePage;
    private javax.swing.JButton jumpLastPage;
    private javax.swing.JButton jumpNextPage;
    private javax.swing.JTextField page;
    private javax.swing.JPanel resultJpanel;
    private javax.swing.JTextField searchAgainBox;
    private javax.swing.JButton searchAgainButton;
    // End of variables declaration                   
}

4.SearchLook.java

/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */
package edu.net.itsearch.gui;

import java.awt.Desktop;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.net.URI;

import crawler.SearchResultEntry;

/**
 *
 * @author 格格
 */
public class SearchLook extends javax.swing.JPanel {

    /**
     * Creates new form SearchLook
     */
    public SearchLook() {
        initComponents();
    }
    
     public SearchLook(SearchResultEntry result) {
        initComponents();
        titleJlabel.setText(result.getTitle());
        textArea.setText(result.getText());
        url = result.getUrl();
    }

    /**
     * This method is called from within the constructor to initialize the form.
     * WARNING: Do NOT modify this code. The content of this method is always
     * regenerated by the Form Editor.
     */
    @SuppressWarnings("unchecked")
    /** <editor-fold defaultstate="collapsed" desc="Generated Code"> */                         
    private void initComponents() {

        titleJlabel = new javax.swing.JLabel();
        jumpJbutton = new javax.swing.JButton();
        jScrollPane1 = new javax.swing.JScrollPane();
        textArea = new javax.swing.JTextArea();

        titleJlabel.setText("jLabel1");

        jumpJbutton.setText("跳转");
        jumpJbutton.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent e) {
				if(Desktop.isDesktopSupported()){
	                try {
	                     URI uri=URI.create(url);
	                     Desktop dp=Desktop.getDesktop();
	                    if(dp.isSupported(Desktop.Action.BROWSE)){
	                         dp.browse(uri);
	                    }
	                } catch (Exception o) {
	                    o.printStackTrace();
	                }
	        }
				
			}
		});

        textArea.setColumns(20);
        textArea.setRows(5);
        textArea.setLineWrap(true);
        textArea.setWrapStyleWord(true);
        jScrollPane1.setViewportView(textArea);

        javax.swing.GroupLayout layout = new javax.swing.GroupLayout(this);
        this.setLayout(layout);
        layout.setHorizontalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addContainerGap(36, Short.MAX_VALUE)
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(titleJlabel, javax.swing.GroupLayout.PREFERRED_SIZE, 522, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(30, 30, 30)
                        .addComponent(jumpJbutton)
                        .addContainerGap())
                    .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, layout.createSequentialGroup()
                        .addComponent(jScrollPane1, javax.swing.GroupLayout.PREFERRED_SIZE, 633, javax.swing.GroupLayout.PREFERRED_SIZE)
                        .addGap(31, 31, 31))))
        );
        layout.setVerticalGroup(
            layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
            .addGroup(layout.createSequentialGroup()
                .addGroup(layout.createParallelGroup(javax.swing.GroupLayout.Alignment.BASELINE)
                    .addComponent(titleJlabel, javax.swing.GroupLayout.PREFERRED_SIZE, 29, javax.swing.GroupLayout.PREFERRED_SIZE)
                    .addComponent(jumpJbutton))
                .addPreferredGap(javax.swing.LayoutStyle.ComponentPlacement.RELATED)
                .addComponent(jScrollPane1, javax.swing.GroupLayout.DEFAULT_SIZE, 85, Short.MAX_VALUE)
                .addContainerGap())
        );
    }// </editor-fold>                        

    private String url;
         
    private javax.swing.JScrollPane jScrollPane1;
    private javax.swing.JButton jumpJbutton;
    private javax.swing.JTextArea textArea;
    private javax.swing.JLabel titleJlabel;
    // End of variables declaration                   
}			

关键代码

4.运行结果截图

1.

2.

3.

4.

5.

5.遇到的问题

1)在SearchLook.java类中,用来放文本和标题的容器不知道用JLabel还是Jframe,最终经过百度查询资料,选择的JLabel,原因如下:JFrame是一个顶层的框架类,好比一个窗户的框子。也是一个容器类,这个框子可以嵌入几个玻璃窗,就是说Jframe可以将标签文本和按钮安放并处理,而且能实现最小化/最大化、改变大小、移动等功能特性。而JPanel是一个容器类,相当于一大玻璃窗,可以放置文本框按钮等非容器组件。在结果展示中,我只需要一个JLabel和一个文本区域和一个按钮,所以我选择JPanel。

2)第一次从net beans转到eclipse上编写时发现错误,后来经过检查发现是因为照片文件的问题,获取照片文件的相对路径为当前包,第一开始我单独放在别的包里,移到gui包后就可以正常运行了。

6.git提交记录

7.我的感想

我本身的代码基础不是很扎实,所以课设中很多部分都无法完成,只能实现Gui界面的设计与部分代码的编写。通过这次Java课设,从队友的指导,百度的搜索还有书本上的知识等等地方学到了好多关于Gui的知识,从容器插件还有监听器等等。虽然功能简单,但是我也遇到了不少的问题,比如说第一次写监听器是无法运行,原因就是我调用的类不对。还有就是跳转到网页时遇到了很多困难,研究了很久才解决。我设计的Gui界面有一些不足,但是我还是从中学到了很多,这次课设我受益匪浅。

8.团队博客链接

https://www.cnblogs.com/Rasang/p/12169899.html