如何在 java 中在 JFrame 后面运行 TimerTask



我创建的应用程序(GUI JFrame 表单类)有问题,我正在尝试运行一个包含使用java.util.TimerTask执行数据扫描的命令的方法。我想运行的方法JCheckBoxMenuItem,如果我勾选checkBoxMenuItem就会运行.问题是当我选中"复选框菜单项"时,扫描方法仍在运行,但我无法再次访问 JFrame (GUI)。

import Database.KoneksiDatabase2;
import Design.ClButtonTransparan;
import Design.JPanelWithImage;
import Proses.Data.DebitDiberikan;
import Proses.Data.DebitKebutuhan;
import Proses.Data.DebitTersedia;
import Proses.Data.AutoScanNReply;
import Proses.Data.CurahHujan;
import Proses.Data.DataKirim;
import Proses.Data.DataMasuk;
import Proses.Data.Faktor_K;
import java.awt.Color;
import java.awt.Component;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.border.LineBorder;
import java.util.Timer;
public class FormPAI extends javax.swing.JFrame {
private JPanel contentPane, panel1, panelJam;
private JLabel lbtotQs, lbtotQb, lbtotQa, lbfaktorK, lbQa1, lbQa2, lbQa3;
private JLabel lbQa4, lbQa5, lbQa6, lbQa7, lbQa8, lbQa9, lbQa10, lbQa11;
private JLabel lbQa12, lbQb1, lbQb2, lbQb3, lbQb4, lbQb5, lbQb6, lbQb7;
private JLabel lbQb8, lbQb9, lbQb10, lbQb11, lbQb12, lbTotQ;
private JButton btn1, btn2, btn3, btn4, btn5, btn6;
//public Timer timer2 = null;
private JPopupMenu popUp;
private JMenuItem tulisPesan, inbox, kotakKeluar, pesanTerkirim;
ActionListener aksi, aksiTulisPesan, aksiInbox, aksikotakKeluar, aksiPesanTerkirim;
private Timer timer;
public FormPAI() throws IOException, SQLException {
initComponents();
setTitle("Pembagian Air Irigasi");
setResizable(false);
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 700, 650);
BufferedImage img = ImageIO.read(new File("C:\Users\X201\Documents\NetBeansProjects\PembagianAirIrigasi\src\img\bacground3.jpg"));
contentPane = new JPanelWithImage(img);
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
setLocationRelativeTo(null);
btnClose();
BufferedImage imgSkema = ImageIO.read(new File("C:\Users\X201\Documents\NetBeansProjects\PembagianAirIrigasi\src\img\baturiti3.png"));
panel1 = new JPanelWithImage(resize(imgSkema, 670, 420));
panel1.setBorder(new LineBorder(new Color(0, 0, 0), 1, true));
panel1.setBounds(5, 115, 680, 425);
contentPane.add(panel1);
ClockLabel dateLable = new ClockLabel("date");
ClockLabel timeLable = new ClockLabel("time");
//        ClockLabel dayLable = new ClockLabel("day");
panelJam = new JPanel();
panelJam.setBounds(545, 541, 140, 55);
panelJam.setBackground(Color.black);
panelJam.add(timeLable);
panelJam.add(dateLable);
//        panelJam.add(dayLable);
contentPane.add(panelJam);
jCheckBoxMenuItem1.setText("Run Gammu");
jCheckBoxMenuItem1.setSelected(false);
jCheckBoxMenuItem1.addItemListener(new ItemListener() {
@Override
public void itemStateChanged(ItemEvent e) {
System.out.println("Checked? " + jCheckBoxMenuItem1.isSelected());
int state = e.getStateChange();
if (state == ItemEvent.SELECTED){
try {
scan();
} catch (SQLException ex) {
Logger.getLogger(FormPAI.class.getName()).log(Level.SEVERE, null, ex);
}
}else{
timer.cancel();
}
}
});
}
public void scan() throws SQLException{
java.util.TimerTask task = new java.util.TimerTask()  {
DebitKebutuhan dk = new DebitKebutuhan();
@Override
public void run(){
System.out.println("ajik");
DataMasuk obj = new DataMasuk();
DataKirim dkrm = new DataKirim();
CurahHujan ch = new CurahHujan();
String cek = null, processed="";
try {
Connection c = KoneksiDatabase2.getKoneksiDBSMS();
ResultSet rset = c.prepareStatement("SELECT * FROM inbox WHERE Processed='false'").executeQuery();
while (rset.next()){
cek = rset.getString("ID");
processed = rset.getString("Processed");
}
if (cek != null){
obj.ambilTeksPesan();
obj.cekFormatPesan();
if (obj.formatSMS == true && processed.equals("false")){
obj.ambilDataPesan();
obj.simpanPesan_ke_DB();
obj.sendToDataMasuk();
obj.updateDataMasuk();
ch.simpanCHKeDB();
dkrm.sendToOutbox();
obj.tandaiSudahDibalas(cek);
}
}
rset.close();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
};
timer = new Timer(true);// true to run timer as daemon thread
timer.schedule(task, 0, 5000);// Run task every 5 second
try {
Thread.sleep(60000*60); // Cancel task after 1 minute.
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timer.cancel();
}
public static BufferedImage resize(BufferedImage img, int newW, int newH) { 
Image tmp = img.getScaledInstance(newW, newH, Image.SCALE_SMOOTH);
BufferedImage dimg = new BufferedImage(newW, newH, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = dimg.createGraphics();
g2d.drawImage(tmp, 0, 0, null);
g2d.dispose();
return dimg;
}

public final void btnClose(){
ImageIcon idt = new ImageIcon("C:\Users\X201\Documents\NetBeansProjects\PembagianAirIrigasi\src\img\exit.png");
Image imgRoll = idt.getImage();
Image newImgRoll = imgRoll.getScaledInstance(65, 65, 100);
ImageIcon icon = new ImageIcon("C:\Users\X201\Documents\NetBeansProjects\PembagianAirIrigasi\src\img\shutdown.png");
Image img = icon.getImage();
Image newimg = img.getScaledInstance(65, 65, 100);
btn6 = new ClButtonTransparan("<html><center>"+"KELUAR"+"</center></html>");
btn6.setFont(new Font("Berlin Sans FB Demi", Font.PLAIN,12));
btn6.setBounds(555, 5, 105, 105); // posisi jbutton (x, y) dan ukurunnnya (lebar, tinggi)
btn6.setIcon(new ImageIcon(newimg));
btn6.setRolloverIcon(new ImageIcon (newImgRoll));
btn6.setVerticalTextPosition(SwingConstants.BOTTOM); //membuat text jbutton berada dibawah
btn6.setHorizontalTextPosition(SwingConstants.CENTER); //membuat text jbutton berada ditengah
contentPane.add(btn6);
btn6.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
//JOptionPane.showConfirmDialog(rootPane, menuBar);
System.exit(0);
}
});
}


/**
* 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() {
jMenuBar1 = new javax.swing.JMenuBar();
jMenu1 = new javax.swing.JMenu();
jMenu2 = new javax.swing.JMenu();
jCheckBoxMenuItem1 = new javax.swing.JCheckBoxMenuItem();
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
jMenu1.setText("File");
jMenuBar1.add(jMenu1);
jMenu2.setText("Edit");
jCheckBoxMenuItem1.setSelected(true);
jCheckBoxMenuItem1.setText("jCheckBoxMenuItem1");
jCheckBoxMenuItem1.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
jCheckBoxMenuItem1ActionPerformed(evt);
}
});
jMenu2.add(jCheckBoxMenuItem1);
jMenuBar1.add(jMenu2);
setJMenuBar(jMenuBar1);
javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
getContentPane().setLayout(layout);
layout.setHorizontalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 400, Short.MAX_VALUE)
);
layout.setVerticalGroup(
layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
.addGap(0, 279, Short.MAX_VALUE)
);
pack();
}// </editor-fold>                        
private void jCheckBoxMenuItem1ActionPerformed(java.awt.event.ActionEvent evt) {                                                   
}                                                  
/**
* @param args the command line arguments
*/
public static void main(String args[]) {
/* Set the Nimbus look and feel */
//<editor-fold defaultstate="collapsed" desc=" Look and feel setting code (optional) ">
/* If Nimbus (introduced in Java SE 6) is not available, stay with the default look and feel.
* For details see http://download.oracle.com/javase/tutorial/uiswing/lookandfeel/plaf.html 
*/
try {
for (javax.swing.UIManager.LookAndFeelInfo info : javax.swing.UIManager.getInstalledLookAndFeels()) {
if ("Nimbus".equals(info.getName())) {
javax.swing.UIManager.setLookAndFeel(info.getClassName());
break;
}
}
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) {
java.util.logging.Logger.getLogger(FormPAI.class.getName()).log(java.util.logging.Level.SEVERE, null, ex);
}
//</editor-fold>
/* Create and display the form */
java.awt.EventQueue.invokeLater(new Runnable() {
@Override
public void run() {
try{
FormPAI frame = new FormPAI();
frame.setVisible(true);
//frame.scan();
}catch(Exception e){
}
}
});
}
// Variables declaration - do not modify                     
private javax.swing.JCheckBoxMenuItem jCheckBoxMenuItem1;
private javax.swing.JMenu jMenu1;
private javax.swing.JMenu jMenu2;
private javax.swing.JMenuBar jMenuBar1;
// End of variables declaration                   
}
class ClockLabel extends JLabel implements ActionListener {
String type;
SimpleDateFormat sdf;
public ClockLabel(String type) {
this.type = type;
setForeground(Color.green);
switch (type) {
case "day"  : sdf = new SimpleDateFormat("EEEE  ");
setFont(new Font("Digital-7", Font.PLAIN, 14));
setHorizontalAlignment(SwingConstants.RIGHT);
break;
case "time" : sdf = new SimpleDateFormat("hh:mm a");
setFont(new Font("sans-serif", Font.PLAIN, 16));
setHorizontalAlignment(SwingConstants.CENTER);
break;
case "date" : sdf = new SimpleDateFormat("dd MMMM yyyy");
setFont(new Font("sans-serif", Font.PLAIN, 20));
setHorizontalAlignment(SwingConstants.CENTER);
break;
default     : sdf = new SimpleDateFormat();
break;
}
javax.swing.Timer t = new javax.swing.Timer(1000, this);
t.start();
}
@Override
public void actionPerformed(ActionEvent ae) {
Date d = new Date();
setText(sdf.format(d));
}
}

