2012-06-21 27 views
10

"Có cách nào để ngăn không cho JList chọn phần tử cuối cùng khi người dùng nhấp vào bên dưới nó trong danh sách không?"Làm thế nào để ngăn chặn JList từ việc lựa chọn bên ngoài ranh giới di động?

Đó là câu hỏi mà một người nào đó đã hỏi here và tôi có cùng một vấn đề. Anh chàng đó đã tìm thấy một giải pháp quá (bằng cách ghi đè processMouseEvent()) nhưng tôi muốn biết nếu có một cách tốt hơn/thanh lịch hơn để làm điều đó.

[Chỉnh sửa]

Ok, chi tiết hơn. Nếu bạn có một JList và có một số không gian trống bởi bất kỳ ô/phần tử nào và bạn bấm vào khoảng trống đó thì phần tử cuối cùng trong JList đã được chọn.

Ví dụ thực tế, hãy thử số này JList Swing Tutorial example, nhấp vào khoảng trắng và thấy rằng Rollo đã được chọn.

+0

SO isn' máy phát mã t, để được trợ giúp tốt hơn sớm hơn, hãy đăng một [SSCCE] (http://sscce.org/), nếu không thì câu trả lời của tôi là câu hỏi đơn giản để 'tiêu thụ ' – mKorbel

+0

@GuillaumePolet thnx, hoàn toàn bỏ qua khía cạnh đó – Alex

+0

@mKorbel đơn giản ví dụ được thêm – Alex

Trả lời

16

Xem https://forums.oracle.com/forums/thread.jspa?threadID=2206996

import java.awt.EventQueue; 
import java.awt.Point; 
import java.awt.Toolkit; 
import java.awt.event.InputEvent; 
import java.awt.event.MouseAdapter; 
import java.awt.event.MouseEvent; 

import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JScrollPane; 

