2013-07-30 3 views
4

JTable의 행 헤더를 작성하려고하고있다. 나는 내 연구 herehere을했지만, 거의 아무것도 없다. 내가 찾은 것은 시스템을 계속 보이게하지 않았다.JTable 행 헤더 Look & Feel

이것은 내가 지금까지 발견 한 것입니다 :

enter image description here

첫 번째 열 (이름이없는 사람이) 내가 얻을 수있는 최고입니다. 테이블 헤더 렌더러를 가져 와서 행 셀에 적용했습니다. 그것은 부분적으로 효과가있었습니다. 보시다시피 내림차순/오름차순 정렬에 대한 작은 화살표 아이콘이 열의 모든 셀에 나타나며 셀은 이제 회색으로 표시됩니다. 그것 이외의 완전한 실패. 또한, 내 행 헤더에 어떤 화살표 아이콘도 원하지 않습니다.

Col 1은 UIManager에서 모양과 느낌을 적용하려고했을 때 발생했습니다. 분명히 작동하지 않았다.

콜 2는 포토샵입니다. 그게 내가하려는 일입니다.

다른 2 개 열에 대해서는 아무 것도하지 않았으므로 기본 설정입니다.

질문 : 어떻게 행 헤더와 물론 더 작은 화살표 아이콘을 만들기 위해 행 셀 시스템 (뿐만 아니라 창) 기본 테이블 헤더의 모양과 느낌을 줄 수 있습니다.

여기서 코드

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

I은 ​​단지 코드 부분을 용액을 첨가한다. Col 3은 이제 좋은 모습을 보였으 나 아직 느낌이 부족합니다 (마우스가 끝나지 않았습니다). 헤더를 얻는 가장 좋은 방법은 새 테이블을 만드는 것입니다.

+0

멋진 세계에 오신 것을 환영합니다. 나는 당신을 싫어합니다. 'DefaultTableCellHeaderRenderer'의 구현은 기본적으로'TableHeader'에 의해 사용 된 구현 시작을 기반으로하지 않습니다. – MadProgrammer

+0

1. 여기 몇 가지 시도가 있습니다. 좋은, 아주 좋은, 2.질문 : 실제 목표는 무엇입니까? 3. RowRorter ets에 문제가있을 수 있습니다. (시도하지 않음) 4. 이미지 및 SSCCE로 좋은 질문을 게시하기위한 +1, 5. 쉽게 대답 할 수 있음 - 렌더러에서 무엇이든 설정하지 않음, 렌더러가 속성 또는 값 생성기가 아님 6. 아무 것도하지 않음 L & F와 함께하지만 UIManager에 대한 키는 반복적으로 Renderer (이벤트 묶음, System.out.println 입력)에서 호출되며, 다른 L & F에서도 동일한 문제가 발생합니다. – mKorbel

+0

기본적으로 헤더에서와 같은 정확한 시각을 얻을 수 없습니다. lafs는 renderer가 columnHeader로 사용될 때 편향되도록 구성합니다. 정렬 아이콘을 없애려면 null 테이블을 사용하십시오. 이 컨텍스트에서 시도하지 않은 더러운 트릭은 이미지를 사용하는 것입니다. laf가 renderer를 columnHeader로 구성한다고 생각한 다음 해당 이미지를 셀 렌더러에 그립니다. – kleopatra

답변

3

시스템 LookAndFeel을 유지하려면 렌더러를 조금 변경해야합니다.

우선 렌더러를 UIRessource로 확장합니다. 당신은 UI 변경을 수신 할이 마커 인터페이스를 필요

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

그런 다음 (예를 들어, 생성자에 의해 전달 필드 defRenderer)을 얻을하고있는 JTableHeader에서 원래의 렌더러를 누르고 있습니다. 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 당신의 렌더러() 메서드를 무시하고 defRenderer에에 updateUI 호출을 delegete :

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

를가 많은 상황을 타개 할 가능성이 영수증과 함께. Plain paintComponent-rendering은 조금 더 복잡합니다 ;-) - 자신의 페인트 용 JLayer를 사용합니다 (Java 7에서 소개 됨)