【问题标题】:Hand cursor on disabled JTable禁用 JTable 上的手形光标
【发布时间】:2015-01-02 20:12:46
【问题描述】:

我在JScrollPane 中有一个JTable,使用enabled(false) 禁用它,但是我仍然想在鼠标悬停时更改为手形光标。我试过简单地手动设置表格的光标:

table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));

我已经尝试过覆盖 JTable 的 getCursor() 方法:

JTable table = new JTable(tableModel){
   @Override
   public Cursor getCursor() {
       return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); //DOESNT WORK
   }
};

但是这两种技术都不起作用。我必须采用的一种方法是将mouseMotionListener 添加到整个表中,但是问题在于,在实际应用程序中,按下表中的按钮会导致显示“JOptionpane”;如果用户继续将光标移出表格并关闭“JOptionPane”,则可能会出现错误。 'MouseMotionListener' 肯定是多余的......?

我还研究了覆盖JTable(以及随后的Component)的setEnabled 方法,但是我正在努力找出阻止显示手形光标的代码。任何帮助将非常感激!代码如下:

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

public class TableCursorTest {
    public TableCursorTest(){
        JFrame frame = new JFrame();
        JPanel panel = new JPanel(new GridBagLayout());
        GridBagConstraints constraints = new GridBagConstraints();
        String[] headers = {"Items"};
        Object[][] data = new Object[][]{{"item 1"},{"item 2"}};
        DefaultTableModel tableModel = new DefaultTableModel(data, headers);

        @SuppressWarnings("serial")
        @Override
           public Cursor getCursor() {
                return Cursor.getPredefinedCursor(Cursor.HAND_CURSOR); //DOESNT WORK
           }
        };

        JScrollPane scrollPane = new JScrollPane(table);
        table.setEnabled(false);
        table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); //DOESNT WORK


        constraints.gridx = 0;
        constraints.gridy = 0;
        constraints.weightx = 0;
        constraints.weighty = 0;
        panel.add(scrollPane, constraints);

        frame.setContentPane(panel);
        frame.setPreferredSize(new Dimension(500,500));
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.pack();
        frame.setVisible(true);
    }

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

}

更新:抱歉,问题缺少一些信息:表格并不总是填充滚动窗格,因此设置滚动窗格的手形光标会导致手形光标悬停在不存在的行上。如果可能,手形光标应该只出现在表格的行上。

【问题讨论】:

    标签: java swing jtable jcomponent mouse-cursor


    【解决方案1】:

    这个例子可以正常工作(如果当前类扩展了 Jpanel):

    table.addMouseMotionListener(new MouseMotionAdapter()
        {
               public void mouseMoved(MouseEvent e)
               {
                  int row = table.rowAtPoint(e.getPoint());
                  if (row > -1)
                  {
                     // easiest way:
                      table.clearSelection();
                      table.setRowSelectionInterval(row, row);
                      setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
    
                  }
                  else {
                      setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                  }
               }
            });
        table.getTableHeader().addMouseMotionListener(new MouseMotionAdapter()
        {
               public void mouseMoved(MouseEvent e)
               {
                   setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
               }
            });
    

    【讨论】:

      【解决方案2】:

      如果你的意图是disable editing,你可以覆盖表模型documentationisCellEditable方法

      另外,如果需要disable row selection,可以将rowSelectionAllowed设置为false

      您可以将mouseListener 添加到您的表格中,并为自定义光标覆盖mouseEnteredmouseExited,就像这样

          table.addMouseListener(new MouseAdapter()
          {
      
              @Override
              public void mouseExited(MouseEvent e)
              {
                  table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
              }
      
              @Override
              public void mouseEntered(MouseEvent e)
              {
                  table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
              }
      
          });
      

      一个完整的工作示例:

      public class TableCursorTest
      {
          JFrame frame = new JFrame();
          JPanel panel = new JPanel(new GridBagLayout());
          GridBagConstraints constraints = new GridBagConstraints();
          String[] headers = { "Items" };
          Object[][] data = new Object[][] { { "item 1" }, { "item 2" } };
          @SuppressWarnings("serial")
          DefaultTableModel tableModel = new DefaultTableModel(data, headers)
          {
              public boolean isCellEditable(int row, int column)
              {
                  return false;
              };
          };
      
          public TableCursorTest()
          {
              final JTable table = new JTable(tableModel);
      
              table.addMouseListener(new MouseAdapter()
              {
      
                  @Override
                  public void mouseExited(MouseEvent e)
                  {
                      table.setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
                  }
      
                  @Override
                  public void mouseEntered(MouseEvent e)
                  {
                      table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
                  }
      
              });
      
              table.setRowSelectionAllowed(false);
      
              JScrollPane scrollPane = new JScrollPane(table);
              // table.setEnabled(false);
              // scrollPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));
              // // DOESNT
              // WORK
      
              constraints.gridx = 0;
              constraints.gridy = 0;
              constraints.weightx = 0;
              constraints.weighty = 0;
              panel.add(scrollPane, constraints);
      
              frame.setContentPane(panel);
              frame.setPreferredSize(new Dimension(500, 500));
              frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
              frame.pack();
              frame.setVisible(true);
          }
      
          public static void main(String[] args)
          {
              SwingUtilities.invokeLater(new Runnable()
              {
                  @Override
                  public void run()
                  {
                      new TableCursorTest();
                  }
              });
          }
      }
      

      【讨论】:

        【解决方案3】:
        table.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); //DOESNT WORK
        

        虽然..

        scrollPane.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); //DOES WORK
        

        【讨论】:

        • 您好安德鲁,感谢您的回复。 Scrollpane.setCursor 确实成功地更改了 handCursor,但是它更改了整个窗格的光标。我只希望手形光标悬停在 jtable 的行上,它并不总是足够大以填满表格。
        • “我只希望手形光标在 jtable 的行上。” 挑剔,挑剔。 ;)
        • 哈抱歉!我也试过scrollPane.getViewport().getComponent(0).setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR));,但没有任何影响。
        猜你喜欢
        • 2012-03-16
        • 1970-01-01
        • 1970-01-01
        • 2018-04-06
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多