为了解决边距内打印的问题,我尝试缩放表单,以便它们缩小到要打印到的纸张尺寸。
内部扩展VBox
的Printable.java
public void scaleToFit(){
double maxWidth = 497.0;
this.requestLayout();
double width = this.getWidth();
if(width > maxWidth){
double widthFrac = maxWidth / width;
this.setScaleX(widthFrac);
}
System.out.println(this.getWidth());
//edited out same process for height
}
Printable
将保存在 HashMap data.table
中。当我的打印窗口加载时,我为每个窗口运行 scaleToFit
。 main
是一个 ScrollPane。
扩展 VBox 的 ModPrintCycle.java
内部
//inside constructor
main.sceneProperty().addListener(new ChangeListener<Scene>(){
@Override
public void changed(ObservableValue<? extends Scene> observable, Scene oldValue, Scene newValue) {
System.out.println("new Scene");
newValue.windowProperty().addListener(new ChangeListener<Window>(){
public void changed(ObservableValue<? extends Window> arg0, Window arg1, Window arg2) {
System.out.println("new Window");
arg2.setOnShown(new EventHandler<WindowEvent>(){
@Override
public void handle(WindowEvent event) {
Platform.runLater(new Runnable(){
@Override
public void run() {
System.out.println(event.toString());
lookingAt = data.tables.size();
while(lookingAt-1 >= 0 ){
showNext(-1);
}
}
});
}
});
}
});
}
});
就这个例子而言,我还在按钮中添加了 scaleToFit()
,该按钮可在这些 Printable
之间切换。 [编辑:添加了显式显示使用scaleToFit()的脚本]请注意,data.tables
是一个包含Printables的HashMap。
内部ModPrintCycle.java
延续
private void showNext(int move){
boolean k = false;
if(move > 0 && lookingAt+move < data.tables.size()){
k = true;
}
else if(move < 0 && lookingAt+move >=0){
k = true;
}
if(k){
lookingAt+= move;
}
show();
}
private void show(){
if(data.tables.size() > 0){
if(lookingAt >= 0 && lookingAt < data.tables.size()){
//tableOrder is an ArrayList<String> for the arrangement of data.tables
if(tableOrder.size() > 0){
Printable pt = data.tables.get(tableOrder.get(lookingAt));
main.setContent(pt);
pt.scaleToFit();
}
}
else{
if(lookingAt < 0){
lookingAt = 0;
show();
}
else if(lookingAt >= data.tables.size()){
lookingAt = data.tables.size()-1;
show();
}
}
txtStatus.setText((lookingAt+1) + " / " + data.tables.size());
}else{
main.setContent(null);
txtStatus.setText("Empty");
}
}
public void printAll(ArrayList<String> pageList){
//PrinterJob pj is global
//conditions and try declarations
pj = PrinterJob.createPrinterJob(curP);
PageLayout pp = curP.createPageLayout(Paper.LEGAL, PageOrientation.PORTRAIT, MarginType.DEFAULT);
PageLayout pl = curP.createPageLayout(Paper.LEGAL, PageOrientation.LANDSCAPE, MarginType.DEFAULT);
for(String p : pageList){
Printable pt = data.tables.get(p);
pt.scaleToFit();
if(pt.isLandscape()){
pj.printPage(pl,pt);
}
else{
pj.printPage(pp,pt);
}
}
pj.endJob();
// catch statements
}
但是,每当第一次调用 scaleToFit()
时(加载 ModPrintCycle
时),它会告诉我宽度为 0,因此还不会缩放。第二次调用它时(当我第一次在它们之间进行更改时),它仍然是 0。当它最终运行第三次时(当我回头查看 Printable
时),它终于起作用了并且根据需要更改宽度。
由于这些 Printable
需要打印,因此在有人将所有表单浏览两次之前,我无法确保表单已缩放。
如何在加载表单之前强制表单接受其边界?
最佳答案
由于您发布的代码不完全可执行(即不是 MCVE 或 SSCCE),因此无法重现该问题。也很难猜测原因。但我明白你的目的,所以我建议不要手动缩放它,而是让可打印通过监听器自动缩放:
@Override
public void start( Stage stage )
{
ScrollPane scrollPane = new ScrollPane( new Printable( new Label( "looong loooong loooooong looooong loooong text" ) ) );
stage.setScene( new Scene( scrollPane ) );
stage.show();
}
class Printable extends VBox
{
public Printable( Node... children )
{
super( children );
Printable me = this;
this.widthProperty().addListener( new ChangeListener<Number>()
{
@Override
public void changed( ObservableValue<? extends Number> observable, Number oldValue, Number newValue )
{
double maxWidth = 100.0;
double width = newValue.doubleValue();
if ( width > maxWidth )
{
double widthFrac = maxWidth / width;
me.setScaleX( widthFrac );
}
}
} );
}
}
关于Javafx - 在看到之前界限为零,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33122689/