2009-02-18 39 views
8

Tôi đang gặp sự cố với mã sau, nơi tôi sử dụng JComboBox để thay đổi giá trị Chuỗi trong ô bảng. JComboBox hoạt động tốt, nhưng nếu tôi nhấp vào hộp và sau đó nhấp chuột đi mà không chọn bất kỳ thứ gì danh sách thả xuống của JComboBox vẫn hiển thị, ngay cả khi tôi xóa hàng. Nhấp vào một thành phần Swing khác như JButton thường khiến nó biến mất, nhưng không phải lúc nào cũng vậy.vấn đề tiêu điểm bằng cách sử dụng JComboBox làm trình chỉnh sửa ô trong JTable


    TableColumn col = myTable.getColumnModel().getColumn(0); 
    JComboBox eq = new JComboBox(); 
    eq.addItem("=="); 
    eq.addItem("!="); 
    DefaultCellEditor editor = new DefaultCellEditor(eq); 
    col.setCellEditor(editor);

Edit: tôi đã bị lãng quên kể rằng trước đó tôi đặt:


    myTable.putClientProperty("terminateEditOnFocusLost", Boolean.TRUE); 

Nếu tôi nhận xét dòng này ra hoặc thiết lập nó sai, sau đó nhấp vào các thành phần Swing khác KHÔNG gây hộp biến mất. Với nó trong, nhấp vào bất cứ điều gì mà tập trung làm cho hộp để đi xa, làm cho vấn đề ít gây phiền nhiễu nhưng có thể che giấu nguyên nhân của hành vi.

Tôi có làm gì sai ở đây hoặc quên một bước không? Cách khác, có cách nào buộc nó đóng cửa không?

Cảm ơn!

Trả lời

11

Để hiểu điều này, bạn cần phải hiểu những gì diễn ra với bảng có thể chỉnh sửa. Một chút lý thuyết ngắn:

Mỗi ô có trình kết xuất và trình chỉnh sửa tiềm năng. Trình kết xuất chỉ báo cho ô biết cách vẽ và không tương tác với các sự kiện. Tuy nhiên, trình soạn thảo là một thành phần có thể tương tác với các sự kiện. Khi một sự kiện xảy ra kích hoạt chỉnh sửa, thành phần trình chỉnh sửa sẽ được thêm vào đầu bảng. Khi chỉnh sửa kết thúc, thành phần sẽ bị xóa.

Để làm cho thành phần biến mất, bạn sẽ phải đảm bảo rằng ô vẫn không ở trạng thái "chỉnh sửa". Đây là lý do tại sao terminateEditOnFocusLast làm cho JComboBox biến mất. Nếu bạn muốn những thứ khác để có được hộp để đi, bạn sẽ cần phải có thể gọi removeEditor() để đáp ứng với các sự kiện nhất định, có thể tập trung, hoặc lựa chọn ô.

Để thực sự xử lý những gì xảy ra, tôi khuyên bạn nên xem nhanh mã nguồn để removeEditor(), editCellAt() v.v. và có thể từng bước một trong trình gỡ lỗi. Có thể bạn đã ghi đè một số mã xử lý sự kiện hoặc đang gọi nó khi bạn không nên. Trình soạn thảo/sự kiện xử lý mã trong JTable là khá mong manh, và nó khá dễ dàng do tai nạn để có được các cuộc gọi xảy ra theo thứ tự sai với các hiệu ứng phụ buồn cười.

Ngoài ra, Java rất tinh tế đã thay đổi hành vi sự kiện và tập trung của JTable giữa các phiên bản một lần, tôi nghĩ rằng nó nằm trong khoảng từ 1,4 đến 1,5, khi việc xử lý tập trung cho swing thay đổi. Vì vậy, điều đầu tiên tôi khuyên bạn nên thử là mã của bạn với một phiên bản Java khác. Lỗi này có thể do Sun gây ra (một số mã trình soạn thảo phức tạp của chúng ta phải được thay đổi) và nếu nó khác nhau giữa các phiên bản thì sẽ dễ dàng báo cáo với Sun.

+0

Cảm ơn cho nền và câu trả lời thấu đáo. Tôi đã xem xét các phương pháp đó nhưng chưa bật lên bất kỳ thứ gì. Tôi nghĩ rằng về cơ bản bạn đã có câu trả lời đúng, mặc dù tôi chỉ cần tìm ra nơi nó đang xảy ra. Cảm ơn! –

+0

Câu trả lời hoàn toàn tuyệt vời! –

+0

Cảm ơn bài học về sự khác biệt giữa trình kết xuất và trình chỉnh sửa. Rất hữu ích. – Boundless

1

Tôi biết câu hỏi này là cũ nhưng để tham khảo ở đây là giải pháp của tôi. Tôi mở rộng DefaultCellEditor và lắng nghe cho JComboBox bị hủy sau đó buộc trình chỉnh sửa hủy.

import javax.swing.DefaultCellEditor; 
import javax.swing.JComboBox; 
import javax.swing.event.PopupMenuEvent; 
import javax.swing.event.PopupMenuListener; 

public class ComboBoxCellEditor extends DefaultCellEditor { 

    public ComboBoxCellEditor(JComboBox comboBox) { 
     super(comboBox); 
     comboBox.addPopupMenuListener(new PopupMenuListener() { 

      public void popupMenuWillBecomeVisible(PopupMenuEvent e) { 
      } 

      public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { 
      } 

      public void popupMenuCanceled(PopupMenuEvent e) { 
       cancelCellEditing(); 
      } 
     }); 
    } 
} 

Sau đó ...

DefaultCellEditor editor = new ComboBoxCellEditor(combobox); 
column.setCellEditor(editor); 
Các vấn đề liên quan