2013-07-30 86 views
4

我想爲我的JTable創建行標題。我已經完成了我的研究herehere,但幾乎沒有什麼。我發現沒有保持系統看起來的感覺。JTable行標題的外觀和感覺

這是我到目前爲止已經發現:

enter image description here

第一列(一個沒有名字)是我能做到的最好。我將表格標題渲染器應用到行單元格中。它部分工作。正如您所看到的,降序/升序排列的小箭頭圖標出現在列的每個單元格中,並且單元格現在變成灰色。除此之外,它完全失敗。此外,我不希望我的行標題中有任何箭頭圖標。

Col 1是我嘗試應用UIManager的外觀時感受到的。顯然它不起作用。

第2列是photoshop,這正是我想要做的。

我沒有做任何其他2列,所以它的默認設置。

的問題是: 我怎麼可以給系統(未僅限於Windows)缺省表頭行單元格中,以創建一個行頭,當然沒有小箭頭圖標的外觀和感覺。

下面是代碼

import java.awt.Component; 
import java.awt.Dimension; 
import javax.swing.JFrame; 
import javax.swing.JScrollPane; 
import javax.swing.JTable; 
import javax.swing.UIManager; 
import javax.swing.table.DefaultTableColumnModel; 
import javax.swing.table.DefaultTableModel; 
import javax.swing.table.JTableHeader; 
import javax.swing.table.TableCellRenderer; 
import javax.swing.table.TableColumnModel; 
import sun.swing.table.DefaultTableCellHeaderRenderer; 

public class RowHeaderTest extends JFrame 
{ 

    public RowHeaderTest() 
    { 
     initComponents(); 
    } 

    private void initComponents() 
    { 
     setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE); 

     JScrollPane scrollPane = new JScrollPane(); 
     JTable table = new JTable(); 
     table.setAutoCreateRowSorter(true); 
     table.getTableHeader().setReorderingAllowed(false); 
     table.setModel(new DefaultTableModel(
       new Object[][] 
       { 
        { 
         "Row 1", "Data 2", "Data 3", "Data 4", "Data 5" 
        }, 
        { 
         "Row 2", "Data 6", "Data 7", "Data 8", "Data 9" 
        }, 
        { 
         "Row 3", "Data 10", "Data 11", "Data 12", "Data 13" 
        } 
       }, 
       new String[] 
       { 
        "", "Col 1", "Col 2", "Col 3", "Col 4" 
       })); 
     table.getColumnModel().getColumn(0).setHeaderRenderer(HeaderRenderer.THIS); 
     table.getColumnModel().getColumn(0).setCellRenderer(HeaderRenderer.THIS); 
     table.getColumnModel().getColumn(1).setHeaderRenderer(HeaderRendererUI.THIS); 
     table.getColumnModel().getColumn(1).setCellRenderer(HeaderRendererUI.THIS); 
     table.getColumnModel().getColumn(3).setHeaderRenderer(RowTableHeaderRendere.THIS); 
     table.getColumnModel().getColumn(3).setCellRenderer(RowTableHeaderRendere.THIS); 
     scrollPane.setViewportView(table); 
     setSize(new Dimension(400, 200)); 
     setLocationRelativeTo(null); 
     add(scrollPane); 
    } 

    public static void main(String args[]) 
    { 
     try 
     { 
      UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); 
     } 
     catch (ClassNotFoundException | InstantiationException | IllegalAccessException | javax.swing.UnsupportedLookAndFeelException ex) 
     { 
      java.util.logging.Logger.getLogger(RowHeaderTest.class.getName()).log(java.util.logging.Level.SEVERE, null, ex); 
     } 
     java.awt.EventQueue.invokeLater(new Runnable() 
     { 
      public void run() 
      { 
       new RowHeaderTest().setVisible(true); 
      } 
     }); 
    } 
} 

final class HeaderRenderer extends DefaultTableCellHeaderRenderer 
{ 

    public static final HeaderRenderer THIS = new HeaderRenderer(); 

    @Override 
    public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, 
      boolean hasFocus, int row, int column) 
    { 
     TableCellRenderer renderer = table.getTableHeader().getDefaultRenderer(); 
     return renderer.getTableCellRendererComponent(table, value, isSelected, 
       hasFocus, row, column); 
    } 
} 

