2017-06-04 69 views
0

定製的過渡效果,我已經在我的JTable與添加的TableCellRenderer與JLabel的圖片。但是,當鼠標移過單元格時,如何在JLabel上添加邊框到特定的列和行上?JTable中如何實現用的TableCellRenderer

這是第一次渲染器類:

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

如果您創建併發佈一個有效的[MCVE]這將有很大的幫助,一個小而完整的程序,只有必要的代碼,以證明您的問題,我們可以複製,粘貼,編譯和運行而無需修改,因爲這將有助於我們要充分理解你可能會做錯什麼。請注意,這是以代碼格式發佈的代碼,而不是作爲非現場資源的鏈接。 –

+0

將鼠標移動監聽器添加到單元格渲染器返回的組件。 – Antoniossss

+0

已經這樣做,但沒有影響:( – Kevin

回答

2

因此,對於你的表的特定列,你要畫上由鼠標(僅懸停細胞,只有在此列)徘徊在小區邊界。

(編輯:澄清後,似乎this question has been asked before - 我要離開我的回答如下,因爲它仍可能幫助)

  • 不動態更改單元格渲染器,只有1個渲染器列,並處理單個渲染器中的情況。

  • 不會在渲染器返回的Component上添加偵聽器:此類偵聽器不會被觸發,因爲該組件僅用於其邏輯運算paint()

  • 代替,添加上表本身鼠標移動偵聽器,並計算懸停的細胞與JTable的方法rowAtPointcolumnAtPoint,當鼠標移過表,或退出的區域的座標。

  • (與手頭上的問題無關,但值得一提)避免爲渲染器的每次調用創建新的JLabel,這是浪費。 Swing是單線程,它是安全的,重複使用相同的對象(前提是你不要忘記重置其所有屬性,可能有2個呼叫之間已經改變),顯示效果

小演示:

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:在演示中,我每次重繪整個可見區域,但是如果要優化它,應該只能重繪2個單元格,這是一個完整的新問題,請參閱here以獲得有關該問題的幫助。

+0

好吧,我會嘗試它,並告訴結果後 – Kevin

+0

[例如](https://stackoverflow.com/q/16814512/714968) – mKorbel

+0

感謝這項工程 – Kevin