我正在使用Eclipse Kepler并且我有一个应用程序,它实例有两个JFrame
个实例,其中一个在这一点上是不可见的,因为我会在另一个执行某些检查的方法中让用户看到它。但是,当我运行它时,没有任何反应,但是当我调试它时,它在执行时会出现此错误mainWindow.setFrameListOfActivities()
:
InvocationEvent.dispatch() line: not available 'Source not Found'
这是我的代码:
在mainWindow
中,我的框架已实例化,然后我实例updateActivitiesToRun
:
package view;
import java.awt.EventQueue;
public class mainWindow extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JFormattedTextField ftfAlertTime;
private JFormattedTextField ftfScheduledTime;
private JTextArea txtGsdDescription;
private JFormattedTextField ftfGsdNumber;
private static JFrame frameListOfActivities;
public static JFrame getFrameListOfActivities() {
return frameListOfActivities;
}
public static void setFrameListOfActivities() {
frameListOfActivities.setVisible(true);
}
/**
* Launch the application.
*/
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
mainWindow frame = new mainWindow();
frame.setVisible(true);
frame.setLocationRelativeTo(null);
frame.setResizable(false);
//My Second JFrame
listActivities frameListOfActivities = new listActivities();
frameListOfActivities.setVisible(false);
//Starts the scheduler, which checks if there are any activities
ScheduledExecutorService updateActivitiesToRun = Executors.newScheduledThreadPool(1);
updateActivitiesToRun.scheduleAtFixedRate(scheduledTask.updateActivitiesToRun, 0, 2, TimeUnit.SECONDS);
//Update activities to cancel the notification after their scheduled time
//ScheduledExecutorService updatePastScheduledTimeActivities = Executors.newScheduledThreadPool(1);
//updatePastScheduledTimeActivities.scheduleAtFixedRate(scheduledTask.updatePastScheduledTimeActivities, 0, 10, TimeUnit.SECONDS);
} catch (Exception e) {
System.out.println(e.getMessage());
}
}
});
}
/**
* Create the frame.
* @throws Exception
*/
public mainWindow() throws Exception {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setLocationRelativeTo(null);
setResizable(false);
setBounds(100, 100, 450, 300);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JLabel lblGsdNumber = new JLabel("GSD Number:");
lblGsdNumber.setBounds(10, 11, 89, 14);
contentPane.add(lblGsdNumber);
JLabel lblDescription = new JLabel("Description:");
lblDescription.setBounds(10, 36, 89, 14);
contentPane.add(lblDescription);
JLabel lblAlertTime = new JLabel("Alert time:");
lblAlertTime.setBounds(10, 188, 71, 14);
contentPane.add(lblAlertTime);
JLabel lblScheduledTime = new JLabel("Scheduled Time:");
lblScheduledTime.setBounds(220, 188, 115, 14);
contentPane.add(lblScheduledTime);
JButton btnCreateActivity = new JButton("Create Activity");
btnCreateActivity.addActionListener(new ActionListener() {
//Create Activity button event
public void actionPerformed(ActionEvent e) {
if (ftfGsdNumber.getText().equals("")) {
JOptionPane.showMessageDialog(null,"Please provide the number of the activity.");
ftfGsdNumber.requestFocus();
} else {
int validation = Integer.parseInt(ftfScheduledTime.getText().replace(":", ""));
if (validation > 2359) {
JOptionPane.showMessageDialog(null,"Please provide a valid time schedule for the activity, between 00:00 and 23:59.");
ftfScheduledTime.requestFocus();
} else {
//Confirmation message
int result = JOptionPane.showConfirmDialog(null,
"Confirm details of the new activity?",null, JOptionPane.YES_NO_OPTION);
if (result == JOptionPane.YES_OPTION){
try{
DatabaseQueries.writeActivity(DatabaseQueries.databaseConnect(), ftfGsdNumber.getText(),
txtGsdDescription.getText(), ftfAlertTime.getText(), ftfScheduledTime.getText());
//Success Message
JOptionPane.showMessageDialog(null,"Activity has been saved successfully");
//Clear the txt and formated boxes
cleanTextBoxes();
}
catch(Exception ex) {
JOptionPane.showMessageDialog(null, "Unable to insert new activity in database. Error: " + ex);
}
}
}
}
}
});
btnCreateActivity.setBounds(148, 228, 133, 23);
contentPane.add(btnCreateActivity);
txtGsdDescription = new JTextArea();
txtGsdDescription.setBounds(10, 61, 414, 116);
txtGsdDescription.setLineWrap(true);
contentPane.add(txtGsdDescription);
ftfAlertTime = new JFormattedTextField();
ftfAlertTime.setColumns(5);
ftfAlertTime.setBounds(78, 185, 83, 20);
contentPane.add(ftfAlertTime);
createMask(ftfAlertTime);
ftfScheduledTime = new JFormattedTextField();
ftfScheduledTime.setColumns(5);
ftfScheduledTime.setBounds(341, 185, 83, 20);
contentPane.add(ftfScheduledTime);
createMask(ftfScheduledTime);
ftfGsdNumber = new JFormattedTextField();
ftfGsdNumber.setBounds(109, 8, 115, 20);
contentPane.add(ftfGsdNumber);
createMaskGsd(ftfGsdNumber);
}
//Creates the mask of the Scheduled Time and Alert Time
public void createMask(JFormattedTextField fieldToBeFormated) throws Exception{
MaskFormatter mask = new MaskFormatter("##:##");
mask.install(fieldToBeFormated);
}
public void createMaskGsd(JFormattedTextField fieldToBeFormated) throws Exception{
MaskFormatter mask = new MaskFormatter("IN##########");
mask.install(fieldToBeFormated);
}
public void cleanTextBoxes(){
txtGsdDescription.setText("");
ftfAlertTime.setText("");
ftfGsdNumber.setText("");
ftfScheduledTime.setText("");
}
}
以下是listActivities
JFrame
的代码:
package view;
import java.awt.event.ActionEvent;
public class listActivities extends JFrame {
/**
*
*/
private static final long serialVersionUID = 1L;
private JPanel contentPane;
private JTable table;
/**
* Launch the application.
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
listActivities frame = new listActivities();
frame.setVisible(true);
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
*/
/**
* Create the frame.
*/
public listActivities() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setBounds(100, 100, 450, 318);
contentPane = new JPanel();
contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
setContentPane(contentPane);
contentPane.setLayout(null);
JButton btnAcknowledge = new JButton("Acknowledge");
btnAcknowledge.addActionListener(new ActionListener() {
//Acknowledge button event
public void actionPerformed(ActionEvent arg0) {
}
});
btnAcknowledge.setBounds(154, 246, 131, 23);
contentPane.add(btnAcknowledge);
table = new JTable();
table.setModel(new DefaultTableModel(
new Object[][] {
},
new String[] {
"GSD Number", "Scheduled Time"
}
) {
/**
*
*/
private static final long serialVersionUID = 1L;
boolean[] columnEditables = new boolean[] {
false, true
};
public boolean isCellEditable(int row, int column) {
return columnEditables[column];
}
});
table.getColumnModel().getColumn(0).setPreferredWidth(114);
table.getColumnModel().getColumn(1).setPreferredWidth(139);
table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
table.setBounds(10, 11, 414, 96);
contentPane.add(table);
JLabel lblDescription = new JLabel("Description:");
lblDescription.setBounds(10, 118, 86, 14);
contentPane.add(lblDescription);
JTextArea textArea = new JTextArea();
textArea.setBounds(10, 143, 414, 92);
textArea.setLineWrap(true);
contentPane.add(textArea);
}
}
这是scheduledTask
类的代码,在尝试将Frame设置为可见时出错:
package rules;
import java.sql.ResultSet;
import java.sql.SQLException;
import persistence.DatabaseQueries;
import view.mainWindow;
public class scheduledTask {
private static ResultSet resultSetVar;
public static Runnable updateActivitiesToRun = new Runnable() {
public void run() {
System.out.println("first message");
mainWindow.setFrameListOfActivities();
DatabaseQueries.updateActivitiesToStartNotification(DatabaseQueries.databaseConnect());
}
};
}
答案 0 :(得分:2)
frameListOfActivities
方法中的{p> setFrameListOfActivities
为null
...
这是因为您已在main
方法中重新声明了它...
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
//...
//My Second JFrame
listActivities frameListOfActivities = new listActivities();
// ^--- Redeclared as a local variable...
frameListOfActivities.setVisible(false);
谨防过度依赖static
,这是一个非常好的指标,表明您的设计是错误的并且需要工作。 frameListOfActivities
的实例应传递给使用Runnable
安排的ScheduledExecutorService
实例。我也担心每隔2秒就可以看到这个窗口...好像你不喜欢你的用户......
事实上,我想知道SwingWorker
是否是更好的解决方案......请记住,Swing不是线程安全的,你永远不应该从事件调度线程之外创建或修改UI的状态
避免使用null
布局,像素完美布局是现代ui设计中的一种幻觉。影响组件个体大小的因素太多,您无法控制。 Swing旨在与布局管理器一起工作,放弃这些将导致问题和问题的结束,您将花费越来越多的时间来纠正。有关详细信息,请参阅Why is it frowned upon to use a null layout in SWING?
还要注意多帧的使用,这会使用户难以管理(我有足够的打开窗口),这也会使用户感到困惑。有关详细信息,请查看The Use of Multiple JFrames, Good/Bad Practice?