final class HeaderRendererUI extends DefaultTableCellHeaderRenderer 
{ 

    public static final HeaderRendererUI THIS = new HeaderRendererUI(); 

    @Override 
    public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, 
      boolean hasFocus, int row, int column) 
    { 
     setText(value.toString()); 
     //TableHeader.ancestorInputMap 
     setBackground(isSelected ? UIManager.getColor("TableHeader.focusCellBackground") : UIManager.getColor("TableHeader.background")); 
     setBorder(UIManager.getBorder("TableHeader.cellBorder")); 
     setFont(UIManager.getFont("TableHeader.font")); 
     setForeground(UIManager.getColor("TableHeader.foreground")); 
     return this; 
    } 
} 

final class RowTableHeaderRendere extends DefaultTableCellHeaderRenderer 
{ 

    public static final RowTableHeaderRendere THIS = new RowTableHeaderRendere(); 

    @Override 
    public Component getTableCellRendererComponent(
      JTable table, Object value, boolean isSelected, 
      boolean hasFocus, int row, int column) 
    { 
     JTable t = new JTable(new DefaultTableModel(
       null, 
       new String[] 
       { 
        value.toString() 
       })); 
     return t.getTableHeader(); 
    } 
} 

EDIT

我剛添加部分解決的代碼。 Col 3現在看起來很好看,但仍然缺乏感覺(它沒有鼠標懸停),我不太確定創建一個新表格只是爲了獲得標題是實現它的最佳方式。

+0

歡迎來到我討厭你的外觀和感覺的奇妙世界。 'DefaultTableCellHeaderRenderer'的實現不是基於'TableHeader'默認使用的實現。 – MadProgrammer

+0

1.這裏有一些嘗試,包括好,非常好,2。問什麼是真正的目標3. RowRorter ets可能存在問題。 (未嘗試)4. +1發佈很好的問題,與圖像和SSCCE,5.可能是如此容易回答 - >不要在Renderer中設置任何東西,渲染器是裝飾器而不是屬性或值生成器6.沒有任何東西用L&F做,但用UIManager的鍵從Renderer重複調用(一堆事件放在那裏System.out.println),同樣的問題在另一個L&F太 – mKorbel

+0

基本上,你不能得到像標題一樣的確切視覺效果: lafs將渲染器配置爲偏向於用作columnHeader。要擺脫排序圖標,請輸入空表格。一個骯髒的技巧(在這種情況下沒有嘗試)是使用圖像:使laf相信它將渲染器配置爲columnHeader,然後將該圖像繪製到單元格渲染器中。 – kleopatra

回答

3

爲了保持系統LookAndFeel,您需要稍微改變渲染器。

首先使用UIRessource擴展您的渲染器。你需要這個標記接口來接收用戶界面的變化:

class HeaderRenderer extends DefaultTableCellHeaderRenderer 
        implements javax.swing.plaf.UIResource { 

然後得到並從JTableHeader上保持原有的渲染器(例如,通過構造函數傳遞場defRenderer)。在你的getTableCellRendererComponent中調用defRenderer.getTableCellRendererComponent,修改並返回這個JLabel。

private final TableCellRenderer defRenderer; 

HeaderRenderer (TableCellRenderer defRenderer) { 
    this.defRenderer = defRenderer; 
} 

@Override 
public Component getTableCellRendererComponent(
     JTable table, Object value, boolean isSelected, 
     boolean hasFocus, int row, int column) { 
    Component c = defRenderer.getTableCellRendererComponent (...); 
    if (c instanceof JLabel) { 
    JLabel lbl = (JLabel)c; 
    // do anything you want... 
    } 
    return c; 
} 

至少覆蓋updateUI在渲染()方法和delegete的updateUI調用defRenderer:

@Override 
public void updateUI() { 
    TableCellRenderer locDefRenderer = defRenderer; 
    if (locDefRenderer instanceof JComponent) { 
    ((JComponent) locDefRenderer).updateUI(); 
    } else { 
    super.updateUI(); 
    } 
} 

有了這個收據是可以改變很多事情。普通paintComponent渲染有點複雜;-) - 對於自己的油漆使用JLayer(在Java 7中引入)