Probleme bei JTable-Drucken

Hallo Erdal,
Ein Beispiel:
PHP:
String[] spaltenNamen = {"Kommissions-\nund Probe\nnummer", "Bezeichnung", "Kennziffer",
   "Zahl der\nProbenahme"};
String data[][] = {{1, "Bzeeich1", 11, 5}, {2, "Bzeeich2", 22, 6}, {3, "Bzeeich3", 33, 7}};
...
      meinTabelle = new JTable(data, spaltenNamen);
      con.add(meinTabelle, BorderLayout.CENTER);
      meinTabelle.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
      meinTabelle.setEnabled(false);
      // Die Spalten nicht verschiebbar erzeugen
      meinTabelle.getTableHeader().setReorderingAllowed(false);
      JScrollPane scroller = new JScrollPane(meinTabelle);
      con.add(scroller, BorderLayout.CENTER);
      con.setVisible(true);
      meinTabelle.updateUI();
...
 
Hallo Athro,

hab eine neue Methode von JTable nämlich getPrintable entdeckt. Damit ist es sehr sehr einfach zu drucken, es nimmt einem die ganze Arbeit ab. Das eigentliche Drucken im unteren Beispiel umfasst grad mal 10 Zeilen von ca. Zeile 55 bis 65. Hab noch zusätzlich ein Druckeinstellungsdialog implementiert. Hab es mit und ohne Kopfzeile und Fußzeile probiert, mal Hochformat mal Querformat. Bin zufrieden mit dem Druckergebnis. Einer der Parameter von getPrintable ist PrintMode. Hier kann man entweder auf Normal setzen oder FitWidth wählen. Dieses FitWidth passt die Tabellenbreite an die Seitenbreite an.


Java:
import java.awt.*;
import java.awt.event.*;
import java.awt.print.PageFormat;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.text.MessageFormat;

import javax.swing.*;
import javax.swing.table.AbstractTableModel;
import javax.swing.text.BadLocationException;
import javax.swing.text.Utilities;

public class TablePrintingExample extends JFrame implements ActionListener {

	private TableModelSimple tms = new TableModelSimple();

	private JTable table = new JTable(tms);

	private JButton btn = new JButton("Print...");

	private PrintDialog pDialog = new PrintDialog();

	private PrinterJob printerJob = PrinterJob.getPrinterJob();

	public TablePrintingExample() {
		super("Table Printing Example");
		this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		this.setLocationByPlatform(true);
		this.setSize(480, 640);
		this.setAlwaysOnTop(true);
		this.addComponentListener(new ComponentAdapter() {
			public void componentResized(ComponentEvent e) {
				tms.wrappTableHeaders();
			}
		});

		table.setAutoResizeMode(JTable.AUTO_RESIZE_OFF);
		btn.addActionListener(this);

		this.add(new JScrollPane(table), BorderLayout.CENTER);
		this.add(btn, BorderLayout.SOUTH);

		this.setVisible(true);

		tms.wrappTableHeaders();

		table.updateUI();
	}

	public static void main(String[] args) {
		new TablePrintingExample();
	}

	public void actionPerformed(ActionEvent e) {
		Object[] o = pDialog.showPrintDialog();

		if (o != null) {
			printerJob.setPrintable(table.getPrintable((JTable.PrintMode) o[0],
					(MessageFormat) o[1], (MessageFormat) o[2]),
					(PageFormat) o[3]);
			try {
				printerJob.print();
			} catch (PrinterException ee) {
				ee.printStackTrace();
			}
		}
	}

	class PrintDialog extends JDialog implements ActionListener {

		Object[] o;

		private JLabel l1 = new JLabel("Orientation:   ");

		private JLabel l2 = new JLabel("Print Mode:   ");

		private JLabel l3 = new JLabel("Extras:   ");

		private JCheckBox c1 = new JCheckBox("Header");

		private JCheckBox c2 = new JCheckBox("Footer");

		private JRadioButton r1 = new JRadioButton("Portrait");

		private JRadioButton r2 = new JRadioButton("Landscape");

		private JRadioButton r3 = new JRadioButton("Normal");

