2011-02-04 7 views
5

JTextArea'yı TableCellRenderer olarak kullanan bir JTable'ım var, böylece tablo hücreleri sözcük sarfını kullanabilir. JTable iyi görüntüler. Tabloyu JTable'ın print method aracılığıyla bir yazıcıya yazdırdığımda, çıktı her zaman verilerin yaklaşık% 60'ında kesilir. Farklı bilgisayarları ve farklı yazıcıları ve farklı yazıcı sürücülerini, farklı JVM sürümlerini (1.5, 1.6) denedim, ancak bunların hiçbiri yardımcı olmadı. Aşağıda, sorunu yeniden üreten bağımsız bir Java ana sınıfı bulunmaktadır. Herhangi bir fikir?Kesik JTable baskı çıktısı

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; 
     } 
    } 
} 

cevap

0

Kök nedenini ve çözümü bulduğumu düşünüyorum. Yazdırma problemi, tablonun yanlış yükseklik olması gerçeğinden kaynaklanmaktadır. Tablo yanlış yüksekliktir, çünkü bazı tabloların satırları yanlış yüksekliktedir. Satırların bazıları yanlış yüksekliktir, çünkü hücre oluşturucuları JTable tarafından çağrılmamıştır (yani, getTableCellRendererComponent yöntemi çağrılmamıştır.) JTable, hücre oluşturucuların bazılarının atlanmasının nedeni optimizasyondur - hücre oluşturucuları atlar ekran dışı olan hücreler içindir - ekran dışı görüntü oluşturma gerekli değildir; JTable'ın bu alanda optimizasyonu mantıklı. Ancak, oluşturucular, her bir satırın doğru yüksekliğinin ayarlandığı programdaki tek yerdir. Hücre oluşturucuda satır yüksekliğini ayarlama seçeneğim biraz anlaşılabilir çünkü hücre oluşturucu, satırın hangi yükseklikte olması gerektiğini bilmek için en iyi konumda.

Bu örnek programın düzeltilmesinin en basit yolu, her hücre oluşturucuda getTableCellRendererComponent numaralı numarayı el ile aramaktır (bu, tablonun model verilerini değiştirdikten sonra yapılmalıdır.) Bu, işleyicilere her bir satırı ayarlama fırsatı verir. Tabloda doğru bireysel yüksekliğe kadar. Her satırın doğru yüksekliğinde, JTable toplamı, yazdırma kesilme sorununu çözecek gibi görünen doğru yükseklik olarak biter. Aşağıdaki kod sadece bunu yapmak için bütün oluşturucuların ziyaret gösterir: Bütün hücre render

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); 
    } 
} 

Bu kılavuz ziyareti sadece ekrandaki hücrelerinin hücre oluşturuculara çağırmanın jtable en optimizasyonunu atlar. Bu nedenle, yalnızca kullanıcı yazdırma isteğinde bulunduktan sonra (ancak JTable'da yazdırma yöntemini çağırmadan önce) bu geçici çözüm kodunu çalıştırmak isteyebilirsiniz. Bu, kullanıcı yalnızca GUI kullanıyor ve yazdırmıyorsa, JTable optimizasyonunun etkin kalmasını sağlar. yuvarlak

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

yanlış şekilde: hiçbir şekilde arayanın durumunu asla değiştirmek not_ _must oluşturucusunu – kleopatra

+0

@kleopatra - geri bildiriminiz için teşekkür ederiz. Cevabınızı yorumunuza cevaben güncellemek istiyorum. Ancak, "işlenenin arayanın durumunu değiştirmemesi gereken" kuralın belgelerini aramaya gittim ve hiçbir şey bulamadım. Yanlış olduğunu söylemiyorum - sadece bu konuda daha fazla okumak istiyorum ve belki de doğrulama almak istiyorum. Bu sözleşmenin belgelendiği herhangi bir fikir var mı? –

0

Biraz benim için çalışmasını sağlamak için Mike Clarks çözüm değiştirebilir zorunda kaldı. Bunun yerine, rowHeight güncellemesini bu gönderide gösterdiğiniz döngüye taşıyın.