我在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种方式调用。这是ItemListener
附加到JComboBox
,ActionListener
附加到JMenu
和ComponentListener
的。{/ p>
的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();
}
}
的ItemListener
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();
}
}
}
我有很多这样的方法从数据库中获取数据并提供JTable并从GUI获取数据并保存在数据库中。
现在我的问题是,无论何时发生数据库调用,所有这些都有时会冻结。我认为它是线程问题的bcs,因此我将上述DisplayInitialRevenue_Thread
作为测试调用displayInitialRevenue_Method()
。然后我只调用了与调用此方法相关的区域,但有时它仍会冻结!我的其他数据库方法不在单独的线程中,但这是方法,所以为什么甚至调用“只”这个方法导致这个冻结?这是一个线程!
旁注,我使用的是MySQL服务器版本:5.6.16 - XAMPP附带的MySQL社区服务器(GPL)。
答案 0 :(得分:2)
致电t.start()
以开始新的Thread
,呼叫Thread#run
不再做任何事情,然后在同一线程上下文中调用run
的{{1}}方法。 ..
话虽如此,Swing不是线程安全的,Swing要求对UI的所有更新都是在Event Dispatching Thread的上下文中进行的。您应该考虑使用Thread
,而不是使用Thread
,它允许您在后台线程中执行长时间运行的任务,但它提供了易于使用SwingWorker
/ {{1}方法和调用publish
完成时,它们在EDT的上下文中为您执行。
有关详细信息,请参阅Worker Threads and SwingWorker