public class TestJList { 
    public static void main(String[] args) { 
     EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       JList list = new JList(new Object[] { "One", "Two", "Three" }) { 
        @Override 
        public int locationToIndex(Point location) { 
         int index = super.locationToIndex(location); 
         if (index != -1 && !getCellBounds(index, index).contains(location)) { 
          return -1; 
         } 
         else { 
          return index; 
         } 
        } 
       }; 

       list.addMouseListener(new MouseAdapter() { 

        @Override 
        public void mouseClicked(MouseEvent e) { 
         JList list = (JList) e.getSource(); 
         if (list.locationToIndex(e.getPoint()) == -1 && !e.isShiftDown() 
           && !isMenuShortcutKeyDown(e)) { 
          list.clearSelection(); 
         } 
        } 

        private boolean isMenuShortcutKeyDown(InputEvent event) { 
         return (event.getModifiers() & Toolkit.getDefaultToolkit() 
           .getMenuShortcutKeyMask()) != 0; 
        } 
       }); 

       JFrame frame = new JFrame("Test"); 
       frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); 
       frame.getContentPane().add(new JScrollPane(list)); 
       frame.pack(); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
+0

1 mã excelent, bởi cả hai áp phích trên OTN, vui lòng xem danh sách tất cả được tích hợp sẵn trong 'putClientProperty (...)' trong API Swing – mKorbel

+1

cũng đọc nhận xét của Kleopatra bên dưới câu trả lời. Nó có thể là một chút bất tiện để xóa lựa chọn. Kỳ vọng của tôi sẽ là không có gì xảy ra. Nếu tôi đã thực hiện một lựa chọn hợp lệ trước đây (và không nhất thiết là ô cuối cùng) và sau đó tôi nhấp vào bên ngoài JList, tôi sẽ muốn lựa chọn vẫn còn, không được xóa –

2

Nhìn vào các cuộc gọi stack, bạn có thể không thực sự làm những gì bạn muốn mà không phiền với AWT-Sự kiện:

Thread [AWT-EventQueue-0] (Suspended (breakpoint at line 384 in DefaultListSelectionModel)) 
    DefaultListSelectionModel.changeSelection(int, int, int, int, boolean) line: 384  
    DefaultListSelectionModel.changeSelection(int, int, int, int) line: 415 
    DefaultListSelectionModel.setSelectionInterval(int, int) line: 459 
    TestJList$1(JList<E>).setSelectionInterval(int, int) line: 2067 
    BasicListUI$Handler.adjustSelection(MouseEvent) line: 2739 
    BasicListUI$Handler.mousePressed(MouseEvent) line: 2695 
    AWTEventMulticaster.mousePressed(MouseEvent) line: 280 
    TestJList$1(Component).processMouseEvent(MouseEvent) line: 6502 
    TestJList$1(JComponent).processMouseEvent(MouseEvent) line: 3321  
    TestJList$1.processMouseEvent(MouseEvent) line: 24 
    TestJList$1(Component).processEvent(AWTEvent) line: 6270  
    TestJList$1(Container).processEvent(AWTEvent) line: 2229  
    TestJList$1(Component).dispatchEventImpl(AWTEvent) line: 4861 
    TestJList$1(Container).dispatchEventImpl(AWTEvent) line: 2287 
    TestJList$1(Component).dispatchEvent(AWTEvent) line: 4687 
    LightweightDispatcher.retargetMouseEvent(Component, int, MouseEvent) line: 4832 
    LightweightDispatcher.processMouseEvent(MouseEvent) line: 4489 
    LightweightDispatcher.dispatchEvent(AWTEvent) line: 4422  
    JFrame(Container).dispatchEventImpl(AWTEvent) line: 2273  
    JFrame(Window).dispatchEventImpl(AWTEvent) line: 2713 
    JFrame(Component).dispatchEvent(AWTEvent) line: 4687  
    EventQueue.dispatchEventImpl(AWTEvent, Object) line: 707  
    EventQueue.access$000(EventQueue, AWTEvent, Object) line: 101 
    EventQueue$3.run() line: 666  
    EventQueue$3.run() line: 664  
    AccessController.doPrivileged(PrivilegedAction<T>, AccessControlContext) line: not available [native method]  
    ProtectionDomain$1.doIntersectionPrivilege(PrivilegedAction<T>, AccessControlContext, AccessControlContext) line: 76  
    ProtectionDomain$1.doIntersectionPrivilege(PrivilegedAction<T>, AccessControlContext) line: 87 
    EventQueue$4.run() line: 680  
    EventQueue$4.run() line: 678  

Bạn có thể thực hiện ListUI của riêng bạn và sau đó làm bất cứ điều gì bạn muốn (bao gồm ngăn chặn hành vi không mong muốn này), nhưng tôi thực sự không khuyên bạn nên đi xuống con đường đó.

Đối với những gì nó có giá trị (nó được thực hiện bằng cách ghi đè các phương pháp processXXXEvent), đây là một đoạn nhỏ mà tôi thực sự tìm thấy không phải là xấu xí và có thể ngăn chặn việc lựa chọn đối tượng khi nhấp bên ngoài giới hạn của họ:

import java.awt.event.MouseEvent; 

import javax.swing.JFrame; 
import javax.swing.JList; 
import javax.swing.JScrollPane; 
import javax.swing.SwingUtilities; 

public class TestJList { 

    private JList list; 

    protected void initUI() { 
     JFrame frame = new JFrame("test"); 
     list = new JList(new Object[] { "Hello", "World", "!" }) { 

      private boolean processEvent(MouseEvent e) { 
       int index = list.locationToIndex(e.getPoint()); 
       return index > -1 && list.getCellBounds(index, index).contains(e.getPoint()); 
      } 

      @Override 
      protected void processMouseEvent(MouseEvent e) { 
       if (processEvent(e)) { 
        super.processMouseEvent(e); 
       } 
      } 

      @Override 
      protected void processMouseMotionEvent(MouseEvent e) { 
       if (processEvent(e)) { 
        super.processMouseMotionEvent(e); 
       } 
      } 
     }; 
     list.setVisibleRowCount(10); 

     frame.add(new JScrollPane(list)); 
     frame.pack(); 
     frame.setVisible(true); 
    } 

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

      @Override 
      public void run() { 
       new TestJList().initUI(); 
      } 
     }); 
    } 
} 
Các vấn đề liên quan