Tenho um problema estranho com o posicionamento ImageView
de s em a Scene
no JavaFX.
Quero que três imagens do mesmo tamanho (200 x 200) apareçam uma ao lado da outra na mesma altura. Então, especifico o mesmo valor em setTranslateY()
para cada imagem. Mas, por algum motivo, elas aparecem em alturas diferentes: Cada imagem seguinte parece 200 pixels mais baixa que a anterior.
Aqui está o código:
public class Main extends Application {
@Override
public void start(Stage myStage) throws IOException {
myStage.setTitle("title");
myStage.setScene(getScene());
stage = myStage;
myStage.show();
}
public static void main(String[] args) {
launch();
}
private Scene getScene() {
List<Node> nodes = new ArrayList<>();
Image i1 = loadFromPath("... some path");
Image i2 = loadFromPath("... some other path");
Image i3 = loadFromPath("... again some other path");
ImageView v1 = new ImageView(i1);
ImageView v2 = new ImageView(i2);
ImageView v3 = new ImageView(i3);
v1.setTranslateX(100);
v1.setTranslateY(100);
v2.setTranslateX(320);
v2.setTranslateY(100);
v3.setTranslateX(540);
v3.setTranslateY(100);
nodes.add(v1);
nodes.add(v2);
nodes.add(v3);
VBox box = new VBox(nodes.toArray(new Node[0]));
box.setMinWidth(800);
box.setMaxWidth(800);
box.setMinHeight(400);
box.setMaxHeight(400);
return new Scene(box);
}
private Image loadFromPath(String path) {
FileInputStream input = null;
try {
input = new FileInputStream(path);
} catch (FileNotFoundException e) {
throw new RuntimeException(e);
}
return new Image(input);
}
}
O resultado fica assim:
Quando uso setLayoutX()
and setLayoutY()
em vez de setTranslateX()
and setTranslateY()
, o resultado é ainda pior:
Alguém pode explicar esse resultado?
Painéis de layout, como
VBox
, dispõem os componentes para você de acordo com um algoritmo que é específico para o painel de layout particular que você está usando. Eles fazem isso definindo as propriedadeslayoutX
elayoutY
dos nós filhos.Em particular, uma
VBox
("caixa vertical") disporá os nós filhos em uma coluna vertical: veja a documentação .Então, se você usar um painel de layout, definir o
layoutX
andlayoutY
dos nós filhos não terá efeito, pois eles serão alterados posteriormente pelo painel de layout quando ele executar seu layout. Isso explica o resultado que você obtém na segunda captura de tela: as imagens estão na posição determinada pelo algoritmo de layout doVBox
. A primeira imagem está no canto superior esquerdo da caixa, e a segunda imagem está diretamente abaixo dela. Se você remover todas as chamadas parasetLayoutX(...)
andsetLayoutY(...)
, bem como chamadas parasetTranslateX(...)
and ,setTranslateY(...)
verá exatamente os mesmos resultados. As posições mostradas na segunda captura de tela são efetivamente as posições padrão para o layout definido por umVBox
.Transformações, como traduções gerenciadas pela configuração das
translateX
propriedades etranslateY
, são aplicadas depois que o painel de layout executa seu layout. Então, na primeira captura de tela, a primeira imagem está 100 pixels à direita e 100 pixels abaixo, a posição em queVBox
a colocou (o canto superior esquerdo). A segunda imagem está 320 pixels à direita e 100 pixels abaixo da posição em queVBox
a colocou (a posição em que aparece na segunda imagem). Em outras palavras, as traduções são relativas às posições definidas pelo layout noVBox
.Pelas coordenadas que você está definindo, parece que você quer que as imagens sejam colocadas horizontalmente uma ao lado da outra; para conseguir isso, basta usar a
HBox
em vez de aVBox
(como sugerido em um comentário ).Você pode usar preenchimento para colocar espaço adicional ao redor do conteúdo da caixa, se necessário:
e espaçamento para colocar um espaço entre cada imagem:
Se você realmente quiser colocar tudo manualmente (o que não é recomendado), use um contêiner que não execute nenhum layout (por exemplo, um
Pane
) em vez doVBox
, e defina as propriedadeslayoutX
andlayoutY
manualmente.Veja a documentação e o tutorial para mais informações.