2011-09-14 4 views
10

とJTableはどのように私はMouse CursorオーバーJTable'RowJPopupMenuを

私の質問に選択されている場合にのみトリガーとJPopupMenuを示す防ぐことができます。

...もし選択された行から getBoundsなどの別の方法があると Mouse位置していることを比較/決定を

私の簡単なsscceは、いずれかの行を選択することができ、JPopupMenu全体JTable

import java.awt.event.*; 
import javax.swing.*; 
import javax.swing.table.*; 

public class TableCheckBox extends JFrame { 

    private static final long serialVersionUID = 1L; 
    private JTable table; 

    public TableCheckBox() { 
     Object[] columnNames = {"Type", "Company", "Shares", "Price", "Boolean"}; 
     Object[][] data = { 
      {"Buy", "IBM", new Integer(1000), new Double(80.50), false}, 
      {"Sell", "MicroSoft", new Integer(2000), new Double(6.25), true}, 
      {"Sell", "Apple", new Integer(3000), new Double(7.35), true}, 
      {"Buy", "Nortel", new Integer(4000), new Double(20.00), false} 
     }; 
     DefaultTableModel model = new DefaultTableModel(data, columnNames); 
     table = new JTable(model) { 

      private static final long serialVersionUID = 1L; 

      @Override 
      public Class getColumnClass(int column) { 
       return getValueAt(0, column).getClass(); 
      } 
     }; 
     table.setPreferredScrollableViewportSize(table.getPreferredSize()); 
     JScrollPane scrollPane = new JScrollPane(table); 
     add(scrollPane); 
     createPopupMenu(); 
    } 

    private void createPopupMenu() { 
     JPopupMenu popup = new JPopupMenu(); 
     JMenuItem myMenuItem1 = new JMenuItem("cccccccccccccccccccccc"); 
     JMenuItem myMenuItem2 = new JMenuItem("bbbbbbbbbbbbbbbbbbbbbb"); 
     popup.add(myMenuItem1); 
     popup.add(myMenuItem2); 
     MouseListener popupListener = new PopupListener(popup); 
     table.addMouseListener(popupListener); 
    } 

    private class PopupListener extends MouseAdapter { 

     private JPopupMenu popup; 

     PopupListener(JPopupMenu popupMenu) { 
      popup = popupMenu; 
     } 

     @Override 
     public void mousePressed(MouseEvent e) { 
      maybeShowPopup(e); 
     } 

     @Override 
     public void mouseReleased(MouseEvent e) { 
      if (table.getSelectedRow() != -1) { 
       maybeShowPopup(e); 
      } 
     } 

     private void maybeShowPopup(MouseEvent e) { 
      if (e.isPopupTrigger()) { 
       popup.show(e.getComponent(), e.getX(), e.getY()); 
      } 
     } 
    } 

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

      @Override 
      public void run() { 
       TableCheckBox frame = new TableCheckBox(); 
       frame.setDefaultCloseOperation(EXIT_ON_CLOSE); 
       frame.pack(); 
       frame.setLocation(150, 150); 
       frame.setVisible(true); 
      } 
     }); 
    } 
} 
からトリガーされ、単に非たかっ反対の状態を示し、
+2

途中でいいSSCCE。 –

+0

です。ない。サブクラス。 。 _view_。ために。 _model_。理由。 – kleopatra

+0

私にとって(kleopatraによっても)うまくいった解決策はここにまだリンクされていません:http://stackoverflow.com/a/17316876/411282 –

答えて

7

それがハイライトされているためそれは、面白い質問ですねJComponentの欠落しているAPI:

popupMenusを登録するには、componentPopupMenuプロパティを使用することをお勧めします。関連APIが欠落している(そして実際に、この要件のために必要な)されているもの

void setComponentPopupMenu(JPopupMenu); 
JPopupMenu getComponentPopupMenu(); 
Point getPopupLocation(MouseEvent); 

ある

JPopupMenu getComponentPopupMenu(MouseEvent); 

getPopupLocationが(LAFの深いAWTEventHelperにより)と呼ばれているとして、この欠如は、すべてのより多くの迷惑ですの後、 getComponentPopup()。したがって、ポップアップをトリガした可能性のある最後のマウスイベントを格納し、ポップアップを返すかどうかを決定するようなハックの余裕はありません。その場所のnullを返すと、マウスの位置に表示されます。

唯一の(汚れた)ハック(私の手がMouseListenerで手を汚してしまうのを忘れていた;-) getComponentPopupをオーバーライドしてまたはそれは

table = new JTable(model) { 

     /** 
     * @inherited <p> 
     */ 
     @Override 
     public JPopupMenu getComponentPopupMenu() { 
      Point p = getMousePosition(); 
      // mouse over table and valid row 
      if (p != null && rowAtPoint(p) >= 0) { 
       // condition for showing popup triggered by mouse 
       if (isRowSelected(rowAtPoint(p))) { 
        return super.getComponentPopupMenu(); 
       } else { 
        return null; 
       } 
      } 
      return super.getComponentPopupMenu(); 
     } 

    }; 

副作用は、または問題にならないかもしれない、そのポップアップ示すがあれば、マウスがどこテーブル上記のようにキーボードによってトリガされないで現在のマウス位置に基づいて、返しません。

+0

、どのように簡単に学習しているか、精巧に感謝....hehehe、確かにあなたのポストは答えであり、別の私の問題を閉じている、私の+1 – mKorbel

+0

'JTable'を埋め込んだ' JScrollPane'の使用により、別の問題が生じるかもしれません。以前は、行の外側をクリックすると(空のスペースにある 'JScrollPane'の中で)、' JTable'で発生しないイベントに問題があることを覚えています: 'JScrollPane'自体のイベントを待ち受けなければなりませんでした(または、 'JViewport'が正確に覚えていない可能性があります)。だから、おそらく@mKorbel、それも考慮する必要があります( 'JScrollPane'が' JTable'よりも高いときは必ずそうするべきです)。 – jfpoilpret

+0

@jfpoilpret MouseからJViewPortまでのイベントをどのように消費することができないのか、JViewPortとの間でMouseEventsをconsimingする例を提供できますか?JComponent :-) – mKorbel

12

これはおそらくこのようなものをお探しですか?

だけで、選択した行の上に表示からポップアップを防ぐために、選択した行(複数可)のみ

private void maybeShowPopup(MouseEvent e) { 
    if (e.isPopupTrigger()) { 

     // get row that pointer is over 
     int row = table.rowAtPoint(e.getPoint()); 

     // if pointer is over a selected row, show popup 
     if (table.isRowSelected(row)) { 
      popup.show(e.getComponent(), e.getX(), e.getY()); 
     } 
    } 
    } 

あるいはその逆、上のポップアップを表示するには:

private void maybeShowPopup(MouseEvent e) { 
    if (e.isPopupTrigger()) { 
     int row = table.rowAtPoint(e.getPoint()); 
     int[] selectedRows = table.getSelectedRows(); 

     if (!table.isRowSelected(row)) { 
      popup.show(e.getComponent(), e.getX(), e.getY()); 
     } 
    } 
+1

+1私の別の視点にもかかわらず:)。実際には、あなたのものは簡単ですばらしい解決策です。 – Heisenbug

+1

+1 - 一度あなたはすべてのループとマニュアルのチェックをisRowSelected(行)で置き換えます:-) – kleopatra

+1

すごく申し訳ありません。私は完全に間違っていた。私がやりたいことはできないようです。しかし、@ kleopatra、私は知りたい:セルレンダラーがマウスイベントを処理できないという事実には何らかの正当な理由があるのだろうか? – Heisenbug

関連する問題