2011-02-04 8 views
5

JTextArea를 TableCellRenderer로 사용하는 JTable을 사용하므로 표 셀에서 단어 줄 바꿈을 사용할 수 있습니다. JTable이 잘 표시됩니다. JTable의 print method을 통해 테이블을 프린터로 인쇄 할 때 출력은 항상 데이터의 약 60 %에서 잘립니다. 다른 컴퓨터와 다른 프린터, 다른 프린터 드라이버, 다른 JVM 버전 (1.5, 1.6)을 시도했지만 그 중 아무 것도 도움이되지 않았습니다. 다음은이 문제를 재현하는 자체 포함 된 Java 기본 클래스입니다. 어떤 아이디어?잘라진 JTable 인쇄 출력

import java.awt.*; 
import java.awt.event.*; 
import java.awt.print.*; 
import java.util.*; 
import javax.swing.*; 
import javax.swing.table.*; 

public class JTextAreaJTableTest extends javax.swing.JFrame { 

    public static void main(String args[]) { 
     java.awt.EventQueue.invokeLater(new Runnable() { 
      public void run() { 
       JTextAreaJTableTest frame = new JTextAreaJTableTest(); 
       frame.setSize(640, 480); 
       frame.setLocationRelativeTo(null); 
       frame.setVisible(true); 
      } 
     }); 
    } 

    JButton jButtonPrint; 
    JScrollPane jScrollPane; 
    JTable jTable; 
    JToolBar jToolBar; 

    public JTextAreaJTableTest() { 
     initComponents(); 

     DefaultTableModel dtm = (DefaultTableModel) jTable.getModel(); 
     Vector<Vector<String>> data = new Vector<Vector<String>>(); 
     for (int i = 0; i < 50; i++) { 
      Vector<String> rowData = new Vector<String>(); 
      rowData.add("Entry " + i); 
      rowData.add("Lorem ipsum dolor sit amet, consectetur adipisicing" 
        + " elit, sed do eiusmod tempor incididunt ut labore et" 
        + " dolore magna aliqua. Ut enim ad minim veniam, quis" 
        + " nostrud exercitation ullamco laboris nisi ut aliquip" 
        + " ex ea commodo consequat. Duis aute irure dolor in" 
        + " reprehenderit in voluptate velit esse cillum dolore" 
        + " eu fugiat nulla pariatur. Excepteur sint occaecat" 
        + " cupidatat non proident, sunt in culpa qui officia" 
        + " deserunt mollit anim id est laborum. " + i); 
      data.add(rowData); 
     } 
     Vector<String> columnNames = new Vector<String>(); 
     columnNames.add("Key"); 
     columnNames.add("Value"); 
     dtm.setDataVector(data, columnNames); 
     jTable.setDefaultRenderer(String.class, null); 
     jTable.getColumnModel().getColumn(0).setCellRenderer(
       new TextAreaCellRenderer()); 
     jTable.getColumnModel().getColumn(1).setCellRenderer(
       new TextAreaCellRenderer()); 
    } 

    private void initComponents() { 
     jToolBar = new JToolBar(); 
     jButtonPrint = new JButton(); 
     jScrollPane = new JScrollPane(); 
     jTable = new JTable(); 

     setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); 

     jToolBar.setRollover(true); 

     jButtonPrint.setText("Print"); 
     jButtonPrint.setFocusable(false); 
     jButtonPrint.setHorizontalTextPosition(SwingConstants.CENTER); 
     jButtonPrint.setVerticalTextPosition(SwingConstants.BOTTOM); 
     jButtonPrint.addActionListener(new ActionListener() { 
      public void actionPerformed(ActionEvent evt) { 
       jButtonPrintActionPerformed(evt); 
      } 
     }); 
     jToolBar.add(jButtonPrint); 

     getContentPane().add(jToolBar, BorderLayout.NORTH); 

     jScrollPane.setViewportView(jTable); 

     getContentPane().add(jScrollPane, BorderLayout.CENTER); 
    } 

    private void jButtonPrintActionPerformed(ActionEvent evt)            
    {             
     try { 
      jTable.print(); 
     } catch (PrinterException ex) { 
      ex.printStackTrace(); 
     } 
    }            

    public static class TextAreaCellRenderer extends JTextArea implements 
      TableCellRenderer { 

     public TextAreaCellRenderer() { 
      this.setLineWrap(true); 
      this.setWrapStyleWord(true); 
     } 

     public Component getTableCellRendererComponent(JTable table, 
       Object value, boolean isSelected, boolean hasFocus, 
       int row, int column) { 
      this.setText(String.valueOf(value)); 
      TableColumnModel columnModel = table.getColumnModel(); 
      this.setSize(columnModel.getColumn(column).getWidth(), 1); 
      int newHeight = this.getPreferredSize().height; 
      if (newHeight > table.getRowHeight(row)) { 
       table.setRowHeight(row, this.getPreferredSize().height); 
      } 
      return this; 
     } 
    } 
} 

