2011-11-08 3 views
1

Я пишу инструмент, который выполняет задачу в текстовом файле. Задача занимает некоторое время, поэтому я сделал панель, которая отображает имя файла и прогресс в процентах. Пользователь может запускать задачу на одном или нескольких файлах, поэтому мне нужно отобразить панель для каждого файла.
С помощью я получил здесь код, который отображает текстовую область и добавляет панели. Проблема заключается в том, что текстовые поля и список панелей растут за счет друг друга при добавлении новых элементов. Вы можете увидеть, как это происходит при добавлении строки или нажав на новую кнопку и добавление панелей: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 будет лучше. Добавьте кнопки в СЕВЕР и 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

Смежные вопросы