2011-10-01 106 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

相關問題