我在 Java 的 ComponentAdapter
中实现了很多东西。由于它确实从数据库加载数据并显示在 JTable 中,因此我将其添加到另一个线程中。我将向您展示一种由此类 ComponentAdapter
private class DisplayInitialRevenue_Thread implements Runnable
{
@Override
public void run()
{
displayInitialRevenue_Method();
}
}
private void displayInitialRevenue_Method()
{
//Get the dates from the combo
String selectedCouple = revenueYearCombo.getSelectedItem().toString();
if(selectedCouple.equals("Select Year"))
{
return;
}
String[] split = selectedCouple.split("/");
//Related to DB
double totalamountInvested;
//Get data from the database
dbConnector = new DBHandler();
dbConnector.makeConnection();
DefaultTableModel model = (DefaultTableModel) initialRevenueTable.getModel();
model.setRowCount(0);
ResultSet selectAllDetails = dbConnector.selectAllDetails("SQL CODE HERE ");
try
{
if(selectAllDetails.isBeforeFirst()==false)
{
JOptionPane.showMessageDialog(null,"This table is empty");
}
else
{
while(selectAllDetails.next())
{
String clientName = selectAllDetails.getString("Client Name");
String providerName = selectAllDetails.getString("Provider Name");
Double amountInvested = selectAllDetails.getDouble("Invest_Amount");
//Get Other Data
//Update the table
Object[]row = {dateS,clientName,providerName,amountInvested};
model.addRow(row);
//Get the total
amountInvested = amountInvested+amountInvested;
}
//Add the sum
Object[]blankRow = {null,null,null,null};
model.addRow(blankRow);
Object[]row = {dateS,clientName,providerName,amountInvested};
}
}
catch(SQLException sql)
{
JOptionPane.showMessageDialog(null,sql.getLocalizedMessage());
}
}
而且,上面的线程可以通过 3 种方式调用。即通过附加到 JComboBox
的 ItemListener
、附加到 JMenu
的 ActionListener
和 ComponentListener
>.
组件监听器
private class DisplayInitialRevenue extends ComponentAdapter
{
public void componentShown(ComponentEvent e)
{
formMemorizer = FormMemorizer.Initial_Revenue;
//displayInitialRevenue_Method();
DisplayInitialRevenue_Thread t = new DisplayInitialRevenue_Thread();
t.run();
}
}
项目监听器
private class RevenueYearComboAction implements ItemListener
{
@Override
public void itemStateChanged(ItemEvent e)
{
if(e.getStateChange() == ItemEvent.SELECTED)
{
int selection = formMemorizer;
if(selection==-1)
{
return;
}
else if(selection==FormMemorizer.Initial_Revenue)
{
//displayInitialRevenue_Method();
DisplayInitialRevenue_Thread t = new DisplayInitialRevenue_Thread();
t.run();
}
}
}
我有很多这样的方法来从数据库获取数据并提供给 JTables,从 GUI 获取数据并保存在数据库中。
现在我的问题是,每当发生数据库调用时,所有这些有时都会卡住。我认为这是线程问题的原因,所以我做了上面的 DisplayInitialRevenue_Thread
来调用 displayInitialRevenue_Method()
作为测试。然后我只调用了与调用此方法相关的区域,但有时它仍然卡住!我的其他数据库方法不在单独的线程中,但这是方法,那么为什么即使“仅”调用此方法也会导致该方法卡住?它在一个线程中!
顺便说一下,我使用的是 Java 8,使用 MySQL 服务器版本:5.6.16 - XAMPP 附带的 MySQL Community Server (GPL)。
最佳答案
调用t.start()
启动一个新的Thread
,调用Thread#run
什么也不做,然后调用run同一线程上下文中
方法...Thread
的
话虽如此,Swing 不是线程安全的,Swing 要求对 UI 的所有更新都在事件调度线程的上下文中进行。您应该考虑使用 SwingWorker
,而不是使用 Thread
,它允许您在后台线程中执行长时间运行的任务,但它提供了易于使用的 publish
/process
方法并在完成时调用 done
,这些方法是在 EDT 的上下文中为您执行的。
参见Worker Threads and SwingWorker了解更多详情
关于java - 调用数据库时应用程序卡住,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27164311/