Javafx - 在看到之前边界为零
Javafx - Bounds are zero until seen
为了解决边距内打印的问题,我正在尝试缩放我的表单,以便它们缩小到要打印到的纸张大小。
在延伸 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
中。当我的打印 window 加载时,我为每个打印 运行 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);
}
}
});
}
});
}
});
}
});
只是为了这个例子,我还在 Printable
之间变化的按钮中添加了 scaleToFit()
。 [编辑:添加了明确显示使用 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 );
}
}
} );
}
}
为了解决边距内打印的问题,我正在尝试缩放我的表单,以便它们缩小到要打印到的纸张大小。
在延伸 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
中。当我的打印 window 加载时,我为每个打印 运行 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);
}
}
});
}
});
}
});
}
});
只是为了这个例子,我还在 Printable
之间变化的按钮中添加了 scaleToFit()
。 [编辑:添加了明确显示使用 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 );
}
}
} );
}
}