2011-10-01 62 views
4

是否有任何干净的方式允许用户选择JTable的多个非连续单元格? 或者我被迫实现我自己的ListSelectionModel?我使用JTable上的setCellSelectionEnabled()和setSelectionModel()方法玩过,但我只能选择连续单元组。单独的而不是连续的JTable的单元格选择

编辑:

我试了@mKorbel很好的SSCCE。它对列表工作正常,但它似乎没有完全在表上工作。这里是一个SSCCE:

import java.awt.Component; 

import java.awt.event.InputEvent; 
import java.awt.event.MouseEvent; 

import javax.swing.JFrame; 
import javax.swing.JPanel; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 


public class TableSelection extends JFrame{ 
    String[] columnNames = {"First Name", 
      "Last Name", 
      "Sport", 
      "# of Years", 
      "Vegetarian"}; 
    Object[][] data = { 
      {"Kathy", "Smith", 
      "Snowboarding", new Integer(5), new Boolean(false)}, 
      {"John", "Doe", 
      "Rowing", new Integer(3), new Boolean(true)}, 
      {"Sue", "Black", 
      "Knitting", new Integer(2), new Boolean(false)}, 
      {"Jane", "White", 
      "Speed reading", new Integer(20), new Boolean(true)}, 
      {"Joe", "Brown", 
      "Pool", new Integer(10), new Boolean(false)} 
     }; 

    public TableSelection(){ 
     JPanel main= new JPanel(); 
     JTable table = new JTable(data, columnNames){ 
      @Override 
       protected void processMouseEvent(MouseEvent e) { 
        int modifiers = e.getModifiers() | InputEvent.CTRL_MASK; 
        // change the modifiers to believe that control key is down 
        int modifiersEx = e.getModifiersEx() | InputEvent.CTRL_MASK; 
        // can I use this anywhere? I don't see how to change the modifiersEx of the MouseEvent 
        MouseEvent myME = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), modifiers, e.getX(), 
          e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e.getButton()); 
        super.processMouseEvent(myME); 
       } 

     }; 
     JScrollPane pane = new JScrollPane(table); 
     main.add(pane); 
     this.add(main); 

     this.setSize(800, 600); 
     this.setVisible(true); 
    } 
    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 
     // TODO Auto-generated method stub 
     new TableSelection(); 
    } 

} 

我可以选择非连续的行,但不是单个单元格。我的意思是,我想能够选择单元格0,0和3,3例如。

+0

不可能用两个一维选择模型的叠加。你需要一个真正的二维模型。旧的codeguru网站上曾经有一个例子,它需要在ui代理中进行调整。不知道现在是/现在在哪里 – kleopatra

+0

@kleopatra:谢谢。我想我会找到一个不同的解决方案。 – Heisenbug

+0

我可以把赏金放在你的问题上,也许有另一种解决方案,当然是 – mKorbel

回答

9
  1. 如果没有为JTable#setSelectionMode(ListSelectionModel.SINGLE_SELECTION)定义,那么CTRL + MOUSE_CLICK

  2. 还是你的意思还记得最后一次选择的?

  3. ListSelectionModelJTableJList两者使用。

enter image description hereenter image description hereenter image description hereenter image description hereenter image description here

import java.awt.Component; 
import java.awt.event.InputEvent; 
import java.awt.event.MouseEvent; 
import javax.swing.*; 

public class Ctrl_Down_JList { 

    private static void createAndShowUI() { 
     String[] items = {"Sun", "Mon", "Tues", "Wed", "Thurs", "Fri", "Sat"}; 
     JList myJList = new JList(items) { 

      private static final long serialVersionUID = 1L; 

      @Override 
      protected void processMouseEvent(MouseEvent e) { 
       int modifiers = e.getModifiers() | InputEvent.CTRL_MASK; 
       // change the modifiers to believe that control key is down 
       int modifiersEx = e.getModifiersEx() | InputEvent.CTRL_MASK; 
       // can I use this anywhere? I don't see how to change the modifiersEx of the MouseEvent 
       MouseEvent myME = new MouseEvent((Component) e.getSource(), e.getID(), e.getWhen(), modifiers, e.getX(), 
         e.getY(), e.getXOnScreen(), e.getYOnScreen(), e.getClickCount(), e.isPopupTrigger(), e.getButton()); 
       super.processMouseEvent(myME); 
      } 
     }; 
     JFrame frame = new JFrame("Ctrl_Down_JList"); 
     frame.getContentPane().add(new JScrollPane(myJList)); 
     frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     frame.pack(); 
     frame.setLocationRelativeTo(null); 
     frame.setVisible(true); 
    } 

