JList:按顶部/底部按钮排序

时间:2012-05-26 11:40:33

标签: java swing sorting netbeans jlist

我遇到与上一个问题相关的问题:JList: sorting by Up/down buttons 我的向上/向下按钮现在正常工作,但这是另一回事: 我还需要制作顶部/底部按钮。他们似乎更难。我使用actionPerformed按钮“Top”:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
 int indexOfSelected = jList1.getSelectedIndex();
 swapElements2(indexOfSelected, 0);
 indexOfSelected = 0;
 jList1.setSelectedIndex(indexOfSelected );
 jList1.updateUI();
}

swapElements2方法看起来像这样:

private void swapElements2(int pos1, int pos2) {
  String tmp1 =  (String) listModel.get(pos1);
  String tmp2 =  (String) listModel.get(pos2);
  listModel = (DefaultListModel) jList1.getModel();
  int sizeOfList = listModel.getSize();

  listModel.set(pos2, listModel.get(sizeOfList-1));
  for (int i=sizeOfList-2;i>0;i--){
    listModel.set(i+1, listModel.get(i));
  }

  listModel.set(pos2, tmp1);
  listModel.set(pos2+1, tmp2);
}

当然,只有在选择了jList的最后一个元素时才有效。有谁知道如何制作一个将元素从选定位置移动到0位置的通用方法?方法还应该向前移动所有其他元素,如果没有选择,则最后一个元素应该保留在它的位置。

我会感激任何帮助。

从评论中编辑,这也不起作用:

private void jButton1ActionPerformed(java.awt.event.ActionEvent evt) {
 String temp = (String) listModel.remove(jList1.getSelectedIndex());
 listModel.add(0, temp);
}

错误:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
name podziwiaj.jpg
at java.io.File.<init>(File.java:222)

这是:

public File(String pathname) {
if (pathname == null) {
    throw new NullPointerException();
}
this.path = fs.normalize(pathname);
this.prefixLength = fs.prefixLength(this.path);
}

列表存储文件(图像)的路径名称,并且在选择项目时显示。

1 个答案:

答案 0 :(得分:3)

我自己的偏好是使用列表的模型来执行此操作。类似的东西:

DefaultListModel model = (DefaultListModel)jList1.getModel();
File temp = model.remove(jList1.getSelectedIndex());
model.add(0, temp);

要查看列表模型可用的方法,请查看DefaultListModel API

编辑:代码工作正常。

修改2 :我的sscce

import java.awt.event.ActionEvent;
import javax.swing.*;

public class TestList {