问题是你正在让 UI 线程进入睡眠状态,看起来你的睡眠时间比你想象的要长......60000 * 60 = 一小时!

public void scan() throws SQLException{
java.util.TimerTask task = new java.util.TimerTask()  {
// ...
};
timer = new Timer(true);// true to run timer as daemon thread
timer.schedule(task, 0, 5000);// Run task every 5 second
try {
//--------------------------------------------------
//    This is putting the UI to sleep for an hour!
//--------------------------------------------------
Thread.sleep(60000*60); // Cancel task after 1 minute. <-- NOT 1 minute!
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timer.cancel();
}

您应该尝试将所有业务放在一个单独的线程上。可以这样做:

public void scan() throws SQLException{
Runnable scanRunner = new Runnable() {
public void run() {
java.util.TimerTask task = new java.util.TimerTask()  {
// ...
};
timer = new Timer(true);// true to run timer as daemon thread
timer.schedule(task, 0, 5000);// Run task every 5 second
try {
Thread.sleep(1000*60); // Cancel task after 1 minute.
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
timer.cancel();
}
};
new Thread(scanRunner).start();
}

作为旁注,这样做可能会有很多其他问题,因为您可以在闲暇时选中/取消选中 UI 中的框,并且它不会停止任何以前的扫描任务......我会让你自己处理这种情况,或者问一个不同的问题。

最新更新