2011-11-08 47 views
1

我正在編寫一個工具在文本文件上執行一項任務。該任務需要一些時間才能完成,因此我製作了一個顯示文件名和進度百分比的面板。用戶可以在一個或多個文件上運行該任務,因此我需要爲每個文件顯示一個面板。
隨着我到這裏的幫助,我有這個代碼顯示文本區域並添加面板。問題在於,添加新項目時,textarea和麪板列表的增長都是以犧牲對方爲代價的。JSplitPane不顯示項目

import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 
import java.util.logging.Logger; 

public class FProgressDisplay extends JFrame { 
    private final static Logger LOGGER = Logger.getLogger(FProgressDisplay.class.getName()); 
    private List<PanelTaskProgress> tasks; 
    JTextArea txtLog; 
    JButton btnNew; 
    JButton btnAbort; 
    JButton btnClose; 
    static int i; 
    JPanel taskPanel; 

    public static void main(String[] args) { 
     try { 
      FProgressDisplay frame = new FProgressDisplay(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setVisible(true); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new RuntimeException("Failed to initialize application."); 
     } 
    } 
    /** 
    * Create the frame. 
    */ 
    public FProgressDisplay() { 
     setTitle("Mask tool - Progress"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     // should be done AFTER components are added 
     //pack(); 
     getContentPane().setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 
     taskPanel = new JPanel(); 
     taskPanel.setLayout(new BoxLayout(taskPanel, BoxLayout.Y_AXIS)); 

     JPanel panel = new JPanel(); 
     getContentPane().add(panel); 

     btnNew = new JButton("New"); 
     panel.add(btnNew); 
     btnNew.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent ae) { 
       addTask(++i, "Task " + i); 
      } 
     }); 

     btnAbort = new JButton("Abort"); 
     panel.add(btnAbort); 

     btnClose = new JButton("Close"); 
     panel.add(btnClose); 

     txtLog = new JTextArea(10,0); 
     txtLog.setLineWrap(true); 
     getContentPane().add(txtLog); 

     tasks = new ArrayList<PanelTaskProgress>(); 

     JScrollPane scrollPane = new JScrollPane(taskPanel); 
     getContentPane().add(scrollPane); 

     for(i = 0; i < 10; i++) { 
      addTask(i, "Task"+i); 
     } 
     pack(); 
    } 

    public void addTask(long id, String fileName) { 
     PanelTaskProgress newTaskPanel = new PanelTaskProgress(id, fileName); 
     tasks.add(newTaskPanel); 
     taskPanel.add(newTaskPanel); 
     validate(); 
     //repaint(); 
     LOGGER.info("Added new panel"); 
    } 

    public class PanelTaskProgress extends JPanel { 
     private static final long serialVersionUID = 1L; 
     JLabel lblTaskDescription; 
     JLabel lblProgress; 
     private long id; 
     /** 
     * Create the panel. 
     */ 
     public PanelTaskProgress(long id, String fileName) { 
      try { 
       //setLayout(null); 

       lblTaskDescription = new JLabel(id + " " + fileName); 
       //lblTaskDescription.setPreferredSize(new Dimension(632, 14)); 
       add(lblTaskDescription); 

       lblProgress = new JLabel("0%"); 
       lblProgress.setHorizontalAlignment(SwingConstants.CENTER); 
       //lblProgress.setBounds(664, 11, 51, 14); 
       add(lblProgress); 

       LOGGER.info("Created new panel; Id: " + id + "; File: " + fileName); 
      } catch (Exception e) { 
       LOGGER.severe("Error creating new panel; " + e.getMessage()); 
      } 
     } 
    } 
} 

我想每個留在自己的領域,如果需要添加滾動:當添加行或點擊新建按鈕,添加面板您可以看到這種情況出現。我試圖在上面的例子中添加一個JSplitPane,但是這兩個窗格都是空的。

import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.plaf.SplitPaneUI; 

import java.util.*; 
import java.util.logging.Logger; 