   private static void createAndShowGui() {
      String[] data = {"Mon", "Tues", "Wed", "Thurs", "Fri", "Sat", "Sun"};
      final DefaultListModel<String> model = new DefaultListModel<String>();
      for (String datum : data) {
         model.addElement(datum);
      }
      final JList<String> myList = new JList<String>(model);      
      JButton toTop = new JButton(new AbstractAction("To Top") {

         @Override
         public void actionPerformed(ActionEvent arg0) {
            int selectedIndex = myList.getSelectedIndex();
            if (selectedIndex < 0) {
               return;
            }
            String temp = model.remove(selectedIndex);
            model.add(0, temp);
         }
      });



      JPanel mainPanel = new JPanel();
      mainPanel.add(new JScrollPane(myList));
      mainPanel.add(toTop);


      JFrame frame = new JFrame("TestList");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

如果您在审核后仍然感到困惑,请考虑阅读SSCCE,并在此处发布我们可以修改和更正的内容。

编辑3
根据我们在聊天中的讨论,
您的问题是当您调用To Top JButton时,您正在从列表中删除所选项目,而ListSelectionListener仍在侦听,这将导致抛出NPE。一种可能的解决方案是在删除或添加任何项之前删除ListSelectionListener,然后在执行这些操作后重新添加侦听器。当您更新列表模型时,这可能是必要的。请参阅下面的SSCCE。另请参阅阅读和理解SSCCE代码比使用大代码更容易。

import java.awt.BorderLayout;
import java.awt.Component;
import java.awt.Dimension;
import java.awt.Image;
import java.awt.event.*;
import java.io.File;
import java.io.IOException;

import javax.imageio.ImageIO;
import javax.swing.*;
import javax.swing.event.*;

@SuppressWarnings("serial")
public class MyToolView extends JPanel {

   public File[] file;
   public static int i = 0;

   final static JFileChooser fc = new JFileChooser();
   private static final int PREF_W = 900;
   private static final int PREF_H = 750;
   final DefaultListModel listModel = new DefaultListModel();
   final JList myList = new JList(listModel);
   private JLabel imageLabel = new JLabel();
   private javax.swing.JButton openButton;
   private JButton toTopBtn;
   private javax.swing.JList imageJList;
   private javax.swing.JScrollPane jScrollPane1;
   private javax.swing.JPanel mainPanel;

   public MyToolView() {
      initComponents();
   }

   private void initComponents() {
      jScrollPane1 = new javax.swing.JScrollPane();
      imageJList = new javax.swing.JList(listModel);
      openButton = new javax.swing.JButton();
      toTopBtn = new JButton("To Top");

      JPanel topPanel = new JPanel();
      topPanel.add(jScrollPane1);
      topPanel.add(openButton);
      topPanel.add(toTopBtn);

      setLayout(new BorderLayout());
      add(topPanel, BorderLayout.PAGE_START);
      add(new JScrollPane(imageLabel), BorderLayout.CENTER);

      toTopBtn.addActionListener(new ActionListener() {

         @Override
         public void actionPerformed(ActionEvent e) {
            toTopBtnActionPerformed(e);
         }
      });

      jScrollPane1.setFocusable(false);
      jScrollPane1.setName("jScrollPane1"); // NOI18N

      imageJList.setModel(new javax.swing.AbstractListModel() {
         String[] strings = { "AAAA.JPG", "BBBB.JPG" };

         public int getSize() {
            return strings.length;
         }

         public Object getElementAt(int i) {
            return strings[i];
         }
      });
      imageJList.setName("jList1"); // NOI18N
      imageJList.setCellRenderer(new JavaRenderer());
      jScrollPane1.setViewportView(imageJList);
      imageJList.addListSelectionListener(listSelectionListener);

      openButton.setFocusable(false);
      openButton.setName("openButton"); // NOI18N
      openButton.setAction(new OpenAction("Open"));

   }

   @Override
   public Dimension getPreferredSize() {
      return new Dimension(PREF_W, PREF_H);
   }

   private void toTopBtnActionPerformed(java.awt.event.ActionEvent evt) {

      // ******** here **********
      imageJList.removeListSelectionListener(listSelectionListener);
      int selectedIndex = imageJList.getSelectedIndex();
      if (selectedIndex < 0) {
         return;
      }
      String temp = (String) listModel.remove(selectedIndex);
      listModel.add(0, temp);

      // ******** here **********
      imageJList.addListSelectionListener(listSelectionListener);
   }

   ListSelectionListener listSelectionListener = new ListSelectionListener() {
      public void valueChanged(ListSelectionEvent listSelectionEvent) {
         System.out.print("First index: " + listSelectionEvent.getFirstIndex());
         System.out.print(", Last index: " + listSelectionEvent.getLastIndex());

         String path = (String) imageJList.getSelectedValue();
         System.out.println("path should be here: " + path);
         Image img;
         try {
            System.out.println("path is null: " + (path == null));
            File imageFile = new File(path);
            img = ImageIO.read(imageFile);
            imageLabel.setIcon(new ImageIcon(img));
            imageLabel.setText("");
         } catch (IOException ex) {
            ex.printStackTrace();
         }
      }
   };

   private class OpenAction extends AbstractAction {
      public OpenAction(String text) {
         super(text);
      }

      public void actionPerformed(ActionEvent evt) {

         fc.setMultiSelectionEnabled(true);
         int returnVal = fc.showDialog(null, "Open");
         int len = 0;

         if (returnVal == JFileChooser.APPROVE_OPTION) {
            imageJList.removeListSelectionListener(listSelectionListener); //!!
            file = fc.getSelectedFiles();
            len = file.length;
            System.out.println("length = " + len);

            // this code should be inside the if block
            for (i = 0; i < len; i++) {
               String path = file[i].getPath();
               System.out.printf("%d: %s%n", i, path);
               listModel.add(i, path);
            }
            imageJList.setModel(listModel);
            imageJList.addListSelectionListener(listSelectionListener); //!!
         }
         // imageJList.updateUI(); //!! you shouldn't call this.
      }
   }

   private static void createAndShowGui() {
     MyToolView mainPanel = new MyToolView();

      JFrame frame = new JFrame("MyToolView");
      frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
      frame.getContentPane().add(mainPanel);
      frame.pack();
      frame.setLocationByPlatform(true);
      frame.setVisible(true);
   }

   public static void main(String[] args) {
      SwingUtilities.invokeLater(new Runnable() {
         public void run() {
            createAndShowGui();
         }
      });
   }
}

class JavaRenderer extends DefaultListCellRenderer {
   private int a;

   @Override
   public Component getListCellRendererComponent(JList jList1, Object value,
         int index, boolean isSelected, boolean hasFocus) {

      if (value instanceof String) {
         String name = (String) value;
         String[] splitedArray = null;
         splitedArray = name.split("\\\\");
         a = splitedArray.length - 1;
         name = splitedArray[a];
         System.out.println("name " + name);
         return super.getListCellRendererComponent(jList1, name, index,
               isSelected, hasFocus);// what we display
      } else {
         return super.getListCellRendererComponent(jList1, value, index,
               isSelected, hasFocus);// what we take
      }
   }
}