我是這個社區的新人!Swing Worker和GUI更新
我想問你一些關於SwingWorker及其與GUI的關係。
我知道有關於SwingWorker的一些回答問題,並且我已經閱讀了很多這些問題,並提供了一些有用的建議。
現在我想發佈一些代碼,我寫了一個基本的應用程序,它從指定的目錄中統計文件和文件夾的數量。
由於搜索可能需要很長時間,我希望在此過程中顯示進度條。 此外,我希望用戶有可能通過單擊按鈕或簡單地關閉包含進度欄的框架來停止計數過程。
這裏有在代碼中的一些問題,下面貼出:
- 調用執行()進行的SwingWorker方法是WaitingFrame構造函數的最後一個指令:有沒有一個更好的地方嗎?
- WaitingFrame的dispose()方法是從SwingWorker的done()方法調用的,它是正確的嗎? 如果計數過程非常快,可以在等待幀實際可見之前調用dispose方法嗎? 因此,我會有兩個開放的框架...
- 是否有更好的方法來中斷過程並管理向用戶顯示的消息對話框? 我用了兩個布爾變量,有效和中斷,達到我的目的...
而這裏的代碼:
import java.awt.*;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;
import javax.swing.*;
import javax.swing.border.*;
public class CountFiles
{
public static void main(String[] args)throws Exception
{
SwingUtilities.invokeLater(new Runnable(){
public void run(){
try
{
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
new CountFilesFrame().setVisible(true);
}
catch(Exception ex){
ex.printStackTrace();
}
}
});
}
}
class CountFilesFrame extends JFrame
{
private JTextField field;
public CountFilesFrame()
{
super("Conta File e Cartelle");
setDefaultCloseOperation(EXIT_ON_CLOSE);
setResizable(false);
JPanel pane=(JPanel)getContentPane();
pane.setBackground(Color.WHITE);
pane.setBorder(new EmptyBorder(5,20,5,20));
JPanel center=new StyledPanel(pane,BorderLayout.CENTER,new FlowLayout(FlowLayout.LEFT,5,10)),bottom=new StyledPanel(pane,BorderLayout.SOUTH,new FlowLayout(FlowLayout.LEFT,20,0));
// Center panel
center.add(new JLabel("Cartella :"));
String text="";
try{
File folder=new File("../");
text=folder.exists()?folder.getCanonicalPath():"";
}
catch(Exception ex){}
field=new JTextField(text,25);
center.add(field);
// JTextArea
String newLine=System.getProperty("line.separator"),message="Scegliere la cartella da cui far partire la ricerca."+newLine+
"Sara' contato il numero di file e di cartelle presenti "+newLine+"nella directory inserita e in tutte le sottocartelle";
JTextArea area=new JTextArea(message);
area.setEditable(false);
area.setFont(field.getFont());
pane.add(area,BorderLayout.NORTH);
// Bottom panel
bottom.add(new JButton(new AbstractAction("Cambia Cartella"){
public void actionPerformed(ActionEvent e){
changeDirectory();
}
}));
bottom.add(new JButton(new AbstractAction("Inizia ricerca"){
public void actionPerformed(ActionEvent e){
new WaitingFrame(CountFilesFrame.this);
}
}));
pack();
setLocationRelativeTo(null);
}
public void changeDirectory()
{
JFileChooser chooser=new JFileChooser(field.getText());
chooser.setDialogTitle("Cambia Cartella");
chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY);
if(chooser.showDialog(this,"Scegli")==JFileChooser.APPROVE_OPTION)
{
try
{
File selected=chooser.getSelectedFile();
if(selected.exists())field.setText(selected.getCanonicalPath());
}
catch(Exception ex){}
}
}
private class WaitingFrame extends JFrame
{
private Counter counter;
public WaitingFrame(CountFilesFrame f)
{
super("Ricerca File");
setDefaultCloseOperation(DISPOSE_ON_CLOSE);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
stopCounter();
}
});
setResizable(false);
JPanel pane=(JPanel)getContentPane(),buttonPanel=new StyledPanel(pane,BorderLayout.SOUTH,new FlowLayout(FlowLayout.CENTER,0,10));
JLabel label=new JLabel("Conteggio in corso...",JLabel.CENTER);
label.setBorder(new EmptyBorder(0,0,10,0));
pane.add(label,BorderLayout.NORTH);
pane.setBackground(Color.WHITE);
pane.setBorder(new EmptyBorder(10,40,0,40));
JProgressBar progressBar=new JProgressBar(0,100);
progressBar.setBorderPainted(false);
progressBar.setIndeterminate(true);
pane.add(progressBar,BorderLayout.CENTER);
buttonPanel.add(new JButton(new AbstractAction("Annulla"){
public void actionPerformed(ActionEvent e){
stopCounter();
}
}));
while(pane.getSize().width!=pane.getPreferredSize().width)pack();
setLocationRelativeTo(null);
setVisible(true);
(counter=new Counter()).execute();
}
public void stopCounter()
{
counter.interrupt();
counter.cancel(true);
}
private class Counter extends SwingWorker<Void,Void>
{
private boolean valid=true,interrupted=false;
private int filesNumber=0,foldersNumber=0;
protected Void doInBackground()
{
File folder=new File(field.getText());
if(!folder.exists()||!folder.isDirectory())valid=false;
else countFiles(folder);
return null;
}
protected void done()
{
dispose();
if(interrupted)return;
else if(!valid)JOptionPane.showMessageDialog(CountFilesFrame.this,"Inserire una cartella valida","Percorso specificato errato",JOptionPane.ERROR_MESSAGE);
else JOptionPane.showMessageDialog(CountFilesFrame.this,"Sono stati trovati "+(foldersNumber-1)+" cartelle e "+filesNumber+" file","Ricerca completata",JOptionPane.INFORMATION_MESSAGE);
}
private void countFiles(File file)
{
if(file.isDirectory())
{
foldersNumber++;
for(File nested:file.listFiles())countFiles(nested);
}
else filesNumber++;
}
public void interrupt()
{
interrupted=true;
}
}
}
}
class StyledPanel extends JPanel
{
public StyledPanel(JPanel parent,String position,LayoutManager layout)
{
super(layout);
setBackground(Color.WHITE);
parent.add(this,position);
}
}
我發佈的所有應用程序代碼,所以你可以嘗試編譯運行。
在此先感謝您的幫助! PS:我沒有改變界面語言,我很抱歉。此外,我很抱歉我的英語不好......
*「沒有更改界面語言」*它似乎與問題沒有關係,所以爲什麼你會打擾?我注意到所有的類名和屬性都是英文的。這很方便。 :) –