public class FProgressDisplay extends JFrame { 
    private final static Logger LOGGER = Logger 
      .getLogger(FProgressDisplay.class.getName()); 
    private List<PanelTaskProgress> tasks; 
    JTextArea txtLog; 
    JButton btnNew; 
    JButton btnAbort; 
    JButton btnClose; 
    static int i; 
    JPanel taskPanel; 

    private JSplitPane splitPane; 

    public static void main(String[] args) { 
     try { 
      FProgressDisplay frame = new FProgressDisplay(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setVisible(true); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new RuntimeException("Failed to initialize application."); 
     } 
    } 

    /** 
    * Create the frame. 
    */ 
    public FProgressDisplay() { 
     setTitle("Mask tool - Progress"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     // should be done AFTER components are added 
     // pack(); 
     getContentPane().setLayout(
       new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 
     taskPanel = new JPanel(); 
     taskPanel.setLayout(new BoxLayout(taskPanel, BoxLayout.Y_AXIS)); 

     JPanel panel = new JPanel(); 
     getContentPane().add(panel); 

     btnNew = new JButton("New"); 
     panel.add(btnNew); 
     btnNew.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent ae) { 
       addTask(++i, "Task " + i); 
      } 
     }); 

     btnAbort = new JButton("Abort"); 
     panel.add(btnAbort); 

     btnClose = new JButton("Close"); 
     panel.add(btnClose); 

     txtLog = new JTextArea(10, 0); 
     txtLog.setLineWrap(true); 
     //getContentPane().add(txtLog); 

     tasks = new ArrayList<PanelTaskProgress>(); 

     JScrollPane scrollPane = new JScrollPane(taskPanel); 
     //getContentPane().add(scrollPane); 
     splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, txtLog, scrollPane); 
     splitPane.setDividerLocation(150); 

     for (i = 0; i < 10; i++) { 
      addTask(i, "Task" + i); 
     } 
     pack(); 
    } 

    public void addTask(long id, String fileName) { 
     PanelTaskProgress newTaskPanel = new PanelTaskProgress(id, fileName); 
     tasks.add(newTaskPanel); 
     taskPanel.add(newTaskPanel); 
     validate(); 
     // repaint(); 
     LOGGER.info("Added new panel"); 
    } 

    public class PanelTaskProgress extends JPanel { 
     private static final long serialVersionUID = 1L; 
     JLabel lblTaskDescription; 
     JLabel lblProgress; 
     private long id; 

     /** 
     * Create the panel. 
     */ 
     public PanelTaskProgress(long id, String fileName) { 
      try { 
       // setLayout(null); 

       lblTaskDescription = new JLabel(id + " " + fileName); 
       // lblTaskDescription.setPreferredSize(new Dimension(632, 14)); 
       add(lblTaskDescription); 

       lblProgress = new JLabel("0%"); 
       lblProgress.setHorizontalAlignment(SwingConstants.CENTER); 
       // lblProgress.setBounds(664, 11, 51, 14); 
       add(lblProgress); 

       LOGGER.info("Created new panel; Id: " + id + "; File: " 
         + fileName); 
      } catch (Exception e) { 
       LOGGER.severe("Error creating new panel; " + e.getMessage()); 
      } 
     } 
    } 
} 

這裏是解決方案:

package layout.sscce; 

import java.awt.BorderLayout; 
import java.awt.event.*; 
import javax.swing.*; 
import java.util.*; 
import java.util.logging.Logger; 

public class FProgressDisplay extends JFrame { 
    private final static Logger LOGGER = Logger 
      .getLogger(FProgressDisplay.class.getName()); 
    private List<PanelTaskProgress> tasks; 
    JTextArea txtLog; 
    JButton btnNew; 
    JButton btnAbort; 
    JButton btnClose; 
    static int i; 
    JPanel taskPanel; 

    private JSplitPane splitPane; 