		private JRadioButton r4 = new JRadioButton("Fit Width");

		private JButton b1 = new JButton("Cancel");

		private JButton b2 = new JButton("Print");

		private ButtonGroup bg1 = new ButtonGroup();

		private ButtonGroup bg2 = new ButtonGroup();

		private JTextField t1 = new JTextField(30);

		private JTextField t2 = new JTextField(30);

		public PrintDialog() {
			super(TablePrintingExample.this, "Print Settings", true);
			this.setDefaultCloseOperation(JDialog.DISPOSE_ON_CLOSE);
			this.setLocationByPlatform(true);

			bg1.add(r1);
			bg1.add(r2);
			bg2.add(r3);
			bg2.add(r4);
			r1.setSelected(true);
			r3.setSelected(true);
			c1.setSelected(true);
			c2.setSelected(true);

			b1.addActionListener(this);
			b2.addActionListener(this);
			c1.addActionListener(this);
			c2.addActionListener(this);

			GridBagLayoutManager gMan = new GridBagLayoutManager(this
					.getContentPane());

			gMan.setInsets(10, 10, 0, 10);
			gMan.addComponent(gMan.getLabWSep(l1), 0, 0, 3, 1, 1, 1);
			gMan.setInsets(0, 10, 0, 10);
			gMan.addComponent(r1, 1, 1, 1, 1, 1, 1);
			gMan.addComponent(r2, 2, 1, 1, 1, 1, 1);
			gMan.setInsets(10, 10, 10, 10);
			gMan.addComponent(gMan.getLabWSep(l2), 0, 2, 3, 1, 1, 1);
			gMan.setInsets(0, 10, 0, 10);
			gMan.addComponent(r3, 1, 3, 1, 1, 1, 1);
			gMan.addComponent(r4, 2, 3, 1, 1, 1, 1);
			gMan.setInsets(10, 10, 10, 10);
			gMan.addComponent(gMan.getLabWSep(l3), 0, 4, 3, 1, 1, 1);
			gMan.setInsets(0, 10, 0, 10);
			gMan.addComponent(c1, 0, 5, 1, 1, 1, 1);
			gMan.setInsets(0, 10, 0, 10);
			gMan.addComponent(t1, 0, 6, 3, 1, 1, 1);
			gMan.setInsets(0, 10, 0, 10);
			gMan.addComponent(c2, 0, 7, 1, 1, 1, 1);
			gMan.setInsets(0, 10, 10, 10);
			gMan.addComponent(t2, 0, 8, 3, 1, 1, 1);
			gMan.setInsets(10, 10, 10, 10);
			gMan.addComponent(new JSeparator(JSeparator.HORIZONTAL), 0, 9, 3,
					1, 1, 1);
			gMan.addComponent(b1, 1, 10, 1, 1, 1, 1);
			gMan.addComponent(b2, 2, 10, 1, 1, 1, 1);
			this.pack();
		}

		public Object[] showPrintDialog() {
			this.setVisible(true);
			return o;
		}

		class GridBagLayoutManager {

			private Container cont;

			private GridBagLayout gbl;

			private GridBagConstraints gbc;

			public final int CENTER = GridBagConstraints.CENTER;

			public final int EAST = GridBagConstraints.EAST;

			public final int WEST = GridBagConstraints.WEST;

			public final int NORTH = GridBagConstraints.NORTH;

			public final int SOUTH = GridBagConstraints.SOUTH;

			public final int BOTH = GridBagConstraints.BOTH;

			public final int VERTICAL = GridBagConstraints.VERTICAL;

			public final int HORIZONTAL = GridBagConstraints.HORIZONTAL;

			public final int NONE = GridBagConstraints.NONE;

			public GridBagLayoutManager(Container cont) {
				this.cont = cont;
				gbl = new GridBagLayout();
				gbc = new GridBagConstraints();
				cont.setLayout(gbl);
			}

			public void addComponent(Component c, int x, int y, int width,
					int height, double weightx, double weighty, int fill,
					int anchor) {
				gbc.fill = fill;
				gbc.anchor = anchor;
				gbc.gridx = x;
				gbc.gridy = y;
				gbc.gridwidth = width;
				gbc.gridheight = height;
				gbc.weightx = weightx;
				gbc.weighty = weighty;
				cont.add(c, gbc);
			}

