0

すぐに対話できるように (数独ソルバー用に) テーブルを作成しましたが、マウス イベント (入力、終了、クリック) は、セルをクリックした後にのみセル レンダラーに到達します。(レンダラーをアクティブにする前に、セルごとに 1 回クリックする必要があります。後でそのセルに戻ると、すぐに機能します。)

コードを変更してテーブル セルをすぐにアクティブにするにはどうすればよいですか? または、マウスの最初のクリックで正確に何が起こるかを調べて、テーブルの作成直後にこれらの操作を実行できるようにすることはできますか? (UI 階層のすべてのレベルでマウス イベントをキャッチしようとしましたが、見つかりませんでした。)

テーブルを最小 1x1 に縮小し、不要なコードをすべて削除しました。残りのコードを以下に示します。マウス オーバー (小さな黒い四角形が表示されます) は、1 回のクリック後にのみアクティブになることに注意してください。(コードは完成しており、そのままコンパイルできます。)

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);
  }
}
4

1 に答える 1

1

これは、レンダラーがイベントを処理することを想定していないためです。レンダラーは、テーブルまたは列のすべてのセルを描画するためにのみ使用される固有のコンポーネントです。

テーブルがそれ自体を描画するとき、セルを反復処理します。セルごとに、レンダラー コンポーネントが変更され、レンダラー コンポーネントの「スクリーンショット」が取得され、表のセルに貼り付けられます。そのため、イベントを処理できません。テーブル自体にイベント リスナーを追加する必要があります。レンダラーではありません。

レンダラーはエディターでもあり、エディターはイベントを処理できるため、クリックすると機能します。しかし、あなたのテーブルは実際には編集可能ではなく、エディターをまったく持つべきではないように思えます。むしろ、テーブルにリスナーを追加してください。

于 2012-12-07T12:11:51.350 に答える