当前位置: 首页 > 知识库问答 >
问题:

JTable:如何使用TableCellRenderer实现自定义滚动效果

韦原
2023-03-14

我已经在带有TableCellRenderer的JTable中添加了一个带有JLabel的图片。但是,当鼠标移动到单元格上时,如何在特定的列和行上为JLabel添加边框呢?

这是第一个呈现器类:

public class RenderTabel implements TableCellRenderer{
@Override
public Component getTableCellRendererComponent(JTable table, Object 
value,boolean isSelected, boolean hasFocus,int row, int column){

   JLabel gambar=new JLabel();
   String url="D:\\Kuliah Semester 4\\Pemrograman Berorientasi Objek\\DINUS BOOKSTORE\\image";
   ImageIcon img=scalegmbr(url+"\\"+table.getModel().getValueAt(row, 0)+".png");
   gambar.setIcon(img);
   gambar.setText("");
   gambar.setHorizontalAlignment(SwingConstants.CENTER);


        table.setRowHeight(row, 50);


        table.getColumnModel().getColumn(column).setPreferredWidth(80); 
 return gambar;       
 }
  public  ImageIcon scalegmbr(String file){
   Image image=new ImageIcon(file).getImage();
   return new ImageIcon(image.getScaledInstance(80,50,SCALE_SMOOTH));
 }
 }

这是第二个呈现器类:

public class RenderTabel1 implements TableCellRenderer{
@Override
public Component getTableCellRendererComponent(JTable table, Object 
value,boolean isSelected, boolean hasFocus,int row, int column){

   JLabel gambar=new JLabel();
   String url="D:\\Kuliah Semester 4\\Pemrograman Berorientasi Objek\\DINUS BOOKSTORE\\image";
   ImageIcon img=scalegmbr(url+"\\"+table.getModel().getValueAt(row, 0)+".png");
   gambar.setIcon(img);
   gambar.setText("");
   gambar.setHorizontalAlignment(SwingConstants.CENTER);
  gambar.setBorder(javax.swing.BorderFactory.createLineBorder(new java.awt.Color(200, 100, 52), 2));

        table.setRowHeight(row, 50);


        table.getColumnModel().getColumn(column).setPreferredWidth(80); 
  return gambar;       
  }
   public  ImageIcon scalegmbr(String file){
   Image image=new ImageIcon(file).getImage();
   return new ImageIcon(image.getScaledInstance(80,50,SCALE_SMOOTH));
 }
}

这就是我在JTable中设置鼠标输入和鼠标单击的方式:

private void tblbukuMouseEntered(java.awt.event.MouseEvent evt) {                                     
    // TODO add your handling code here: 



    tblbuku.getColumnModel().getColumn(6).setCellRenderer( new RenderTabel1());
}                                    

private void tblbukuMouseExited(java.awt.event.MouseEvent evt) {                                    
    // TODO add your handling code here:
    tblbuku.getColumnModel().getColumn(6).setCellRenderer( new RenderTabel());

}   

但当鼠标移动到第6列的一个单元格时,这会为该列中的所有单元格添加一个边框。当鼠标进入特定的行和列时,如何将它只变成特定的行和列?

共有1个答案

龚彬
2023-03-14

因此,对于表中的特定列,您希望在鼠标悬停的单元格上绘制边框(仅在该列中的悬停单元格)。

(编辑:经过澄清后,这个问题似乎以前有人问过--我将我的答案留在下面,因为它可能仍有帮助。)