			public void addComponent(Component c, int x, int y, int width,
					int height, double weightx, double weighty) {
				gbc.fill = GridBagConstraints.BOTH;
				gbc.anchor = GridBagConstraints.CENTER;
				gbc.gridx = x;
				gbc.gridy = y;
				gbc.gridwidth = width;
				gbc.gridheight = height;
				gbc.weightx = weightx;
				gbc.weighty = weighty;
				cont.add(c, gbc);
			}

			public void setInsets(int top, int left, int bottom, int right) {
				gbc.insets = new Insets(top, left, bottom, right);
			}

			public JPanel getLabWSep(JLabel l) {
				JPanel p = new JPanel();
				p.setLayout(new GridBagLayout());
				GridBagConstraints c = new GridBagConstraints();
				p.add(l, c);
				c.fill = GridBagConstraints.HORIZONTAL;
				c.weightx = 1;
				c.gridx = 1;
				p.add(new JSeparator(JSeparator.HORIZONTAL), c);
				return p;
			}
		}

		public void actionPerformed(ActionEvent e) {
			if (e.getSource() == b1)
				this.dispose();
			else if (e.getSource() == b2)
				validatePrintSettings();
			else if (e.getSource() == c1)
				t1.setEnabled(c1.isSelected());
			else if (e.getSource() == c2)
				t2.setEnabled(c2.isSelected());
		}

		public void validatePrintSettings() {
			PageFormat pf = new PageFormat();
			MessageFormat header = null;
			MessageFormat footer = null;
			pf.setOrientation(r1.isSelected() ? PageFormat.PORTRAIT
					: PageFormat.LANDSCAPE);
			JTable.PrintMode printMode = r3.isSelected() ? JTable.PrintMode.NORMAL
					: JTable.PrintMode.FIT_WIDTH;
			if (c1.isSelected())
				header = new MessageFormat(t1.getText());
			if (c2.isSelected())
				footer = new MessageFormat(t2.getText());
			o = new Object[] { printMode, header, footer, pf };
			this.dispose();
		}
	}

	class TableModelSimple extends AbstractTableModel {
		private int heightofTableHeader = 0;

		public String getColumnName(int col) {
			String name = "";
			for (int i = 0; i <= col; i++) {

				name = name + (((col % 2) == 0) ? col * col : col);
			}
			return name;
		}

		public int getRowCount() {
			return 40;
		}

		public int getColumnCount() {
			return 8;
		}

		public Object getValueAt(int row, int col) {
			return row + " " + col;
		}

		public void wrappTableHeaders() {
			heightofTableHeader = 0;
			int cols = this.getColumnCount();
			for (int i = 0; i < cols; i++) {
				table.getColumnModel().getColumn(i).setHeaderValue(
						getWrappedText(i));
			}
			table.getTableHeader().setPreferredSize(
					new Dimension(table.getTableHeader().getWidth(),
							heightofTableHeader));
			table.updateUI();
		}

		public String getWrappedText(int columnIndex) {
			JTextArea c = new JTextArea(table.getColumnName(columnIndex));
			c.setPreferredSize(new Dimension(table.getColumnModel().getColumn(
					columnIndex).getWidth(), 100));
			c.setLineWrap(true);
			c.setWrapStyleWord(true);
			c.setFont(table.getFont());
			JWindow win = new JWindow();
			win.add(c);
			win.pack();

			int len = c.getDocument().getLength();
			int offset = 0;
			StringBuffer buf = new StringBuffer((int) (len * 1.30));
			String s = "";
			try {
				while (offset < len) {
					int end = Utilities.getRowEnd(c, offset);
					if (end < 0) {
						break;
					}
					end = Math.min(end + 1, len);
					s = c.getDocument().getText(offset, end - offset);
					buf.append(s);
					if (!s.endsWith("\n")) {
						buf.append('\n');
					}
					offset = end;
				}
			} catch (BadLocationException e) {
				e.printStackTrace();
			}

			s = buf.toString();

			c.setText(s);
			int height = c.getLineCount()
					* table.getFontMetrics(table.getFont()).getHeight();
			if (height > heightofTableHeader)
				heightofTableHeader = height;

			s = s.replaceAll("\n", "<BR>");

			s = "<HTML><P ALIGN=\"CENTER\">" + s + "</P><HTML>";

			try {
				return s;
			} finally {
				buf = null;
				s = null;
				c = null;
				win = null;
			}
		}
	}
}


