Add a label on top of an imageview that is on a Ti

2019-08-04 11:38发布

问题:

I was making an app that allows users to create custom shops from a game graphically but I was having troubles as I wanted to add a label which shows how much of an item is in a shop but since the imageview is already on a Tile pane, it creates a label beside it but I wanted to create a label on top of it.

回答1:

You could make your items labels and apply the images as graphic nodes to the labels. When the items are selected, you can invoke label.setText("text string") on the label to change the label's text or css style as needed. If the items need to be interactive, you might want to make the buttons instead of labels.

The approach below has a bit of trickery in it by using a combination of contentDisplay="TOP" graphicTextGap="-40.0" and -fx-padding: 0 0 20 0; to position text, which is a little counterintuitive.

<?import java.lang.*?>
<?import java.util.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.image.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.paint.*?>

<StackPane id="StackPane" maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="-1.0" prefWidth="-1.0" xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2">
  <children>
    <TilePane hgap="10.0" prefColumns="3" prefHeight="-1.0" prefRows="1" prefWidth="-1.0" style="-fx-background-color: linear-gradient(palegreen, forestgreen);&#10;-fx-padding: 20px;" vgap="10.0">
      <children>
        <Label contentDisplay="TOP" graphicTextGap="-40.0" style="-fx-font-size: 20px;&#10;-fx-text-fill: gold;&#10;-fx-padding: 0 0 20 0;" text="Roast Beef">
          <graphic>
            <ImageView fitHeight="0.0" fitWidth="0.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true">
              <image>
                <Image url="http://icons.iconarchive.com/icons/rockettheme/ecommerce/256/piggy-bank-icon.png" backgroundLoading="true" />
              </image>
            </ImageView>
          </graphic>
        </Label>
        <Label contentDisplay="TOP" graphicTextGap="-40.0" style="-fx-font-size: 20px;&#10;-fx-text-fill: gold;&#10;-fx-padding: 0 0 20 0;&#10;-fx-border-color: palegoldenrod;&#10;-fx-border-width: 5px;&#10;-fx-border-radius: 10px;&#10;-fx-border-insets: -5px;&#10;" text="Bag 'o' Love">
          <graphic>
            <ImageView fitHeight="0.0" fitWidth="0.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true">
              <image>
                <Image url="http://icons.iconarchive.com/icons/rockettheme/ecommerce/256/bag-icon.png" backgroundLoading="false" />
              </image>
            </ImageView>
          </graphic>
        </Label>
        <Label contentDisplay="TOP" graphicTextGap="-40.0" style="-fx-font-size: 20px;&#10;-fx-text-fill: gold;&#10;-fx-padding: 0 0 20 0;" text="Show Me">
          <graphic>
            <ImageView fitHeight="0.0" fitWidth="0.0" mouseTransparent="true" pickOnBounds="true" preserveRatio="true">
              <image>
                <Image url="http://icons.iconarchive.com/icons/rockettheme/ecommerce/256/wallet-icon.png" backgroundLoading="true" />
              </image>
            </ImageView>
          </graphic>
        </Label>
      </children>
    </TilePane>
  </children>
</StackPane>
<!-- icon usage license: 
     Creative Commons with attribution,
     back link to http://www.rockettheme.com required -->

This is perhaps not the best way to achieve what you want, as you could create a custom ShopItem component derived from Region. With the custom component, you would provide layout logic to internally layer your text (and other graphics as needed) over the top of your item image. This layout logic should be a bit more intuitive than the mechanism provided above.

Another approach would be to make each shop item an AnchorPane which contained the image and text label.

The custom component approach, though more flexible, is a bit more complicated, so I just provided the simple label based solution here.