フォームの枠に文字を入れるで作った郵便番号プログラムに印字位置の微調整機能を取り付けます。印刷物により、またプリンターの特性から多少ずれてしまうという時に、プログラム側で手動でずらして合わせようというものです。
ここで使う予定なのは、JSpinnerです。
| -0.2 | ▲ |
| ▼ |
その前に、印刷プレビューに従ってプレビューの機能を付け、g2.drawString(...で直接書いていた印字を、AjustStringクラスを用いた印字へ書き換えます。
先に印字結果を示します。

旧タイプの印字は黒字で、AjustStringクラスを用いた印字は青で両方重ねています。黒、青片方ずつの図も作りました。このページのボタン操作で片方ずつの印字結果を見ることができます。
旧タイプは、ずれがあるように見えます。四角の枠の左側に文字を配置した後、一律に2.0mmだけ右に寄せていました。ところが、枠の幅が左の3つは6.4mm、右の4つは5.8mmなので、小さい枠では枠の右側に寄ってしまうのです。
AjustStringでは一文字ずつにして枠の幅を指定し、センタリングで書いているので、全部の文字が枠の中心に収まっています。
赤枠も書くようにしました。ピッタリと入る様子をスクリーンショットだけで示したかったことが大きいですが、郵便番号の枠のない用紙に印刷する場合も考慮に入れています。もっとも郵便局の読み取りでは赤枠はなくても良い(機械は赤をドロップして黒だけ読む)ので、文字を手書きしないならいらないのですが。
AjustStringの使い勝手の良さを実感していただくため、黒字も残してあります。
package print01;
import java.awt.*;
import java.awt.print.*;
import java.awt.geom.Line2D;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintJobAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintJobAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.OrientationRequested;
import javax.swing.*;
import static java.awt.Font.*;
import static java.awt.RenderingHints.*;
public class ZipBidou extends JPanel implements Printable {
double pcardlongside = 148d*72/25.4; //
double pcardshortside = 100d*72/25.4; // w=283.46457 h=419.52756
double pwidth = pcardshortside; //用紙の横幅。用紙を変更する時はここ
double pheight = pcardlongside; //用紙の縦幅
double wZh = pwidth/pheight; //横÷縦
Dimension prevsize; //previewSize preferredSizeで使用
double scale; //Graphics2D#.scale()に使用
public ZipBidou(){
setBackground(Color.white);
prevsize = new Dimension(); //(int)pwidth,(int)pheight);
prevsize.setSize(pwidth*2,pheight); //newではintしか認められないがsetはdoubleも許容される
setPreferredSize(prevsize); //これは初期値 (new Dimension(595,841)におなじ)
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int viewpw = getParent().getWidth();
int viewph = getParent().getHeight();
JScrollPane sp = (JScrollPane) getParent().getParent();
int hbarh = sp.getHorizontalScrollBar().getHeight();
int vbarw = sp.getVerticalScrollBar().getWidth();
boolean hbarAri = sp.getHorizontalScrollBar().isVisible();
boolean vbarAri = sp.getVerticalScrollBar().isVisible();
if (vbarAri) viewpw += vbarw;
if (hbarAri) viewph += hbarh;
if((double)(viewpw-vbarw)/viewph > wZh){
prevsize.setSize(viewpw-vbarw, (viewpw-vbarw)/wZh);
scale = (viewpw-vbarw)/pwidth;
}else if( wZh > (double)viewpw / (viewph-hbarh) ){
prevsize.setSize((viewph-hbarh)*wZh, viewph-hbarh);
scale = (viewph-hbarh)/pheight;
}else{
if ( (double)viewpw/viewph > wZh ) {
prevsize.setSize(viewph*wZh, viewph);
scale = viewph/pheight;
}else{
prevsize.setSize(viewpw, viewpw/wZh);
scale = viewpw/pwidth;
}
}
setPreferredSize(prevsize);
//System.out.println(scale); //test
g2.scale(scale,scale);
drawPage(g2);
}
@Override
public int print(Graphics g, PageFormat pf, int pageIndex) {
if (pageIndex != 0) return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) g;
drawPage(g2);
return PAGE_EXISTS;
}
public void drawPage(Graphics2D g2){
g2.setRenderingHint(KEY_ANTIALIASING,VALUE_ANTIALIAS_ON);
g2.setRenderingHint(KEY_TEXT_ANTIALIASING,VALUE_TEXT_ANTIALIAS_ON);
float hbas1 = 44.0f;
float hbas2 = 66.0f;
float hptch1 = 13.9f/2;
float hptch2 = 20.5f/3;
float hwbox1 = 6.4f;
float hwbox2 = 5.8f;
float vbas = 20.3f;
float vwrec = 8.3f;
float mm2pt = 72/25.4f;
String zip = "2345678";
g2.setFont(new Font(SANS_SERIF, PLAIN, 16));
//g2.setFont(new Font("SansSerif", Font.PLAIN, 16));
AjustString kp;
BasicStroke finestroke = new BasicStroke(0.4f);
Linemm line = new Linemm(); //drawline with new class
g2.setPaint(Color.black);
float vbk = 1.5f; //vbasそのままだと下線に接するのでもどす値(mm)
float hfw = 2.0f; //vbasそのままだと左線に接するので進める値(mm)
//今までの文字
for(int i=0; 3>i; i++){
g2.drawString(zip.substring(i,i+1),(hbas1+hfw+hptch1*i)*mm2pt,(vbas-vbk)*mm2pt);
}
for(int i=0; 4>i; i++){
g2.drawString(zip.substring(i+3,i+4),(hbas2+hfw+hptch2*i)*mm2pt,(vbas-vbk)*mm2pt);
}
//AjustStringを使った文字(blue)
g2.setPaint(Color.blue);
for(int i=0; 3>i; i++){
kp = new AjustString(g2,zip.substring(i,i+1),hwbox1);
kp.drawCenter(hbas1+hptch1*i,vbas-vbk);
}
for(int i=0; 4>i; i++){
kp = new AjustString(g2,zip.substring(i+3,i+4),hwbox2);
kp.drawCenter(hbas2+hptch2*i,vbas-vbk);
}
//枠(red)
g2.setPaint(Color.red);
g2.setStroke(finestroke);
for(int i=0; 3>i; i++){
line.setLR(hbas1+hptch1*i,hbas1+hwbox1+hptch1*i);
line.setY(vbas-vwrec);
g2.draw(line); //Rectangle TOP
line.setY(vbas);
g2.draw(line); //Rectangle bottom
line.setTB(vbas-vwrec,vbas);
line.setX(hbas1+hptch1*i);
g2.draw(line); //Rectangle left
line.setX(hbas1+hwbox1+hptch1*i);
g2.draw(line); //Rectangle right
}
for(int i=0; 4>i; i++){
line.setLR(hbas2+hptch2*i,hbas2+hwbox2+hptch2*i);
line.setY(vbas-vwrec);
g2.draw(line); //Rectangle TOP
line.setY(vbas);
g2.draw(line); //Rectangle bottom
line.setTB(vbas-vwrec,vbas);
line.setX(hbas2+hptch2*i);
g2.draw(line); //Rectangle left
line.setX(hbas2+hwbox2+hptch2*i);
g2.draw(line); //Rectangle right
}
g2.setPaint(Color.black);
}
public static void main(String[] args) {
PrinterJob pj = PrinterJob.getPrinterJob();
PrintRequestAttributeSet reqset = new HashPrintRequestAttributeSet();
//MediaSizeName medname = MediaSizeName.ISO_A4;
MediaSizeName medname = MediaSizeName.JAPANESE_POSTCARD;
reqset.add(medname);
MediaSize medsize = MediaSize.getMediaSizeForName(medname);
float medwidth = medsize.getX(MediaPrintableArea.MM);
float medheight = medsize.getY(MediaPrintableArea.MM);
//System.out.println("w="+medwidth + " h="+medheight);//test
//System.out.println("w="+medwidth*72/25.4f + " h="+medheight*72/25.4f);//test
float topmm = 5.5f; //landscape前のTOP
float bottomm = 7.7f;
float leftmm = 6.6f;
float rightmm = 5.5f;
reqset.add(new MediaPrintableArea(
leftmm, topmm,
(medwidth - leftmm - rightmm),
(medheight - topmm - bottomm), MediaPrintableArea.MM));
//reqset.add(OrientationRequested.REVERSE_LANDSCAPE);
//reqset.add(OrientationRequested.LANDSCAPE);
reqset.add(OrientationRequested.PORTRAIT);
ZipBidou zipbidou = new ZipBidou();
JScrollPane scrollPane = new JScrollPane(zipbidou);
String[] goOrNot = {"印刷","中止"};
JOptionPane pane = new JOptionPane(
scrollPane,
JOptionPane.PLAIN_MESSAGE,
JOptionPane.DEFAULT_OPTION,
null,goOrNot,goOrNot[0]
);
//JDialog dialog = pane.createDialog( null, "印刷プレビュー" );
JDialog dialog = pane.createDialog("印刷プレビュー" );
dialog.pack();
dialog.setResizable(true);
dialog.setVisible(true);
String svalue = (String)pane.getValue();
if (svalue==null || !svalue.equals("印刷")) System.exit(0);
pj.setPrintable(zipbidou); //printable instance
if (pj.printDialog( reqset )) {
boolean debug = true;
if(debug){
Attribute[] attrs = reqset.toArray(); //test
for(int n=0 ; attrs.length > n ; n++){ //test
System.out.println( attrs[n].getName()+":"+ attrs[n].toString()+";; ");
}
}
try { pj.print( reqset ); }
catch (PrinterException e) {
System.err.println(e);
}
}
}
}
java.awt.Graphics2D のメソッドである translate(double tx, double ty)を使います。
g2.translate(2,0);と設定しておけば、描画にx,yと指定したものが、x+2,y に指定したことになります。
すでに、印刷プレビューで scale(double sx, double sy) を紹介しています。こちらは、g2.scale(sx,sy) と設定しておけば、描画にx,yで指定したものが、sx*x,sy*y に指定したことになります。
これらは AffineTransform と呼ばれるもので、ユーザー空間の座標をデバイスに依存する座標に変換する方法を定義するものと説明されています。
一般的なx,y,zの座標変換のうちx,yの部分だけを取り出したものになります。
API仕様によると、
[ x'] [ m00 m01 m02 ] [ x ] [ m00x + m01y + m02 ]
[ y'] = [ m10 m11 m12 ] [ y ] = [ m10x + m11y + m12 ]
[ 1 ] [ 0 0 1 ] [ 1 ] [ 1 ]
と一般化されています。
translateは
public abstract void translate(double tx, double ty)
[ 1 0 tx ]
[ 0 1 ty ]
[ 0 0 1 ]
scaleは
public abstract void scale(double sx, double sy)
[ sx 0 0 ]
[ 0 sy 0 ]
[ 0 0 1 ]
回転もあります。thetaはラジアンです。
public abstract void rotate(double theta)
[ cos(theta) -sin(theta) 0 ]
[ sin(theta) cos(theta) 0 ]
[ 0 0 1 ]
1. new SpinnerNumberModel で数値を扱うSpinnerModelを作成します。
2. それを引数にSpinnerのインスタンスを作ります。hspinner,spinner
3. コラム幅を5文字分にします。
4. 上、右のラベルと一緒にSpinner用のパネルに貼ります。
5. 2つのSpinnerインスタンスを引数にZipBidouのインスタンスを作ります。
6. それをscrollPaneに入れます。
7. さらにpreviewSpinnerPanelを作って、scrollPaneとSpinner用のパネルを入れ
8. JOptionPaneに設置してダイアログを作ります。
SpinnerModel vmodel = new SpinnerNumberModel(0.0d, -10.0d, +10.0d, 0.10d);
SpinnerModel hmodel = new SpinnerNumberModel(0.0d, -10.0d, +10.0d, 0.10d);
JSpinner vspinner = new JSpinner(vmodel);
JSpinner hspinner = new JSpinner(hmodel);
((JSpinner.DefaultEditor)(vspinner.getEditor())).getTextField().setColumns(5);
((JSpinner.DefaultEditor)(hspinner.getEditor())).getTextField().setColumns(5);
//印刷位置の微調整(±10mmまで)
JLabel vlabel = new JLabel("上へ(mm)");
JLabel hlabel = new JLabel(" 右へ(mm)");
JPanel spnnpanel = new JPanel();
spnnpanel.add(vlabel);
spnnpanel.add(vspinner);
spnnpanel.add(hlabel);
spnnpanel.add(hspinner);
ZipBidou zipbidou = new ZipBidou(hspinner,vspinner);
JScrollPane scrollPane = new JScrollPane(zipbidou);
JPanel previewSpinnerPanel = new JPanel(new BorderLayout());
previewSpinnerPanel.add(scrollPane,BorderLayout.CENTER);
previewSpinnerPanel.add(spnnpanel,BorderLayout.SOUTH);
String[] goOrNot = {"印刷","中止"};
JOptionPane pane = new JOptionPane(
previewSpinnerPanel, //p
JOptionPane.PLAIN_MESSAGE,
JOptionPane.DEFAULT_OPTION,
null,goOrNot,goOrNot[0]
);
コラム幅を5文字分にするというところがトリッキーです。これをしないとマイナスが出た時に小数以下が隠れたりします。
vspinner.getEditor()でJComponentが得られます。
しかし、実はこれはJComponentを継承したJSpinner.NumberEditorなのです。
JSpinner.NumberEditorの親のJSpinner.DefaultEditorにキャストします。
JSpinner.DefaultEditorのTextFieldをDefaultEditor#getTextField()で得ます。
JSpinner.NumberEditorにキャストしても良かったのですが、getTextField()メソッドがDefaultEditorのメソッドだからです。
得られたTextField()を.setColumns(5)で5カラムの幅にします。
ここまでで、
import javax.swing.JSpinner; import javax.swing.SpinnerModel; import javax.swing.SpinnerNumberModel;
が必要ですが、import javax.swing.*; をしてしまったので、なくても構いません。
javax.swing.JSpinner.NumberEditorまでの継承関係です。
java.lang.Object
java.awt.Component
java.awt.Container
javax.swing.JComponent
javax.swing.JPanel
javax.swing.JSpinner.DefaultEditor
javax.swing.JSpinner.NumberEditor
Spinnerへの操作をZipBidouのインスタンスが感知できるようにします。
操作によってプレビューが変化しますが、これは必ずしも必要ではありません。
Spinner変更の感知はChangeListenerで行います。implementsして、addChangeListener(this)します。
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
public class ZipBidou extends JPanel implements Printable,ChangeListener {
double pcardlongside = 148d*72/25.4; //
double pcardshortside = 100d*72/25.4; // w=283.46457 h=419.52756
....
JSpinner vspinner,hspinner;
public ZipBidou(JSpinner hspinner, JSpinner vspinner){
this.hspinner = hspinner;
this.vspinner = vspinner;
hspinner.addChangeListener(this);
vspinner.addChangeListener(this);
setBackground(Color.white);
prevsize = new Dimension(); //(int)pwidth,(int)pheight);
prevsize.setSize(pwidth,pheight); //newではintしか認められないがsetはdoubleも許容される
setPreferredSize(prevsize); //これは初期値 (new Dimension(595,841)におなじ)
//this.getParent().setPreferredSize(prevsize);
}
implementsしたら、stateChanged(ChangeEvent e)メソッドを用意する必要があります。
@Override
public void stateChanged(ChangeEvent e){
repaint();
}
だけです。
JSpinner#getValue()の値はObjectとなっているが、SpinnerNumberModelの場合はdouble
ここでtranslateの値として使用する。y方向については▲で上に移動させるために「上へ」として、正負を逆にしている。
public void drawPage(Graphics2D g2){
g2.setRenderingHint(KEY_ANTIALIASING,VALUE_ANTIALIAS_ON);
g2.setRenderingHint(KEY_TEXT_ANTIALIASING,VALUE_TEXT_ANTIALIAS_ON);
double trdx = (double)hspinner.getValue();
double trdy = (double)vspinner.getValue();
float mm2pt = 72/25.4f;
g2.translate(trdx*mm2pt,-trdy*mm2pt);
float hbas1 = 44.0f;
float hbas2 = 66.0f;

実用には枠はない方がよい場合が多いでしょう。プレビューの見栄えのために残してあります。
package print01;
import java.awt.*;
import java.awt.print.*;
import java.awt.geom.Line2D;
import javax.print.attribute.Attribute;
import javax.print.attribute.HashPrintJobAttributeSet;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintJobAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSize;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.MediaPrintableArea;
import javax.print.attribute.standard.MediaTray;
import javax.print.attribute.standard.OrientationRequested;
import javax.swing.*;
import static java.awt.Font.*;
import static java.awt.RenderingHints.*;
import javax.swing.event.ChangeListener;
import javax.swing.event.ChangeEvent;
public class ZipBidou extends JPanel implements Printable,ChangeListener {
double pcardlongside = 148d*72/25.4; //
double pcardshortside = 100d*72/25.4; // w=283.46457 h=419.52756
double pwidth = pcardshortside; //用紙の横幅。用紙を変更する時はここ
double pheight = pcardlongside; //用紙の縦幅
double wZh = pwidth/pheight; //横÷縦
Dimension prevsize; //previewSize preferredSizeで使用
double scale; //Graphics2D#.scale()に使用
JSpinner vspinner,hspinner;
public ZipBidou(JSpinner hspinner, JSpinner vspinner){
this.hspinner = hspinner;
this.vspinner = vspinner;
hspinner.addChangeListener(this);
vspinner.addChangeListener(this);
setBackground(Color.white);
prevsize = new Dimension(); //(int)pwidth,(int)pheight);
prevsize.setSize(pwidth,pheight); //newではintしか認められないがsetはdoubleも許容される
setPreferredSize(prevsize); //これは初期値
//this.getParent().setPreferredSize(prevsize);
}
@Override
public void stateChanged(ChangeEvent e){
repaint();
}
@Override
public void paintComponent(Graphics g){
super.paintComponent(g);
Graphics2D g2 = (Graphics2D) g;
int viewpw = getParent().getWidth();
int viewph = getParent().getHeight();
JScrollPane sp = (JScrollPane) getParent().getParent();
int hbarh = sp.getHorizontalScrollBar().getHeight();
int vbarw = sp.getVerticalScrollBar().getWidth();
boolean hbarAri = sp.getHorizontalScrollBar().isVisible();
boolean vbarAri = sp.getVerticalScrollBar().isVisible();
if (vbarAri) viewpw += vbarw;
if (hbarAri) viewph += hbarh;
if((double)(viewpw-vbarw)/viewph > wZh){
prevsize.setSize(viewpw-vbarw, (viewpw-vbarw)/wZh);
scale = (viewpw-vbarw)/pwidth;
}else if( wZh > (double)viewpw / (viewph-hbarh) ){
prevsize.setSize((viewph-hbarh)*wZh, viewph-hbarh);
scale = (viewph-hbarh)/pheight;
}else{
if ( (double)viewpw/viewph > wZh ) {
prevsize.setSize(viewph*wZh, viewph);
scale = viewph/pheight;
}else{
prevsize.setSize(viewpw, viewpw/wZh);
scale = viewpw/pwidth;
}
}
setPreferredSize(prevsize);
//System.out.println(scale); //test
g2.scale(scale,scale);
drawPage(g2);
}
@Override
public int print(Graphics g, PageFormat pf, int pageIndex) {
if (pageIndex != 0) return NO_SUCH_PAGE;
Graphics2D g2 = (Graphics2D) g;
drawPage(g2);
return PAGE_EXISTS;
}
public void drawPage(Graphics2D g2){
g2.setRenderingHint(KEY_ANTIALIASING,VALUE_ANTIALIAS_ON);
g2.setRenderingHint(KEY_TEXT_ANTIALIASING,VALUE_TEXT_ANTIALIAS_ON);
double trdx = (double)hspinner.getValue();
double trdy = (double)vspinner.getValue();
float mm2pt = 72/25.4f;
g2.translate(trdx*mm2pt,-trdy*mm2pt);
float hbas1 = 44.0f;
float hbas2 = 66.0f;
float hptch1 = 13.9f/2;
float hptch2 = 20.5f/3;
float hwbox1 = 6.4f;
float hwbox2 = 5.8f;
float vbas = 20.3f;
float vwrec = 8.3f;
String zip = "2345678";
g2.setFont(new Font(SANS_SERIF, PLAIN, 16));
AjustString kp;
BasicStroke finestroke = new BasicStroke(0.4f);
Linemm line = new Linemm(); //drawline with new class
g2.setPaint(Color.black);
float vbk = 1.5f; //vbasそのままだと下線に接するのでもどす値(mm)
//g2.setPaint(Color.blue);
for(int i=0; 3>i; i++){
kp = new AjustString(g2,zip.substring(i,i+1),hwbox1);
kp.drawCenter(hbas1+hptch1*i,vbas-vbk);
}
for(int i=0; 4>i; i++){
kp = new AjustString(g2,zip.substring(i+3,i+4),hwbox2);
kp.drawCenter(hbas2+hptch2*i,vbas-vbk);
}
//枠(red)
g2.setPaint(Color.red);
g2.setStroke(finestroke);
for(int i=0; 3>i; i++){
line.setLR(hbas1+hptch1*i,hbas1+hwbox1+hptch1*i);
line.setY(vbas-vwrec);
g2.draw(line); //Rectangle TOP
line.setY(vbas);
g2.draw(line); //Rectangle bottom
line.setTB(vbas-vwrec,vbas);
line.setX(hbas1+hptch1*i);
g2.draw(line); //Rectangle left
line.setX(hbas1+hwbox1+hptch1*i);
g2.draw(line); //Rectangle right
}
for(int i=0; 4>i; i++){
line.setLR(hbas2+hptch2*i,hbas2+hwbox2+hptch2*i);
line.setY(vbas-vwrec);
g2.draw(line); //Rectangle TOP
line.setY(vbas);
g2.draw(line); //Rectangle bottom
line.setTB(vbas-vwrec,vbas);
line.setX(hbas2+hptch2*i);
g2.draw(line); //Rectangle left
line.setX(hbas2+hwbox2+hptch2*i);
g2.draw(line); //Rectangle right
}
g2.setPaint(Color.black);
//枠はここまで
}
public static void main(String[] args) {
PrinterJob pj = PrinterJob.getPrinterJob();
PrintRequestAttributeSet reqset = new HashPrintRequestAttributeSet();
//MediaSizeName medname = MediaSizeName.ISO_A4;
MediaSizeName medname = MediaSizeName.JAPANESE_POSTCARD;
reqset.add(medname);
MediaSize medsize = MediaSize.getMediaSizeForName(medname);
float medwidth = medsize.getX(MediaPrintableArea.MM);
float medheight = medsize.getY(MediaPrintableArea.MM);
float topmm = 5.5f; //landscape前のTOP
float bottomm = 7.7f;
float leftmm = 6.6f;
float rightmm = 5.5f;
reqset.add(new MediaPrintableArea(
leftmm, topmm,
(medwidth - leftmm - rightmm),
(medheight - topmm - bottomm), MediaPrintableArea.MM));
//reqset.add(OrientationRequested.REVERSE_LANDSCAPE);
//reqset.add(OrientationRequested.LANDSCAPE);
reqset.add(OrientationRequested.PORTRAIT);
SpinnerModel vmodel = new SpinnerNumberModel(0.0d, -10.0d, +10.0d, 0.10d);
SpinnerModel hmodel = new SpinnerNumberModel(0.0d, -10.0d, +10.0d, 0.10d);
JSpinner vspinner = new JSpinner(vmodel);
JSpinner hspinner = new JSpinner(hmodel);
((JSpinner.DefaultEditor)(vspinner.getEditor())).getTextField().setColumns(5);
((JSpinner.DefaultEditor)(hspinner.getEditor())).getTextField().setColumns(5);
JLabel vlabel = new JLabel("上へ(mm)");
JLabel hlabel = new JLabel(" 右へ(mm)");
JPanel spnnpanel = new JPanel();
spnnpanel.add(vlabel);
spnnpanel.add(vspinner);
spnnpanel.add(hlabel);
spnnpanel.add(hspinner);
ZipBidou zipbidou = new ZipBidou(hspinner,vspinner);
JScrollPane scrollPane = new JScrollPane(zipbidou);
JPanel previewSpinnerPanel = new JPanel(new BorderLayout()); //p
previewSpinnerPanel.add(scrollPane,BorderLayout.CENTER); //p
previewSpinnerPanel.add(spnnpanel,BorderLayout.SOUTH); //p
String[] goOrNot = {"印刷","中止"};
JOptionPane pane = new JOptionPane(
//b notborderbox,
previewSpinnerPanel, //p
JOptionPane.PLAIN_MESSAGE,
JOptionPane.DEFAULT_OPTION,
null,goOrNot,goOrNot[0]
);
//JDialog dialog = pane.createDialog( null, "印刷プレビュー" );
JDialog dialog = pane.createDialog("印刷プレビュー" );
dialog.pack();
dialog.setResizable(true);
dialog.setVisible(true);
String svalue = (String)pane.getValue();
do{
if (svalue!=null && svalue.equals("印刷")) {
pj.setPrintable(zipbidou); //printable instance
if (pj.printDialog( reqset )) {
boolean debug = true;
try { pj.print( reqset ); }
catch (PrinterException e) {
System.err.println(e);
}
}
dialog.setVisible(true);
svalue = (String)pane.getValue();
}
}while(svalue!=null && !svalue.equals("中止"));
System.exit(0);
}
}
印刷後、Javaが終了しないというミスがありました。do以下を書き換えました。印刷後位置を調整して再印刷できます。ただし、枠も一緒に動きます。実用では枠は描画しないので問題ありません。(2017-08-30)