
源码已上传:基于 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文件夹下创建如下包:
4.添加数据库驱动包和JSON数据处理包weather.dao:放置数据持久层组件中的DAO接口。
weather.dao.mysql:放置数据持久层组件中DAO接口具体实现类。还放置了访问MySQL数据库的一些辅助类和配置文件。
weather.domain:放置实体类。
weather.ui:放置表示层组件。
将MySQL数据库JDBC驱动程序 mysql-connector-java-8.0.20.jar 和 fastjson-1.2.79.jar 放到项目根目录下,将jar包添加到项目中。
三、编写代码 1.实体类Weatherpackage 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();
}
}欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)