2015-01-28 4 views
1

Мне нужно разрешить пользователям нажимать кнопку, чтобы выбрать каталог, затем я показываю все файлы каталога в списке и позволяю им выбирать любое количество файлов. После выбора файлов я должен прочитать первую строку каждого файла и поместить это в новый список для них.Как получить список выбранных элементов JList?

Пока что я могу выбрать каталог и показать список файлов. Однако проблема заключается в том, что приложение не будет отображать список файлов, если я не изменю размер окна. Как только я изменил размер, список обновится и покажет файлы. Как я могу решить проблему и как узнать, какие элементы выбраны из списка.

private JFrame frame; 
    final JFileChooser fc = new JFileChooser(); 
    private JScrollPane scrollPane; 
    File directory; 
    JList<File> list; 


    /** 
    * Launch the application. 
    */ 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       try { 
        Main window = new Main(); 
        window.frame.setVisible(true); 
       } catch (Exception e) { 
        e.printStackTrace(); 
       } 
      } 
     }); 
    } 

    /** 
    * Create the application. 
    */ 
    public Main() { 
     initialize(); 
    } 

    /** 
    * Initialize the contents of the frame. 
    */ 
    private void initialize() { 
     frame = new JFrame(); 
     frame.setBounds(100, 100, 785, 486); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.getContentPane().setLayout(null); 

     JButton btnChooseDirectory = new JButton("Choose Directory"); 
     btnChooseDirectory.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 
       int returnVal = fc.showOpenDialog(fc); 
       if (returnVal == JFileChooser.APPROVE_OPTION) { 
        directory = fc.getSelectedFile(); 
        File[] filesInDir = directory.getAbsoluteFile().listFiles(); 
        addFilesToList(filesInDir); 
       } 
      } 
     }); 
     btnChooseDirectory.setBounds(59, 27, 161, 29); 
     frame.getContentPane().add(btnChooseDirectory); 



     JLabel lblFilesMsg = new JLabel("List of files in the directory."); 
     lblFilesMsg.setBounds(20, 59, 337, 16); 
     frame.getContentPane().add(lblFilesMsg); 

     JButton btnParseXmls = new JButton("Analyze"); 
     btnParseXmls.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent e) { 
       for (File name : list.getSelectedValuesList()) { 
        System.err.println(name.getAbsolutePath()); 
       } 
      } 
     }); 
     btnParseXmls.setBounds(333, 215, 117, 29); 
     frame.getContentPane().add(btnParseXmls); 


    } 

    private void addFilesToList(File[] filesInDir){ 

     list = new JList<File>(filesInDir); 

     list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
     list.setLayoutOrientation(JList.VERTICAL); 

     scrollPane = new JScrollPane(list); 
     scrollPane.setBounds(20, 81, 318, 360); 
     frame.getContentPane().add(scrollPane); 

    } 
} 

ответ

3

Как можно решить этот вопрос

Есть несколько возможных решений, проще в вашем случае может быть позвонить revalidate после того как вы добавили JList на панели содержимого, проблема , вы решили использовать макет null (frame.getContentPane().setLayout(null);), который делает вызов revalidate бессмысленным, поскольку он используется для указания менеджерам макетов, что им необходимо обновить их детали макета.

Избегайте использования макетов null, идеальные макеты пикселей являются иллюзией в современном дизайне ui. Слишком много факторов, которые влияют на индивидуальный размер компонентов, ни один из которых вы не можете контролировать. Swing был разработан для работы с менеджерами компоновки в ядре, отбрасывая их, что не приведет к возникновению проблем и проблем, которые вы потратите все больше времени на исправление.

Что я предлагаю сделать, это немного изменить подход.

Начните с использования одного или нескольких менеджеров компоновки, добавьте кнопку «просмотр», кнопку «Анализ» и JList к раме в начале. Когда пользователь выбирает каталог, создайте новый ListModel, а затем примените его к создаваемому для вас JList. Изменение ListModelJList приведет к автоматическому обновлению JList.