Vg Erdal
 
Hallo Erdal,
Es tut mir leid dass ich so lange nicht antworten könnte ich, war 2 Wochen nicht da.
in zwischen und zwar beim Debuger konnte festgestellt dass, nach der Methode show(), wer-den die Dimension meiner Tabelle geändert.

ich habe vor der Show() Methode die Dimension gespeichert und in dem Event des Druckens wieder zurückgesetzt.
PHP:
public class MeinTabGui extends JFrame{
...
...
  public void ezeugTabGUI(...){
      meinTabelle = new JTable(data, spaltenNamen);
      con.add(meinTabelle, BorderLayout.CENTER);
      // speichere die Header Demisionen vor dem Scroller
      tabWidth = meinTabelle.getTableHeader().getWidth();
      tabHight = meinTabelle.getTableHeader().getHeight();
      JScrollPane scroller = new JScrollPane(meinTabelle);
      scroller.setViewportView(meinTabelle); 
      con.add(scroller, BorderLayout.CENTER);
      ...
      ...
    });
      jButtDruck.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        // Druck die akteulle Tabelle        
        druckTabelle(meinTabelle);

      }
    });
    //
       meinTabelle.updateUI();
       ...
       ...
      con.validate();
      con.setVisible(true);  
      show();  
    }
  }

  private void druckTabelle(JTable t){
    // Der JScrollPane verwendet standardmäßig den Header des jTableBody.
    // deshalb setzte ich das Tablle-Hedear-Demisionen auf die Werte vor der JScroller-Erzeugung zurück.
    t.getTableHeader().setSize(tabWidth,tabHight);
    druckTabelle.printJTable(t);
  }

ich kann ich jetzt meine Tabelle drucken, aber es werden nur die Tabellezellen ohne den Tabellespaltennamen gedruckt, weist du woran kann es liegen.
weist Du ob Show() was andres ändert?

Danke
Athro
 
Hallo Erdal,
ich konnte dein Beispiel nicht kompilieren, z.B.: ich konnte in der JTable Klasse keine Print-Mode oder PrintMode unterlasse bzw. Interface finden.
außerdem woher kommen die Methoden:
this.setLocationByPlatform(true);
this.setAlwaysOnTop(true);

mfg
Athro
 
Hallo Athro,

Athro hat gesagt.:
Hallo Erdal,
ich konnte dein Beispiel nicht kompilieren, z.B.: ich konnte in der JTable Klasse keine Print-Mode oder PrintMode unterlasse bzw. Interface finden.

Zeile 58-60 steht folgendes:
Code:
printerJob.setPrintable(table.getPrintable((JTable.PrintMode) o[0],
                    (MessageFormat) o[1], (MessageFormat) o[2]),
                    (PageFormat) o[3]);

printerJob.setPrintable(table.getPrintable(JTable.PrintMode.FitWidth, new MessageFormat(),new MessageFormat()),new PageFormat());

printerJob.setPrintable(table.getPrintable(JTable.PrintMode.NORMAL, new MessageFormat(),new MessageFormat()),new PageFormat());

So würde es aussehen wenn du es manuell in dein Code einfügst. Aus meinem Code ist es deswegen nicht ersichtlich, da ich das per Dialog mache.

außerdem woher kommen die Methoden:
this.setLocationByPlatform(true);
this.setAlwaysOnTop(true);

Das sind Methoden von JFrame.


Hab meinen Code nochmals getestet. Funktioniert einwandfrei. Hast du auf deiner Kiste Java 5 drauf? Oder falls du Eclipse oder eine vergleichbare IDE benutzt, ist in den Einstellungen Java 5 eingestellt?


Vg Erdal
 
Zurück