    public static void main(String[] args) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       createAndShowUI(); 
      } 
     }); 
    } 
+0

+1:哇..它似乎工作。我会尝试使用JTable。 – Heisenbug

+0

+1在Mac OS上使用⌘-click进行非连续选择。 – trashgod

+0

我更新了我的问题。看看 – Heisenbug

7

使用MULTIPLE_INTERVAL_SELECTION,如图。

附录:由于ListSelectionModelMULTIPLE_INTERVAL_SELECTION也提供给JList,你可以利用后者的HORIZONTAL_WRAP获得非连续选择,如下图所示。

enter image description here

控制台:

 
[Cell:06] 
[Cell:06, Cell:16] 
[Cell:06, Cell:16, Cell:18] 
[Cell:06, Cell:08, Cell:16, Cell:18] 

代码:

import java.awt.*; 
import java.util.Arrays; 
import javax.swing.*; 
import javax.swing.event.*; 

/** 
* @see http://stackoverflow.com/questions/7620579 
* @see http://stackoverflow.com/questions/4176343 
*/ 
public class ListPanel extends JPanel { 

    private static final int N = 5; 
    private DefaultListModel dlm = new DefaultListModel(); 
    private JList list = new JList(dlm); 

    public ListPanel() { 
     super(new GridLayout()); 
     for (int i = 0; i < N * N; i++) { 
      String name = "Cell:" + String.format("%02d", i); 
      dlm.addElement(name);    
     } 
     list.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); 
     list.setLayoutOrientation(JList.HORIZONTAL_WRAP); 
     list.setVisibleRowCount(N); 
     list.setCellRenderer(new ListRenderer()); 
     list.addListSelectionListener(new SelectionHandler()); 
     this.add(list); 
    } 

    private class ListRenderer extends DefaultListCellRenderer { 

     public ListRenderer() { 
      this.setBorder(BorderFactory.createLineBorder(Color.red)); 
     } 

     @Override 
     public Component getListCellRendererComponent(JList list, Object 
      value, int index, boolean isSelected, boolean cellHasFocus) { 
      JComponent jc = (JComponent) super.getListCellRendererComponent(
       list, value, index, isSelected, cellHasFocus); 
      jc.setBorder(BorderFactory.createEmptyBorder(N, N, N, N)); 
      return jc; 
     } 
    } 

    private class SelectionHandler implements ListSelectionListener { 

     @Override 
     public void valueChanged(ListSelectionEvent e) { 
      if (!e.getValueIsAdjusting()) { 
       System.out.println(Arrays.toString(list.getSelectedValues())); 
      } 
     } 
    } 

    private void display() { 
     JFrame f = new JFrame("ListPanel"); 
     f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     f.add(this); 
     f.pack(); 
     f.setLocationRelativeTo(null); 
     f.setVisible(true); 
    } 

    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 

      @Override 
      public void run() { 
       new ListPanel().display(); 
      } 
     }); 
    } 
} 
+0

好吧,它似乎不工作。我无法通过这种方式选择多个不是连续的单个单元格。 – Heisenbug

+0

我在Windows上用ctrl修饰符试它。但是现在我正在检查错误,因为即使@ mKorbel的解决方案似乎与我的JTable一起工作。也许我在其他地方有一个bug。 – Heisenbug

+0

我试图从我的代码中提取它,但它并不那么简单。我有几个类参与:构建与自定义渲染器和编辑器的JTable扩展的构建器,等等。 – Heisenbug

相关问题