답변

0

나는 근본 원인과 해결책을 찾았다 고 생각합니다. 인쇄 문제는 테이블의 높이가 잘못 되었기 때문에 발생합니다. 테이블의 행 중 일부가 잘못된 높이이기 때문에 테이블의 높이가 잘못되었습니다. 셀 렌더러가 JTable에 의해 불려 가지 않았기 (즉, getTableCellRendererComponent 메소드가 불려 가지 않았기 때문에) 행의 일부가 잘못된 높이가되었습니다. JTable이 일부 셀 렌더러를 건너 뛰는 이유는 최적화입니다. 즉, 건너 뛴 셀 렌더러 오프 스크린 인 셀을위한 것입니다 - 오프 스크린은 렌더링이 필요하지 않음을 의미합니다. 이 분야에서 JTable의 최적화가 이치에 맞습니다.

그러나 렌더러는 각 행의 정확한 높이가 설정된 프로그램의 유일한 위치입니다. 셀 렌더러가 행의 높이를 알아내는 가장 좋은 위치에 있기 때문에 셀 렌더러의 행 높이를 설정하는 것은 다소 이해할 수 있습니다.

이 예제 프로그램을 수정하는 가장 간단한 방법은 모든 셀 렌더러에서 수동으로 getTableCellRendererComponent을 호출하는 것입니다.이 작업은 렌더러가 모든 단일 행을 설정할 수있는 기회를 제공합니다 테이블에서 정확한 높이로 각 행이 올바른 높이에 있으면 (자), JTable의 오버랩이 올바른 높이가되어, 인쇄 단락의 문제가 해결되고있는 것 같습니다. 다음 코드는 그렇게 모든 렌더러를 방문 보여줍니다 : 모든 셀 렌더링의

for (int colIdx = 0; colIdx < jTable.getColumnCount(); colIdx++) 
{ 
    for (int rowIdx = 0; rowIdx < jTable.getRowCount(); rowIdx++) 
    { 
     TableColumnModel columnModel = jTable.getColumnModel(); 
     TableColumn column = columnModel.getColumn(colIdx); 
     TableCellRenderer renderer = column.getCellRenderer(); 
     Object cellValue = jTable.getValueAt(rowIdx, colIdx); 
     renderer.getTableCellRendererComponent(jTable, cellValue, 
        false, false, rowIdx, colIdx); 
    } 
} 

이 매뉴얼 방문은 화면에 표시되는 셀의 셀 렌더링을 호출하는 JTable가의 최적화를 무시합니다. 따라서 사용자가 인쇄를 요청한 후에 (그러나 JTable의 print 메소드를 호출하기 전에)이 해결 방법 코드 만 실행하려고 할 수 있습니다. 이것에 의해, 유저가 GUI만을 사용하고 있어도 인쇄를하지 않으면, JTable 최적화가 유효하게됩니다. 라운드

for (int colIdx = 0; colIdx < jTable.getColumnCount(); colIdx++) { 
    for (int rowIdx = 0; rowIdx < jTable.getRowCount(); rowIdx++) { 
     TableCellRenderer renderer = jTable.getCellRenderer(rowIdx, colIdx); 
     Object cellValue = jTable.getValueAt(rowIdx, colIdx); 
     renderer.getTableCellRendererComponent(jTable, cellValue, 
       false, false, rowIdx, colIdx); 
    } 
} 
+1

잘못된 방법 : 어떤 방법으로 발신자의 상태를 절대 변경하지 not_ _must 렌더링을 – kleopatra

+0

@kleopatra - 의견에 감사드립니다. 귀하의 의견에 응답하여 내 대답을 업데이트하고 싶습니다. 그러나 규칙의 문서화를 찾으러 갔는데 "렌더러가 호출자의 상태를 변경해서는 안됩니다."그리고 아무 것도 찾을 수 없었습니다. 나는 당신이 틀렸다고 말하는 것이 아닙니다. 단지 그것에 대해 더 읽고 확증을 얻고 싶습니다. 이 계약서의 문서화 된 부분에 대한 아이디어가 있습니까? –

0

나는 약간 나를 위해 작동하도록 마이크 클라크 솔루션을 수정했다. 대신 rowHeight 업데이트를이 게시물에 표시되는 루프로 이동하십시오.