Estou montando uma aplicação java desktop onde tenho uma tabela que é alimentada hora a hora, ai possuo um Jframe que contem alguns gráficos jFreeChart estes gráficos coletam os dados da tabela e se atualizam a cada segundo para apresentação em um monitor.
PROBLEMA: Ao virar o dia, ou seja, após a meia noite o gráfico faz a consulta na tabela porém como ainda não foi alimentada (só será alimentada as 01h) o ResultSet retorna nulo e Thread responsável pela atualização trava e não reinicia mesmo após incluirmos os próximos registros da próxima hora, vou colocar abaixo partes do código passo a passo:
Classe principal:
public class formDashProducao extends javax.swing.JFrame {
public formDashProducao() throws SQLException {
initComponents();
agora(); //Aqui inicia uma Thread que seta e atualiza a data "dd/mm/aaa" em um jLabel na qual é utilizado como filtro para a consulta SQL
atualiza(); //Aqui chama uma outra Thread que possui o método que gera os Gráficos
Thead agora()
//Metodo de tempo para atualizar a data e hora dos jLabels principais da aplicação
public void agora() {
new Thread() {
@Override
@SuppressWarnings("SleepWhileInLoop")
public void run() {
while (true) {
try {
String data = dt.format(new Date());
String hora = hr.format(new Date());
txtData.setText(data);
txtHora.setText(hora);
sleep(1);
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
}
}.start();
}
Thread atualiza()
//Metodo de tempo para chamar a construção dos gráficos e atualiza-los a cada segundo
public void atualiza() {
new Thread() {
@Override
@SuppressWarnings("SleepWhileInLoop")
public void run() {
while (true) {
try {
graficos(); //Aqui chama a construção dos gráficos e atualiza-os
sleep(1000);
} catch (InterruptedException ex) {
System.out.println(ex);
}
}
}
}.start();
}
Método graficos() responsável pela chamada e construção dos gráficos no Jframe
//Metodo para recarregar os gráficos
public void graficos() {
//Recarrega os gráficos
painel1.removeAll();
painel2.removeAll();
painel3.removeAll();
painel5.removeAll();
try {
BarChartPEhh("", "PE - Peças embaladas Hora a Hora", txtData.getText(), painel1); //Primeiro gráfico
BarChartPEObRe("", "PE - Objetivo vs Realizado", txtData.getText(), painel2); //Segundo gráfico
PieChartPECompTurno("", "PE - Peças embaladas por Turno", txtData.getText(), painel3);
BarChartPEMedHh("", "PE - Media de peças embaladas Hh", txtData.getText(), painel5);
//ConclusaoDia(txtData.getText());
//PerformanceT1(txtData.getText());
//PerformanceT2(txtData.getText());
//PerformanceGeral(txtData.getText());
} catch (SQLException ex) {
Logger.getLogger(formDashProducao.class.getName()).log(Level.SEVERE, null, ex);
System.err.println(ex);
}
}
Construção do primeiro gráfico chamado ali no código acima graficos()
BarChartPEhh("", “PE - Peças embaladas Hora a Hora”, txtData.getText(), painel1); //Primeiro gráfico
/////////////////////INICIO GRÁFICO BARRA PE hora a hora////////////////////////
//Criando e personalizando o gráfico de Barra (PE hora a hora)
private JFreeChart createChartPEhh(CategoryDataset dataset, String title) {
JFreeChart chart = ChartFactory.createBarChart(
title,
"",
"",
dataset,
PlotOrientation.VERTICAL,
true, true, false);
//Personalizando o título superior principal
chart.getTitle().setHorizontalAlignment(HorizontalAlignment.CENTER);
chart.getTitle().setFont(new Font("SansSerif", Font.PLAIN, 15));
chart.getTitle().setFrame(BlockBorder.NONE);
//Personalizando a área de plotagem do gráfico
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.white);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setOutlineVisible(false);
plot.setNoDataMessage("Aguarde até a proxima hora ou verifique o servidor");
//Personalizando as barras do gráfico
BarRenderer bar = (BarRenderer) plot.getRenderer();
bar.setGradientPaintTransformer(null);
bar.setBarPainter(new StandardBarPainter());
bar.setSeriesPaint(0, new java.awt.Color(116, 124, 137));
//Colocando legenda nas barras
bar.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
bar.setBaseItemLabelsVisible(true);
bar.setBaseItemLabelFont(new Font("SansSerif", Font.PLAIN, 11));
bar.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));
// Ocultando o eixo Y lateral esquerdo que contem os valores
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setVisible(false);
// Formatando o eixo X inferior que contem as horas
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setTickLabelsVisible(true);
domainAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 10));
//Personalizando a legenda inferior
chart.getLegend().setFrame(BlockBorder.NONE);
chart.getLegend().setItemFont(new Font("SansSerif", Font.PLAIN, 11));
chart.getLegend().setVerticalAlignment(VerticalAlignment.CENTER);
chart.getLegend().setHorizontalAlignment(HorizontalAlignment.CENTER);
return chart;
}
//Criando Dataset para puxar os dados da table pe e colocar no gráfico de barra (PE hora a hora)
private CategoryDataset createDatasetPEhh(String criterio1) throws SQLException {
com.mysql.jdbc.Connection conn = ConnectionMySQL.getConnection();
// Consulta SQL para trazer os dados e alimentar o grafíco
String query = "select LEFT(peData,10) AS peData, "
+ "SUBSTRING(peData,11,3) AS peHora, "
+ "SUM(peEmbalado) AS peEmbalado "
+ "FROM pe "
+ "WHERE peData LIKE '%" + criterio1 + "%'" //Esse critério ele pega a data setada no jLabel da Thread agora()
+ "GROUP BY peHora";
// Criando java statement
Statement st = conn.createStatement();
// Executando a query, e trazendo o resultset
ResultSet rs = st.executeQuery(query);
// Setando os dados para o gráfico
DefaultCategoryDataset result = new DefaultCategoryDataset();
if (rs == null || !rs.first()) { //Tentei fazer isso caso nulo mas o problema continua
throw new NullPointerException("Destino não pode ser nulo!");
} else {
do {
result.addValue(rs.getInt("peEmbalado"), rs.getString("peData"), rs.getString("peHora"));
} while (rs.next());
}
st.close();
return result;
}
//Criando o gráfico de barra (PE hora a hora) finalizado e colocando no Jframe
public void BarChartPEhh(String applicationTitle, String chartTitle, String criterio, javax.swing.JPanel painel) throws SQLException {
// Isso irá criar o conjunto de dados
CategoryDataset dataset = createDatasetPEhh(criterio);
// com base no conjunto de dados que criamos o gráfico
JFreeChart chart = createChartPEhh(dataset, chartTitle);
// vamos colocar o gráfico em um painel
ChartPanel chartPanel = new ChartPanel(chart);
// default tamanho
chartPanel.setPreferredSize(new java.awt.Dimension(200, 200));
//Adicionando o Gráfico dentro do painel passado
painel.add(chartPanel);
painel.repaint();
painel.revalidate();
}
////////////////////////FIM GRÁFICO BARRA PE hora a hora////////////////////////
Construção do segundo gráfico chamado chamado lá no código graficos()
BarChartPEObRe("", “PE - Objetivo vs Realizado”, txtData.getText(), painel2); //Segundo gráfico
/////////////////INICIO GRÁFICO BARRA PE Objetivo vs Realizado//////////////////
//Criando e personalizando o gráfico de Barra (PE Objetivo vs Realizado)
private JFreeChart createChartPEObRe(CategoryDataset dataset, String title) {
JFreeChart chart = ChartFactory.createBarChart(
title,
"",
"",
dataset,
PlotOrientation.VERTICAL,
true, true, false);
//Personalizando o título superior principal
chart.getTitle().setHorizontalAlignment(HorizontalAlignment.CENTER);
chart.getTitle().setFont(new Font("SansSerif", Font.PLAIN, 15));
chart.getTitle().setFrame(BlockBorder.NONE);
//Personalizando a área de plotagem do gráfico
CategoryPlot plot = (CategoryPlot) chart.getPlot();
plot.setBackgroundPaint(Color.white);
plot.setDomainGridlinePaint(Color.white);
plot.setRangeGridlinePaint(Color.white);
plot.setOutlineVisible(false);
plot.setNoDataMessage("Ocorreu um erro inesperado com a conexão com o banco de dados. Favor verificar com TI");
//Personalizando as barras do gráfico
BarRenderer bar = (BarRenderer) plot.getRenderer();
bar.setItemMargin(-0.9);
bar.setGradientPaintTransformer(null);
bar.setBarPainter(new StandardBarPainter());
bar.setSeriesPaint(0, new java.awt.Color(232, 232, 232));//Objetivo
bar.setSeriesPaint(1, new java.awt.Color(74, 112, 139));//Realizado 74, 112, 139
//Colocando legenda nas barras
bar.setBaseItemLabelGenerator(new StandardCategoryItemLabelGenerator());
bar.setBaseItemLabelsVisible(true);
bar.setBaseItemLabelFont(new Font("SansSerif", Font.TRUETYPE_FONT, 16));
bar.setBasePositiveItemLabelPosition(new ItemLabelPosition(ItemLabelAnchor.OUTSIDE12, TextAnchor.BASELINE_CENTER));
// Ocultando o eixo Y lateral esquerdo que contem os valores
NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
rangeAxis.setVisible(false);
// Formatando o eixo X inferior que contem as horas
CategoryAxis domainAxis = plot.getDomainAxis();
domainAxis.setTickLabelsVisible(true);
domainAxis.setTickLabelFont(new Font("SansSerif", Font.PLAIN, 10));
//Personalizando a legenda inferior
chart.getLegend().setFrame(BlockBorder.NONE);
chart.getLegend().setItemFont(new Font("SansSerif", Font.PLAIN, 11));
chart.getLegend().setVerticalAlignment(VerticalAlignment.CENTER);
chart.getLegend().setHorizontalAlignment(HorizontalAlignment.CENTER);
return chart;
}
//Criando Dataset para puxar os dados da table pe e colocar no gráfico de barra (PE Objetivo vs Realizado)
private CategoryDataset createDatasetPEObRe(String criterio1) throws SQLException {
com.mysql.jdbc.Connection conn = ConnectionMySQL.getConnection();
// Consulta SQL para trazer os dados e alimentar o grafíco
String query = "SELECT LEFT(peData,10) AS peData, "
+ "Round(AVG(peObjetivo),0) AS peObjetivo, "
+ "SUM(peEmbalado) AS peRealizado "
+ "FROM pe "
+ "WHERE peData LIKE '%" + criterio1 + "%'"; //Esse critério ele pega a data setada no jLabel da Thread agora()
// Criando java statement
Statement st = conn.createStatement();
// Executando a query, e trazendo o resultset
ResultSet rs = st.executeQuery(query);
// Setando os dados para o gráfico
DefaultCategoryDataset result = new DefaultCategoryDataset();
if (rs == null || !rs.first()) {
result.addValue(0, "Objetivo", criterio1);
result.addValue(0, "Realizado", criterio1);
} else {
do {
result.addValue(rs.getInt("peObjetivo"), "Objetivo", rs.getString("peData"));
result.addValue(rs.getInt("peRealizado"), "Realizado", rs.getString("peData"));
} while (rs.next());
}
st.close();
return result;
}
//Criando o gráfico de barra (PE Objetivo vs Realizado) finalizado e colocando no Jframe
public void BarChartPEObRe(String applicationTitle, String chartTitle, String criterio, javax.swing.JPanel painel) throws SQLException {
// Isso irá criar o conjunto de dados
CategoryDataset dataset = createDatasetPEObRe(criterio);
// com base no conjunto de dados que criamos o gráfico
JFreeChart chart = createChartPEObRe(dataset, chartTitle);
// vamos colocar o gráfico em um painel
ChartPanel chartPanel = new ChartPanel(chart);
// default tamanho
chartPanel.setPreferredSize(new java.awt.Dimension(200, 200));
//Adicionando o Gráfico dentro do painel passado
painel.add(chartPanel);
painel.repaint();
painel.revalidate();
}
///////////////////FIM GRÁFICO BARRA PE Objetivo vs Realizado///////////////////
Enquanto possuo dados na tabela para exibir no dia, ele funciona e atualiza perfeitamente, quando vira o dia ele faz a consulta SQL na nova data porém como ainda não consta dados o ResultSet retorna nulo e para a Thread e mesmo incluindo novos dados o a Thread não retoma e sou obrigado a abrir e fechar novamente a aplicação.
Quando conseguir resolver estarei postando o código completo aqui para compartilhamento.