【JAVA学习记录】用Swing实现天气工具

【JAVA学习记录】用Swing实现天气工具,第1张

 源码已上传:基于 java swing 的高德天气工具

目录

一、简介

二、项目准备

1.数据表

2.天气API数据获取

3.添加包

4.添加数据库驱动

三、编写代码 

1.实体类Weather

2.数据库帮助类

3.DAO类

4.窗口类

5.启动类


一、简介

这个工具实现的功能:

  • 通过高德天气API查询天气数据
  • 将查询的数据存入本地数据库
  • 删除数据
二、项目准备

天气API来源:高德开放平台

数据库:Mysql(工具Navicat)

jar包:MySQL数据库JDBC驱动程序 mysql-connector-java-8.0.20.jar、fastjson-1.2.79.jar

1.数据表

1.1 新建数据库

1.2 数据表结构 

1.3 数据库脚本

CREATE TABLE `NewTable` (
`weatherid`  int NOT NULL AUTO_INCREMENT ,
`city`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`weather`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`temperature`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`winddirection`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`windpower`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`humidity`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
`reporttime`  varchar(50) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL ,
PRIMARY KEY (`weatherid`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
AUTO_INCREMENT=1
ROW_FORMAT=DYNAMIC
;
2.天气API数据获取

获取天气API:天气查询-API文档-开发指南-Web服务 API | 高德地图API

需要申请自己的key:获取key

获取的JSON格式数据:

3.添加包

新建一个工程,在src文件夹下创建如下包:

weather.dao:放置数据持久层组件中的DAO接口。

weather.dao.mysql:放置数据持久层组件中DAO接口具体实现类。还放置了访问MySQL数据库的一些辅助类和配置文件。

weather.domain:放置实体类。

weather.ui:放置表示层组件。

4.添加数据库驱动包和JSON数据处理包

将MySQL数据库JDBC驱动程序 mysql-connector-java-8.0.20.jar 和 fastjson-1.2.79.jar 放到项目根目录下,将jar包添加到项目中。

三、编写代码  1.实体类Weather
package weather.domain;

public class Weather {
    private Integer weatherid;
    private String city; //城市名
    private String weather; //天气现象(汉字描述)
    private String temperature; //实时气温,单位:摄氏度
    private String winddirection; //风向
    private String windpower; //风力级别,单位:级
    private String humidity; //空气湿度
    private String reporttime; //数据发布的时间

    public Integer getWeatherid() {
        return weatherid;
    }

    public void setWeatherid(Integer weatherid) {
        this.weatherid = weatherid;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getWeather() {
        return weather;
    }

    public void setWeather(String weather) {
        this.weather = weather;
    }

    public String getTemperature() {
        return temperature;
    }

    public void setTemperature(String temperature) {
        this.temperature = temperature;
    }

    public String getWinddirection() {
        return winddirection;
    }

    public void setWinddirection(String winddirection) {
        this.winddirection = winddirection;
    }

    public String getWindpower() {
        return windpower;
    }

    public void setWindpower(String windpower) {
        this.windpower = windpower;
    }

    public String getHumidity() {
        return humidity;
    }

    public void setHumidity(String humidity) {
        this.humidity = humidity;
    }

    public String getReporttime() {
        return reporttime;
    }

    public void setReporttime(String reporttime) {
        this.reporttime = reporttime;
    }

    @Override
    public String toString() {
        return "Weather{" +
                "weatherid=" + weatherid +
                ", city='" + city + '\'' +
                ", weather='" + weather + '\'' +
                ", temperature='" + temperature + '\'' +
                ", winddirection='" + winddirection + '\'' +
                ", windpower='" + windpower + '\'' +
                ", humidity='" + humidity + '\'' +
                ", reporttime='" + reporttime + '\'' +
                '}';
    }
}
2.数据库帮助类

2.1 配置文件config.properties

编写数据库的连接信息,url 中 weather 为数据库名;username 为数据库登录名,password 为数据库登录密码。

driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/weather
user=root
password=123456
serverTimezone=UTC

2.2 DBHelper

其中需要修改配置文件的路径。

package weather.dao.mysql;

import java.io.IOException;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Properties;

//数据库辅助类
public class DBHelper {
    // 连接数据库url
    static String url;
    // 创建Properties对象
    static Properties info = new Properties();

    // 1.驱动程序加载
    static {
        // 获得属性文件输入流
        InputStream input = DBHelper.class.getClassLoader()
                .getResourceAsStream("weather/dao/mysql/config.properties"); //配置文件存放路径

        try {
            // 加载属性文件内容到Properties对象
            info.load(input);
            // 从属性文件中取出url
            url = info.getProperty("url");
            // 从属性文件中取出driver
            String driverClassName = info.getProperty("driver");
            Class.forName(driverClassName);
            System.out.println("驱动程序加载成功...");
        } catch (ClassNotFoundException e) {
            System.out.println("驱动程序加载失败...");
        } catch (IOException e) {
            System.out.println("加载属性文件失败...");
        }
    }

    // 获得数据库连接
    public static Connection getConnection() throws SQLException {
        // 创建数据库连接
        Connection conn = DriverManager.getConnection(url, info);
        return conn;
    }
}
3.DAO类

findByCity() 方法是通过调用高德天气api实现的,里面需要修改为自己的key。

package weather.dao.mysql;

import weather.domain.Weather;
import java.util.List;

public interface WeatherDao {
    // 根据城市名查询所有
    List findAll(String city);

    // 根据城市查询一条信息(api)
    Weather findByCity(String city);

    // 创建信息
    int create(Weather weather);

    // 删除信息
    int removeByID(int id);
}

实现类 WeatherDaoImpl 

package weather.dao.mysql;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import weather.domain.Weather;
import java.io.IOException;
import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;

public class WeatherDaoImpl implements WeatherDao {
    @Override
    public List findAll(String city) {
        String sql = "";
        PreparedStatement preparedStatement = null;

        List weathers = new ArrayList<>();
        try{
            Connection con = DBHelper.getConnection();
            if (city.equals("")){
                sql = "select * from tb_weather order by weatherid desc limit 50";
                preparedStatement = con.prepareStatement(sql);
            }else{
                sql = "select * from tb_weather where city = ? order by weatherid desc limit 50";
                preparedStatement = con.prepareStatement(sql);
                preparedStatement.setString(1, city); //绑定参数
            }
            ResultSet resultSet = preparedStatement.executeQuery(); //执行查询
            while (resultSet.next()){ //遍历结果集
                Weather weather = new Weather();
                weather.setWeatherid(resultSet.getInt("weatherid"));
                weather.setCity(resultSet.getString("city"));
                weather.setWeather(resultSet.getString("weather"));
                weather.setTemperature(resultSet.getString("temperature"));
                weather.setWinddirection(resultSet.getString("winddirection"));
                weather.setWindpower(resultSet.getString("windpower"));
                weather.setHumidity(resultSet.getString("humidity"));
                weather.setReporttime(resultSet.getString("reporttime"));

                weathers.add(weather);
            }
        }catch (SQLException e){
            e.printStackTrace();
        }
        return weathers;
    }

    @Override
    public Weather findByCity(String city) {
        //city为城市代码,key为需要自己申请
        String url = "https://restapi.amap.com/v3/weather/weatherInfo?city="+city+"&key="; //这里改为自己的key
        Weather weather = new Weather();

        try{
            HttpClient client = HttpClient.newHttpClient();
            HttpRequest request = HttpRequest.newBuilder(URI.create(url)).build();
            HttpResponse response = client.send(request, HttpResponse.BodyHandlers.ofString());

            String strResult = response.body();

            JSONObject object = JSONObject.parseObject(strResult);
            if(object.getString("count").equals("1")){
                JSONArray lives = object.getJSONArray("lives");
                JSONObject object1 = JSONObject.parseObject(lives.getString(0));

                weather.setCity(object1.getString("city"));
                weather.setWeather(object1.getString("weather"));
                weather.setTemperature(object1.getString("temperature"));
                weather.setWinddirection(object1.getString("winddirection"));
                weather.setWindpower(object1.getString("windpower"));
                weather.setHumidity(object1.getString("humidity"));
                weather.setReporttime(object1.getString("reporttime"));
            }
        }
        catch (IOException | InterruptedException e) {
            e.printStackTrace();
        }
        return weather;
    }

    @Override
    public int create(Weather weather) {
        System.out.println(weather);
        String sql = "insert into tb_weather(city,weather,temperature," +
                "winddirection,windpower,humidity,reporttime) values(?,?,?,?,?,?,?)";
        try {
            Connection conn = DBHelper.getConnection();
            PreparedStatement pre = conn.prepareStatement(sql);
            pre.setString(1,weather.getCity());
            pre.setString(2,weather.getWeather());
            pre.setString(3,weather.getTemperature());
            pre.setString(4,weather.getWinddirection());
            pre.setString(5,weather.getWindpower());
            pre.setString(6,weather.getHumidity());
            pre.setString(7,weather.getReporttime());

            int affectedRows = pre.executeUpdate(); //执行修改
            System.out.println("成功插入"+affectedRows+"条数据");
        }catch (SQLException e){
            return -1;
        }
        return 0;
    }

    @Override
    public int removeByID(int id) {
        String sql = "delete from tb_weather where weatherid = ?";
        int result;
        try{
            Connection conn = DBHelper.getConnection();
            PreparedStatement pre = conn.prepareStatement(sql);
            pre.setInt(1, id); //绑定参数
            result = pre.executeUpdate(); //执行修改
        }catch (SQLException e){
            return -1;
        }
        return result;
    }
}
4.窗口类

4.1 自定义窗口类

package weather.ui;

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

//这是一个屏幕居中的自定义窗口
public class MyFrame extends JFrame {
    // 获得当前屏幕的宽
    private double screenWidth = Toolkit.getDefaultToolkit().getScreenSize().getWidth();
    // 获得当前屏幕的高
    private double screenHeight = Toolkit.getDefaultToolkit().getScreenSize().getHeight();

    public MyFrame(String title, int width, int height) {
        super(title);

        setSize(width, height); // 设置窗口大小
        // 计算窗口位于屏幕中心的坐标
        int x = (int) (screenWidth - width) / 2;
        int y = (int) (screenHeight - height) / 2;
        setLocation(x, y); // 设置窗口位于屏幕中心

        setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); //设置窗口关闭退出程序
    }
}

4.2 天气查询窗口

package weather.ui;

import weather.dao.mysql.WeatherDao;
import weather.dao.mysql.WeatherDaoImpl;
import weather.domain.Weather;

import javax.swing.*;
import java.awt.*;
import java.util.LinkedHashMap;
import java.util.Map;

public class WeatherFrame extends MyFrame {
    private WeatherDao dao = new WeatherDaoImpl(); //天气接口
    private JPanel topJPanel = new JPanel(); //头部面板
    private JPanel contentJPanel = new JPanel(); //内容面板
    private Map areaIdMap = new LinkedHashMap<>() //城市代码,LinkedHashMap可使内容按顺序输出
    {{
        put("杭州市","330100");
        put("上城区","330102");
        put("拱墅区","330105");
        put("西湖区","330106");
        put("滨江区","330108");
        put("萧山区","330109");
        put("余杭区","330110");
        put("富阳区","330111");
        put("临安区","330112");
        put("临平区","330113");
        put("钱塘区","330114");
        put("建德市","330182");
        put("桐庐县","330122");
        put("淳安县","330127");
    }};

    public WeatherFrame(){
        super("天气小工具",400,420);

        getContentPane().add(topJLabel(),BorderLayout.NORTH); //将头部面板放在窗口顶部
        getContentPane().add(contentJPanel,BorderLayout.CENTER); //将内容面板放在窗口中间

        setVisible(true); //设置窗口可见
    }

    //头部组件方法
    public JPanel topJLabel(){
        FlowLayout flowLayout = (FlowLayout) topJPanel.getLayout();
        flowLayout.setVgap(20);
        flowLayout.setHgap(20);

        JLabel label = new JLabel("请选择地区:");
        label.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topJPanel.add(label);

        String[] categorys = areaIdMap.keySet().toArray(new String[0]); //获取地区列表
        JComboBox choice = new JComboBox(categorys); //下拉菜单组件
        choice.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topJPanel.add(choice);

        contentJLable((String) choice.getSelectedItem()); //调用中间组件方法

        choice.addActionListener(e -> { //选中下拉菜单中的内容触发
            JComboBox cb = (JComboBox) e.getSource(); //获取地区
            contentJLable((String) cb.getSelectedItem()); //调用中间组件方法
        });

        JButton historyButton = new JButton("查看历史记录");
        historyButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topJPanel.add(historyButton);

        historyButton.addActionListener((e) -> {
            setVisible(false); //设置窗口不可见
            new WeatherListFrame(); //打开列表窗口
        });

        return topJPanel;
    }

    public void contentJLable(String city){ //传参为下拉菜单选中的地区
        Weather weather = dao.findByCity(areaIdMap.get(city)); //根据地区获取行政代码
        dao.create(weather); //将查询的数据存入数据库

        contentJPanel.removeAll(); //移除所有组件
        contentJPanel.repaint();
        contentJPanel.setLayout(null); //不设置布局管理器

        setJLabel(weather.getCity(),0,0,400,30,24); //地区

        setJLabel(weather.getWeather()+"   "+weather.getTemperature()+"℃", //天气和温度
                0,40,400,50,36);

        setJLabel(weather.getWinddirection()+"风   "+weather.getWindpower()+"级", //风向和风力
                0,100,400,30,18);

        setJLabel("湿度   "+weather.getHumidity(),0,140,400,30,18); //湿度

        setJLabel("更新时间   "+weather.getReporttime(),0,220,400,30,14); //更新时间

        contentJPanel.revalidate(); //重新对面板计算大小并且对面板中的组件进行布局
    }

    public void setJLabel(String label,int x,int y,int width,int height,int fontsize){ //创建组件的方法
        JLabel jLabel = new JLabel(label); //创建组件
        jLabel.setBounds(x,y,width,height); //设置组件位置和大小
        jLabel.setHorizontalAlignment(SwingConstants.CENTER); //设置组件内容居中
        jLabel.setFont(new Font("微软雅黑", Font.PLAIN, fontsize)); //设置组件文字格式
        contentJPanel.add(jLabel); //将组件添加到内容面板
    }
}

4.3 天气历史记录窗口

package weather.ui;

import jdk.swing.interop.SwingInterOpUtils;
import weather.dao.mysql.WeatherDao;
import weather.dao.mysql.WeatherDaoImpl;
import weather.domain.Weather;

import javax.swing.*;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableModel;
import java.awt.*;
import java.util.List;

public class WeatherListFrame extends MyFrame{
    private WeatherDao dao = new WeatherDaoImpl(); //天气接口
    private JPanel topJPanel = new JPanel(); //头部面板
    private JTable table = new JTable(); //表格
    private JScrollPane scrollPane = new JScrollPane();
    private JLabel message = new JLabel("啥也没有!");
    private String[] areaList = {"","杭州市","上城区","拱墅区","西湖区","滨江区","萧山区","余杭区","富阳区",
            "临安区","临平区","钱塘区","建德市","桐庐县","淳安县"};

    public WeatherListFrame() {
        super("天气查询历史记录", 700, 500);

        getContentPane().add(topJLabel(), BorderLayout.NORTH); //将头部面板放在窗口顶部
        // 把表头添加到容器顶部(使用普通的中间容器添加表格时,表头 和 内容 需要分开添加)

        scrollPane.setViewportView(table);
        getContentPane().add(scrollPane,BorderLayout.CENTER);

        setVisible(true); //设置窗口可见
    }

    public JPanel topJLabel(){
        FlowLayout flowLayout = (FlowLayout) topJPanel.getLayout();
        flowLayout.setVgap(20);
        flowLayout.setHgap(20);

        JLabel label = new JLabel("请选择地区:");
        label.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topJPanel.add(label);

        JComboBox choice = new JComboBox(areaList); //下拉菜单组件
        choice.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topJPanel.add(choice);

        contentJLable((String) choice.getSelectedItem()); //调用中间组件方法

        choice.addActionListener(e -> { //选中下拉菜单中的内容触发

            JComboBox cb = (JComboBox) e.getSource(); //获取地区
            contentJLable((String) cb.getSelectedItem()); //调用中间组件方法

        });

        JButton backButton = new JButton("返回首页");
        backButton.setFont(new Font("微软雅黑", Font.PLAIN, 14));
        topJPanel.add(backButton);

        backButton.addActionListener((e) -> {
            setVisible(false); //设置窗口不可见
            new WeatherFrame(); //打开列表窗口
        });

        return topJPanel;
    }

    public void contentJLable(String city){ //传参为下拉菜单选中的地区
        List weatherList = dao.findAll(city); //根据地区获取行政代码

        if (weatherList.size()>0){
            getContentPane().remove(message);
            String[] columnNames = {"ID","地区","天气","温度","风力和风速","湿度","发布时间"}; //列标题
            Object[][] rowData = new Object[weatherList.size()][columnNames.length];
            for(int i = 0;i < weatherList.size();i++){
                rowData[i][0] = weatherList.get(i).getWeatherid().toString();
                rowData[i][1] = weatherList.get(i).getCity();
                rowData[i][2] = weatherList.get(i).getTemperature()+"℃";
                rowData[i][3] = weatherList.get(i).getWeather();
                rowData[i][4] = weatherList.get(i).getWinddirection()+"风 "+weatherList.get(i).getWindpower()+"级";
                rowData[i][5] = weatherList.get(i).getHumidity();
                rowData[i][6] = weatherList.get(i).getReporttime();
            }

            DefaultTableModel tableModel=new DefaultTableModel(rowData,columnNames){//创建一个表格,指定所有行数据和表头
                public boolean isCellEditable(int row,int column){ //设置表格内容不可编辑
                    return false;
                }
            };
            table.setModel(tableModel);

            ListSelectionModel rowSM = table.getSelectionModel(); //返回当前行的状态模型
            rowSM.addListSelectionListener(e -> {
                ListSelectionModel lsm = (ListSelectionModel) e.getSource();
                if (lsm.isSelectionEmpty()){
                    System.out.println("没有选中行");
                }else{
                    int isremove = JOptionPane.showConfirmDialog(null, "请确认是否删除", "", JOptionPane.YES_NO_OPTION);
                    if (isremove == 0){ //确认删除
                        int selectedRow = lsm.getMinSelectionIndex();
                        dao.removeByID(Integer.parseInt(table.getValueAt(selectedRow,0).toString()));
                        tableModel.removeRow(selectedRow);
                    }
                }
            });

            scrollPane.setViewportView(table);
            getContentPane().add(scrollPane,BorderLayout.CENTER);
        }else{
            getContentPane().remove(scrollPane);
            message.setBounds(0,0,600,200); //设置组件位置和大小
            message.setHorizontalAlignment(SwingConstants.CENTER); //设置组件内容居中
            message.setFont(new Font("微软雅黑", Font.PLAIN, 36)); //设置组件文字格式
            getContentPane().add(message,BorderLayout.CENTER);
        }
        getContentPane().repaint();
        getContentPane().revalidate(); //重新对面板计算大小并且对面板中的组件进行布局
    }
}
5.启动类
package weather;

import weather.ui.WeatherFrame;

public class WeatherMain {
    public static void main(String[] args) {
        new WeatherFrame();
    }
}

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/langs/876367.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-13
下一篇2022-05-13

发表评论

登录后才能评论

评论列表(0条)

    保存