    public static void main(String[] args) { 
     try { 
      FProgressDisplay frame = new FProgressDisplay(); 
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
      frame.setVisible(true); 

     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new RuntimeException("Failed to initialize application."); 
     } 
    } 

    /** 
    * Create the frame. 
    */ 
    public FProgressDisplay() { 
     setTitle("Mask tool - Progress"); 
     setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     // should be done AFTER components are added 
     // pack(); 
//  getContentPane().setLayout(
//    new BoxLayout(getContentPane(), BoxLayout.Y_AXIS)); 
     getContentPane().setLayout(
       new BorderLayout()); 

     taskPanel = new JPanel(); 
     taskPanel.setLayout(new BoxLayout(taskPanel, BoxLayout.Y_AXIS)); 

     JPanel buttonPanel = new JPanel(); 
     getContentPane().add(buttonPanel); 

     btnNew = new JButton("New"); 
     buttonPanel.add(btnNew); 
     btnNew.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent ae) { 
       addTask(++i, "Task " + i); 
      } 
     }); 

     btnAbort = new JButton("Abort"); 
     buttonPanel.add(btnAbort); 

     btnClose = new JButton("Close"); 
     buttonPanel.add(btnClose); 

     txtLog = new JTextArea(10, 30); 
     txtLog.setLineWrap(true); 
     //getContentPane().add(txtLog); 

     tasks = new ArrayList<PanelTaskProgress>(); 

     JScrollPane taskScrollPane = new JScrollPane(taskPanel); 
     JScrollPane textScrollPane = new JScrollPane(txtLog); 

     splitPane = new JSplitPane(JSplitPane.VERTICAL_SPLIT, textScrollPane, taskScrollPane); 
     splitPane.setDividerLocation(150); 

     for (i = 0; i < 10; i++) { 
      addTask(i, "Task" + i); 
     } 



     getContentPane().add(buttonPanel, BorderLayout.NORTH); 
     getContentPane().add(splitPane, BorderLayout.CENTER); 

     pack(); 
    } 

    public void addTask(long id, String fileName) { 
     PanelTaskProgress newTaskPanel = new PanelTaskProgress(id, fileName); 
     tasks.add(newTaskPanel); 
     taskPanel.add(newTaskPanel); 
     validate(); 
     // repaint(); 
     LOGGER.info("Added new panel"); 
    } 

    public class PanelTaskProgress extends JPanel { 
     private static final long serialVersionUID = 1L; 
     JLabel lblTaskDescription; 
     JLabel lblProgress; 
     private long id; 

     /** 
     * Create the panel. 
     */ 
     public PanelTaskProgress(long id, String fileName) { 
      try { 
       // setLayout(null); 

       lblTaskDescription = new JLabel(id + " " + fileName); 
       // lblTaskDescription.setPreferredSize(new Dimension(632, 14)); 
       add(lblTaskDescription); 

       lblProgress = new JLabel("0%"); 
       lblProgress.setHorizontalAlignment(SwingConstants.CENTER); 
       // lblProgress.setBounds(664, 11, 51, 14); 
       add(lblProgress); 

       LOGGER.info("Created new panel; Id: " + id + "; File: " 
         + fileName); 
      } catch (Exception e) { 
       LOGGER.severe("Error creating new panel; " + e.getMessage()); 
      } 
     } 
    } 
} 

回答

2

的問題是BoxLayout的。它試圖分配組件之間的空間時會遇到一些奇怪的事情。也許BorderLayout會更好。將按鈕添加到NORTH,將scrollPane添加到CENTER。

或使用代碼,你可以做到以下幾點:

 txtLog = new JTextArea(10, 30); // changed 
     txtLog.setLineWrap(true); 
     getContentPane().add(txtLog); 

     tasks = new ArrayList<PanelTaskProgress>(); 

     JScrollPane scrollPane = new JScrollPane(taskPanel); 
     scrollPane.setPreferredSize(txtLog.getPreferredSize()); // added 
+0

感謝。我做了一個小的補充。 textArea也放置在scrollPane中。 – Yoav