2012-12-07 21 views
0

我創建了即時交互表格(對於Sudoku求解器),但鼠標事件(輸入,退出,單擊)只有在單擊單元格後才能到達單元格渲染器。 (對於每個單元格,我必須在渲染器激活之前單擊一次,之後再回到該單元格,它將立即生效。)Java表格單元格渲染器僅在第一次點擊後處於活動狀態

如何更改我的代碼以立即激活表格單元格?或者我可以發現第一次鼠標點擊發生了什麼,所以我可以在表創建後立即執行這些操作? (我試圖捕捉所有層次的UI層次上的鼠標事件,但無法找到它。)

我已將表格縮小到1x1最小值,並刪除了所有不必要的代碼。剩下的代碼顯示在下面。請注意,鼠標懸停(僅顯示一個黑色方塊)僅在單擊一次後纔有效。 (代碼是完整的,可以按原樣編譯。)

import javax.swing.*; 
import javax.swing.event.CellEditorListener; 
import javax.swing.table.*; 
import java.awt.*; 
import java.awt.event.MouseEvent; 
import java.awt.event.MouseListener; 
import java.util.EventObject; 


public class GUI extends JFrame 
{ 
    private class Table extends JTable 
    { 
    public Table() 
    { 
     super(new AbstractTableModel() 
     { 
      public int getRowCount() { return 1; } 
      public int getColumnCount() { return 1; } 
      public Object getValueAt(int x, int y) { return null; } 
      @Override public boolean isCellEditable(int x, int y) { return true; } 
     }); 
    } 
    @Override public TableCellRenderer getCellRenderer(int x, int y) { return new Editor(); } 
    @Override public TableCellEditor getCellEditor(int x, int y) { return new Editor(); } 
    } 

    private class Editor extends JComponent implements TableCellEditor, TableCellRenderer, MouseListener 
    { 
    private boolean hasFocus = false; 

    public Editor() 
    { 
     addMouseListener(this); 
    } 

    @Override public void paintComponent(Graphics g) 
    { 
     if (hasFocus) 
     { 
     g.fillRect(0, 0, 9, 9); 
     } 
    } 

    public void mouseEntered(MouseEvent e) 
    { 
     hasFocus = true; 
     repaint(); 
    } 

    public void mouseExited(MouseEvent e) 
    { 
     hasFocus = false; 
     repaint(); 
    } 

    public void mouseClicked(MouseEvent e) { } 
    public void mousePressed(MouseEvent e) { } 
    public void mouseReleased(MouseEvent e) { } 

    public Object getCellEditorValue() { return 0; } 
    public boolean isCellEditable(EventObject e) { return true; } 
    public boolean shouldSelectCell(EventObject e) { return false; } 
    public boolean stopCellEditing() { return true; } 
    public void cancelCellEditing() { } 
    public void addCellEditorListener(CellEditorListener l) { } 
    public void removeCellEditorListener(CellEditorListener l) { } 
    public Component getTableCellEditorComponent(JTable t, Object v, boolean s, int x, int y) { return this; } 
    public Component getTableCellRendererComponent(JTable t, Object v, boolean s, boolean f, int x, int y) { return this; } 
    } 

    public static void main(String[] args) 
    { 
    new GUI(); 
    } 

    public GUI() 
    { 
    setContentPane(new Table()); 
    setDefaultCloseOperation (WindowConstants.EXIT_ON_CLOSE); 
    pack(); 
    setVisible(true); 
    } 
} 
+1

所有單元格都是可編輯的,但'setValueAt()'爲空。 – trashgod

+0

爲簡化測試代碼,刪除了編輯功能,它包含在原始代碼中。 – chaos

回答

1

這是因爲渲染器不應該處理事件。渲染器是一個獨特的組件,僅用於繪製表或列中的每個單元格。

當表格自己繪製時,它遍歷單元格。對於每個單元格,都會修改渲染器組件,然後將渲染器組件的「屏幕截圖」採集並粘貼到表格單元格中。所以它不能處理事件。您應該在表本身上添加一個事件偵聽器。不在渲染器上。

點擊後,它可以工作,因爲您的渲染器也是一個編輯器,編輯器可以處理事件。但在我看來,你的桌面其實是不可編輯的,而且你根本就不應該有一個編輯器。相反,在桌子上添加一個監聽器。

+0

好的,它可以將鼠標偵聽器移動到表類中。我以前曾嘗試過,但在各個層面上都有聽衆,可能會破壞它。 – chaos

相關問題