我正在使用 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());
}
};
}
最佳答案
frameListOfActivities
在 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?了解更多详情
关于java - 调用方法设置 JFrame 可见时出错,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26268559/