См Laying Out Components Within a Container для более подробной информации

и как я могу узнать, какие элементы выбираются из списка.

How to Use Lists Смотреть подробнее

Обновленные с примером

import java.awt.BorderLayout; 
import java.awt.Dimension; 
import java.awt.EventQueue; 
import java.awt.Graphics; 
import java.awt.Graphics2D; 
import java.awt.event.ActionEvent; 
import java.awt.event.ActionListener; 
import java.io.File; 
import javax.swing.DefaultListModel; 
import javax.swing.JButton; 
import javax.swing.JFileChooser; 
import javax.swing.JFrame; 
import javax.swing.JLabel; 
import javax.swing.JList; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.UIManager; 
import javax.swing.UnsupportedLookAndFeelException; 

public class Test { 

    public static void main(String[] args) { 
     new Test(); 
    } 

    public Test() { 
     EventQueue.invokeLater(new Runnable() { 
      @Override 
      public void run() { 
       try { 
        UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
       } catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) { 
        ex.printStackTrace(); 
       } 

       JFrame frame = new JFrame("Testing"); 
       frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
       frame.add(new TestPane()); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    public class TestPane extends JPanel { 

     private JList listOfFiles; 

     public TestPane() { 
      setLayout(new BorderLayout()); 
      listOfFiles = new JList(); 
      add(new JScrollPane(listOfFiles)); 

      JPanel top = new JPanel(); 
      top.add(new JLabel("Pick a directory")); 
      JButton pick = new JButton("Pick"); 
      pick.addActionListener(new ActionListener() { 
       @Override 
       public void actionPerformed(ActionEvent e) { 
        JFileChooser fc = new JFileChooser(); 
        fc.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 
        int returnVal = fc.showOpenDialog(fc); 
        if (returnVal == JFileChooser.APPROVE_OPTION) { 
         File directory = fc.getSelectedFile(); 
         File[] filesInDir = directory.getAbsoluteFile().listFiles(); 
         addFilesToList(filesInDir); 
        } 
       } 

       protected void addFilesToList(File[] filesInDir) { 
        DefaultListModel<File> model = new DefaultListModel<>(); 
        for (File file : filesInDir) { 
         model.addElement(file); 
        } 
        listOfFiles.setModel(model); 
       } 
      }); 
      top.add(pick); 

      add(top, BorderLayout.NORTH); 

      JPanel bottom = new JPanel(); 
      JButton analyze = new JButton("Analyze"); 
      bottom.add(analyze); 

      add(bottom, BorderLayout.SOUTH); 
     } 

    } 

} 
+0

Я вижу, что использовать, предлагаю заменить на null? – Jack

+0

«GridBagLayout» приходит на ум, но вы можете использовать комбинацию 'BorderLayout' и' FlowLayout' в зависимости от того, насколько сложным вы хотите UI – MadProgrammer

+0

Как я уже сказал, я добавил GroupLayout в фрейм и назвал метод revalidate, но все же такая же проблема – Jack

3

Не используйте пустые макеты и абсолютное позиционирование с помощью графического интерфейса Swing. Это ошибочность новичка, чтобы поверить, что это самый простой способ сделать достойный сложный графический интерфейс, и в конце концов он вас укусит, и вам будет сложно усилить GUI, которые жесткие, и посмотрите на одну платформу и разрешение экрана, но это выглядит ужасный на всех остальных. Используйте менеджеров компоновки.

Если вы добавляете новый компонент в контейнер, не забудьте вызвать revalidate() и repaint() на контейнере, чтобы позволить Swing отображать недавно добавленные компоненты.

+0

Я вижу, как ча n Я использую диспетчер макета? – Jack

+0

Как было предложено, я добавил GroupLayout в фрейм и назвал метод revalidate, но все еще имею ту же проблему – Jack

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