public class ListExample {
public static void main(String[] args) {
final List l=new List();
l.init();
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
l.list.updateUI();
System.out.println("Asim");
}
});
}
}
public class List extends JFrame{
public DefaultListModel DLM=new DefaultListModel();
public JList list=new JList(DLM);
private JPanel jp=new JPanel();
private JScrollPane sp=new JScrollPane(list);
public void init(){
jp.add(sp);
super.add(jp);
super.setVisible(true);
super.setLayout(new FlowLayout());
super.setSize(400,500);
UL p=new UL();
p.UL_1();
}
public void Update_list(String[] n){
list.setListData(n);
list.updateUI();
}
}
public class UL extends List{
public void UL_1(){
t.start();
}
Thread t=new Thread(new Runnable() {
@Override
public void run() {
//To change body of implemented methods use File | Settings | File Templates.
String[] n={"Asim", "saif","Khan"};
List l=new List();
l.list.setListData(n);
list.updateUI();
}
});
}
回答
你最好不要以糟糕的風格編寫你的java代碼。
不要讓xxxList擴展JFrame,這會引起誤解。 要使用一個線程更新的列表,可能是你可以開始一個新的線程,就像follwing:
前:不鼓勵使用其他非EDT線程,招致錯誤。
import java.awt.FlowLayout;
import javax.swing.*;
/*
* This code is bad dealing with Swing component update
*
* Update a Swing component from A Non-EDT thread is not encouraged
* may incur error like:
*
* Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
*/
public class ListExampleBad {
public static void main(String[] args) {
final ListFrame listFrame=new ListFrame();
listFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
//use a thread to update list data
new Thread(new UpdateList(listFrame)).start();
System.out.println("Asim");
}
});
}
}
//list fram with JList
class ListFrame extends JFrame{
public ListFrame(){
jp.add(sp);
super.add(jp);
super.setVisible(true);
super.setLayout(new FlowLayout());
super.setSize(400,500);
}
public synchronized void updateList(String[] n){
list.setListData(n);
list.updateUI();
}
private static final long serialVersionUID = 1L;
private DefaultListModel<String> DLM=new DefaultListModel<String>();
private JList<String> list=new JList<String>(DLM);
private JPanel jp=new JPanel();
private JScrollPane sp=new JScrollPane(list);
}
//runnable dealing with data update
class UpdateList implements Runnable {
public UpdateList(ListFrame listFrame) {
this.ListFrame = listFrame;
}
@Override
public void run() {
// TODO Auto-generated method stub
if(SwingUtilities.isEventDispatchThread()) {
System.out.println("updating list from Event Dispatch Thread");
}else {
System.out.println("updating list NOT from Event Dispatch Thread");
}
String[] n={"Asim", "saif","Khan"};
ListFrame.updateList(n);
}
private ListFrame ListFrame;
}
謝謝誰提出意見,我更新代碼:
「核心Java」引導我們拖原則:
1)不要在做一個費時的工作EDT線程,使用SwingWorker。
2)除EDT外,不要在其他線程中運行Swing組件。
此外,您可以使用SwingUtilities.isEventDispatchThread()檢查作業是否在EDT線程中執行。
一種方法:使用SwingUtilities.invokeLater
public class ListExampleBetter {
public static void main(String[] args) {
final ListFrameBad listFrame=new ListFrameBad();
listFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//use SwingUtilities.invokeLater,it's ok
SwingUtilities.invokeLater(new UpdateList(listFrame));
}
}
另一種方法:使用SwingWoker
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.List;
import javax.swing.*;
/**
* This example illustrate updating JList from thread
*/
public class ListExample {
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
@Override
public void run() {
ListFrame listFrame = new ListFrame();
listFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
listFrame.setLocationRelativeTo(null);
listFrame.setVisible(true);
}
});
}
}
//frame with JList
class ListFrame extends JFrame{
public ListFrame(){
super("Update JList Demo");
//initalize data field
dataToUpdate =new String[]{"Asim", "saif","Khan"};
DefaultListModel<String> DLM =new DefaultListModel<String>();
DLM.addElement("wait for update...");;
list =new JList<String>(DLM);
//build gui
JPanel btnPanel = new JPanel();
JButton btnUpdate = new JButton("Update");
btnPanel.add(btnUpdate);
JScrollPane sp=new JScrollPane(list);
this.add(btnPanel,BorderLayout.NORTH);
this.add(sp,BorderLayout.CENTER);
this.setSize(DEFAULT_WIDTH,DEFAULT_HEIGHT);
//deal with action
btnUpdate.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
// TODO Auto-generated method stub
ListUpdater updater = new ListUpdater();
updater.execute();
}
});
}
public synchronized void updateList(String[] n){
list.setListData(n);
list.updateUI();
}
//using Swingworker to update list
private class ListUpdater extends SwingWorker<Void,String>{
@Override
public Void doInBackground() {
for(String str :dataToUpdate) {
publish(str);
}
return null;
}
@Override
public void process (List<String> datas) {
for(String str : datas) {
model.addElement(str);
}
}
@Override
public void done() {
if(SwingUtilities.isEventDispatchThread()) {
System.out.println("updating list from Event Dispatch Thread");
}else {
System.out.println("updating list NOT from Event Dispatch Thread");
}
list.setModel(model);
}
private DefaultListModel<String> model =new DefaultListModel<String>();
}
public String[] getDataToUpdate() {
return dataToUpdate;
}
public void setDataToUpdate(String[] dataToUpdate) {
this.dataToUpdate = dataToUpdate;
}
private static final long serialVersionUID = 1L;
private final int DEFAULT_WIDTH = 300,DEFAULT_HEIGHT = 300;
private JList<String> list ;
private String[] dataToUpdate ;
}
嘿,兄弟thanx的答案 而我會按照你的意見:) – user3164210
這仍然是錯誤的。你應該從事件線程更新'JList',而不是使用事件線程產生_another_線程,然後更新'JList'。只需在'main'中對正確的線程進行更新:'SwingUtilities.invokeLater(new UpdateList(listFrame));' – DaoWen
或者使用SwingWorker – MadProgrammer
Swing是單線程架構,這意味着你的預計只修改來自事件調度線程的上下文中的UI元素。同樣,任何長期運行任務或其他阻塞流程都會阻止EDT處理新事件。
雖然有許多的方法你可能做到這一點,可能是最簡單的辦法是使用一個SwingWorker的
例如...
看看在Concurrency in Swing欲瞭解更多詳情
- 1. 更新的JLabel從另一個線程
- 2. 從另一個線程更新UI(progressDialog)
- 3. 從另一個線程javafx更新ImageView
- 4. ProgressBar從另一個線程更新
- 5. 從另一個線程更新UI
- 6. 更新從另一個線程treeview
- 7. 如何將數據從一個JList複製到另一個JList
- 8. 從另一個JFrame中刷新Jlist
- 9. 如何從另一個線程更新列表視圖
- 10. Gtkmm:如何從另一個線程更新UI?連續
- 11. 如何從另一個線程更新GUI?
- 12. 如何從另一個線程更新命令的「CanExecute」值?
- 13. 如何從另一個線程更新控件?
- 14. 從另一個線程更新GUI線程
- 15. 從另一個線程更新主線程中的ListView
- 16. 更新而QListView從另一個線程(pyqt5)更新Python列表
- 17. 從另一個JList的
- 18. 如何更新JList?
- 19. 在另一個線程中更新CollectionView
- 20. Winforms更新DataGridView在另一個線程
- 21. C# - 如何從一個線程在另一個類更新主UI
- 22. 從一個jlist添加到另一個
- 23. PySide:從另一個線程更新GUI更容易的方法
- 24. 從另一個線程刷新UITableViewController
- 25. android UI從另一個線程更改
- 26. 如何從另一個線程
- 27. 我如何從另一個線程
- 28. 如何從另一個線程
- 29. 如何從另一個線程
- 30. 如何更新從另一個TextView
請做一些解釋有關面臨的問題!單獨發佈代碼不會給任何人任何想法,至於__什麼和如何解釋問題。它告訴所提供的,至於你有多少知識,你自己掌握的問題手頭:-) –
對不起,我面臨的問題是從另一個線程更新我的Jlist 我正在製作一個程序,它將更新目前在GUI類中的JList另一個線程 堅果此代碼是一個例子是不適合我:( – user3164210