>

  • 不要动态更改单元格呈现器,该列只有一个呈现器,并在单个呈现器中处理这种情况。

    不要在呈现器返回的组件上添加侦听器:这样的侦听器不会被触发,因为组件仅用于其paint()-ing逻辑。

    相反,在表本身上添加一个鼠标移动侦听器,并在鼠标移动到表上或退出区域时,使用JTable的方法RoWatpointColumnatpoint计算悬停单元格的坐标。

    (与手头的问题无关,但值得一提)避免为呈现器的每次调用创建新的jlabel,这是浪费的。Swing是单线程的,重用同一个对象是安全的(前提是您不要忘记重置它在两次调用之间可能更改的所有属性)

    展示效果的小演示:

    import javax.swing.*;
    import javax.swing.table.DefaultTableCellRenderer;
    import java.awt.*;
    import java.awt.event.MouseAdapter;
    import java.awt.event.MouseEvent;
    
    public class SimpleTableDemo extends JPanel {
    
        public static void main(String[] args) {
            javax.swing.SwingUtilities.invokeLater(SimpleTableDemo::createAndShowGUI);
        }
    
        private int
                hoveredRow = -1,
                hoveredColumn = -1;
    
        SimpleTableDemo() {
            super(new GridLayout(1,0));
    
            String[] columnNames = {"First Name", "Last Name", "Sport", "# of Years", "Vegetarian"};
    
            Object[][] data = {
                    {"Kathy", "Smith", "Snowboarding", 5, Boolean.FALSE},
                    {"John", "Doe", "Rowing", 3, Boolean.TRUE},
                    {"Sue", "Black", "Knitting", 2, Boolean.FALSE},
                    {"Jane", "White", "Speed reading", 20, Boolean.TRUE},
                    {"Joe", "Brown", "Pool", 10, Boolean.FALSE}
            };
    
            final JTable table = new JTable(data, columnNames);
            table.setPreferredScrollableViewportSize(new Dimension(500, 70));
            table.setFillsViewportHeight(true);
            table.getColumn("Sport").setCellRenderer(new MyCellRenderer());
    
            table.addMouseMotionListener(new MouseAdapter() {
                public void mouseMoved(MouseEvent e) {
                    Point p = e.getPoint();
                    hoveredRow = table.rowAtPoint(p);
                    hoveredColumn = table.columnAtPoint(p);
                    table.repaint();
                }
                public void mouseExited(MouseEvent e) {
                    hoveredRow = hoveredColumn = -1;
                    table.repaint();
                }
            });
    
            JScrollPane scrollPane = new JScrollPane(table);
    
            add(scrollPane);
        }
    
        private static void createAndShowGUI() {
            JFrame frame = new JFrame("SimpleTableDemo");
            frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
            SimpleTableDemo newContentPane = new SimpleTableDemo();
            newContentPane.setOpaque(true);
            frame.setContentPane(newContentPane);
            frame.pack();
            frame.setVisible(true);
        }
    
        private class MyCellRenderer extends DefaultTableCellRenderer {
            @Override
            public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
                JLabel label = (JLabel) super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
                if (hoveredColumn == column && hoveredRow == row) {
                    label.setBorder(BorderFactory.createLineBorder(Color.GREEN, 2));
                }
                else {
                    label.setBorder(BorderFactory.createEmptyBorder(2, 2, 2, 2));
                }
                return label;
            }
        }
    
    }
    

    注意1:我使用的是默认的单元格呈现器,不像你,但同样的想法也适用。上面的演示是一个通用的示例,作为示例保留在这里比针对您的情况的特定解决方案更有用(例如,在我对问题的解释中,我理解有关图标的细节是不相关的)。

    注意2:在演示中,我每次都要重新绘制整个可见区域,但如果你想要优化,应该可以只重新绘制两个单元格,这是一个全新的问题,请参阅这里获得有关的帮助。

  •  类似资料:
    • 本文向大家介绍利用JS实现scroll自定义滚动效果详解,包括了利用JS实现scroll自定义滚动效果详解的使用技巧和注意事项,需要的朋友参考一下 前言 最近在公司开发项目的时候,原生滚动条中有些东西没办法自定义去精细的控制,于是开发一个类似于better-scroll一样的浏览器滚动监听的JS实现,下面我们就来探究一下自定义滚动需要考虑哪些东西,经过哪些过程。话不多说了,来一起看看详细的介绍吧。

    • 本文向大家介绍JS实现的页面自定义滚动条效果,包括了JS实现的页面自定义滚动条效果的使用技巧和注意事项,需要的朋友参考一下 本文实例讲述了JS实现的页面自定义滚动条效果。分享给大家供大家参考,具体如下: 这里演示网页上用的滚动条效果,是一个自定义的滚动条代码,除了上下两个箭头以外,滚动条和一般的浏览器基本差不多,鼠标滚轮滚动,滚动条滚动。html结构很简单,mainBox是外层div,conten

    • 本文向大家介绍JS自定义滚动条效果,包括了JS自定义滚动条效果的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了JS自定义滚动条的具体代码,供大家参考,具体内容如下 更多关于滚动效果的精彩文章点击下方专题: javascript滚动效果汇总 jquery滚动效果汇总 以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持呐喊教程。

    • 问题内容: 我正在尝试呈现jtable的特定行(它应该具有不同的背景色,并且应该具有粗体字符)。 我发现了几个有关如何实现自定义的问题,以及有关如何使用表以及本教程(表行渲染)的问题。 我正在使用来显示。我尝试实现两种解决方案,但都没有实现。调试时,可以看到正在创建新的jtable,但是没有调用方法中的断点。 我的代码如下: 如您所见,模型是我对的实现。 当然,我缺少了一些东西。我试图打电话看看是

    • 本文向大家介绍原生js实现自定义滚动条,包括了原生js实现自定义滚动条的使用技巧和注意事项,需要的朋友参考一下 本文实例为大家分享了js实现自定义滚动条的具体代码,供大家参考,具体内容如下 1.HTML文件 div1是滚动条,div2是滚动小球,div3是文本区域容器,div4是文本区域。 2.css样式文件 通过容器溢出隐藏,文本区域的绝对定位,然后再交给js处理。 3.js脚本代码 以上就是本

    • 本文向大家介绍javascript自定义滚动条实现代码,包括了javascript自定义滚动条实现代码的使用技巧和注意事项,需要的朋友参考一下 在工作中经常会遇到内容会超出固定的一个范围,超出的内容一般会使用到滚动条来滚动显示。 但是用浏览器默认的滚动条经常被产品经理鄙视,可是用css却改变不了滚动条的样式,还好,有万能的js ^_^~~ 网上有各种各样的插件,但最顺手的还是自己写的,还可以一边撸