Below is the code I use to view image and caption text together:
try
{
Scanner scanner = new Scanner( new File("data.txt") );
String text = scanner.useDelimiter("ENDOFFILE").next();
scanner.close(); // Put this call in a finally block
System.out.println(text);
String[] data = text.split("\n");
for(int i=0;i<data.length;i++)
{
if(i%2==0)
{
System.out.println("This is "+data[i]);
Image img = new Image(new File(data[i]).toURI().toString(), 100, 0, false, false);
ImageView selectedImage = new ImageView();
selectedImage.setImage(img);
v.getChildren().addAll(selectedImage);
}
else
{
Text t = new Text(data[i]);
t.setFont(Font.font("Tahoma", FontWeight.NORMAL, 14));
v.getChildren().add(t);
}
}
}
catch(Exception E)
{
E.printStackTrace();
}
root2.getChildren().add(v);
Scene scene = new Scene(root2, 1000, 1000);
stage.setScene(scene);
stage.show();
}
data[i] for the image is Udiagram.jpg which is present within the same directory as the program. No exceptions occur but the image is not displayed, it shows empty with only text shown as follows: Text goes here.
The file data.txt is as follows:
UDiagram.jpg
Hit and Run
ENDOFFILE
What could be the reason for not displaying the image but only the text?
I believe you just need to concatenate the file and folder name to the beginning of your String.
Image image = new Image("file:FOLDER_NAME/imageName.gif");
ImageView imageView = new ImageView();
imageView.setImage(image);
imageView.setFitWidth(100);
imageView.setPreserveRatio(true);
imageView.setSmooth(true);
Related
I have a program where I can insert something in a textfield and then after pressing the enter button, it will be displayed as a label in a VBox.
My layout looks like this:
A tab with inside a borderpane with on the bottom a hbox containing a textfield and a button and at the top a scrollpane containing a vbox full of labels.
This is the code:
Tab consoleTab = new Tab("Console");
consoleTab.setClosable(false);
BorderPane consoleContent = new BorderPane();
TextField commandEntry = new TextField();
commandEntry.setPromptText("Enter command...");
Button exe = new Button("Enter");
HBox input = new HBox(5, commandEntry, exe);
VBox outputL = new VBox();
ScrollPane output = new ScrollPane();
output.setMinHeight(365);
output.setMaxHeight(365);
output.setContent(outputL);
EventHandler<ActionEvent> customEvent = e -> {
String in = commandEntry.getText();
if (in.equals("")) return;
Label inserted = new Label("> "+in);
inserted.setStyle("-fx-font-weight: bold");
outputL.getChildren().add(inserted);
commandEntry.setText("");
Command cmd = new Command(in, outputL);
cmd.execute(true);
output.setVvalue(1); // This does not work
};
commandEntry.setOnAction(customEvent);
exe.setOnAction(customEvent);
consoleContent.setTop(output);
consoleContent.setBottom(input);
consoleContent.setPadding(new Insets(5, 5, 5, 5));
consoleTab.setContent(consoleContent);
And this is the Command.java class:
public class Command {
private String command;
private VBox vbox;
public static final String NEW_FILE = "new_file";
public static final String OPEN_FILE = "open";
public static final String SAVE_FILE = "save";
public static final String LIST_FILES = "list";
public static final String HELP = "help";
public Command(String command, VBox v){
this.command = command;
this.vbox = v;
}
public void execute(boolean layout){
String[] args = this.command.split(" ");
String cmd = args[0];
String outputText = "";
switch (cmd){
case NEW_FILE:
break;
case OPEN_FILE:
outputText = "File opened";
break;
case SAVE_FILE:
break;
case LIST_FILES:
outputText = "Files listed";
break;
case HELP:
outputText = "Available commands:\nOPEN: open <file-name>\nLIST: list";
break;
default:
outputText = "Command not found, type help to get the list of available commands";
break;
}
if (layout){
makeLayout(outputText);
}
}
private void makeLayout(String outputText){
this.vbox.getChildren().add(new Label(outputText));
}
}
The problem is that when I call the setVvalue(1.0) method of the scrollpane, this is not setting the scrollbar at the bottom.
I have tried with using output.setContent(outputL) before output.setVvalue(1.0) but nothing changes.
Thanks for any help
Generate a layout pass before setting the scroll value. To generate a layout pass see:
Get the height of a node in JavaFX (generate a layout pass)
// change the content of the scroll pane
// . . .
// generate a layout pass on the scroll pane.
scrollPane.applyCss();
scrollPane.layout();
// scroll to the bottom of the scroll pane.
scrollPane.setVvalue(scrollPane.getVmax());
Why this works
When the layout pass occurs, the vValue of the scroll pane will change to keep the currently visible area displayed rather than the new area. If you then set the vValue to the maximum value, it will change from the value calculated in the layout pass to the maximum value, scrolling the pane to the bottom of the visible content.
Sample code
This is just a code snippet to demonstrate the approach, not an executable application.
I did test the approach with the example code in the original question, and it worked fine.
public void start(Stage stage) {
VBox content = new VBox();
final ScrollPane scrollPane = new ScrollPane();
scrollPane.setContent(content);
Button append = new Button("Append");
append.setOnAction(e -> appendToScrollPane(scrollPane));
VBox layout = new VBox(scrollPane, append);
stage.setScene(new Scene(layout));
stage.show();
}
public void appendToScrollPane(ScrollPane scrollPane) {
// ... actions which add content to the scroll pane ...
// generate a layout pass on the scroll pane.
scrollPane.applyCss();
scrollPane.layout();
// scroll to the bottom of the scroll pane.
scrollPane.setVvalue(scrollPane.getVmax());
}
So, for my class project I am making a game. I want to add a volume slider to change the music volume. I am very stuck here. Please help me.
I was following tutorial, and I was able to display it on the scree. But, the volume doesn't change, even though I slide the bar. Can somebody give me advice? Thank you.
private Scene createOptionScene() {
String path = "E:\\All Computer Science Materials\\Java 240 Project\\PrinceFX\\Music\\"
+ songs.getSong(1) + ".mp3";
Media media = new Media(new File(path).toURI().toString());
currentPlay = new AudioClip(media.getSource());
currentPlay.setCycleCount(MediaPlayer.INDEFINITE);
currentPlay.play();
// Volume Control
volumeSlider.setValue(currentPlay.getVolume() * 100);
volumeSlider.valueProperty().addListener(new InvalidationListener() {
#Override
public void invalidated(Observable observable) {
currentPlay.setVolume(volumeSlider.getValue() / 100);
}
});
HBox temp = new HBox();
temp.getChildren().addAll(volumeSlider);
temp.setTranslateX(850);
temp.setTranslateY(410);
volumeSlider.setMinWidth(300);
Image image = new Image(new File("E:\\All Computer Science Materials\\" +
"Java 240 Project\\PrinceFX\\image\\" + picture.getImage(2) + ".png").toURI().toString());
//Setting the image view
ImageView imageView = new ImageView(image);
//Setting the position of the image
imageView.setX(0);
imageView.setY(0);
//setting the fit height and width of the image view
imageView.setFitHeight(primaryScreenBounds.getHeight());
imageView.setFitWidth(primaryScreenBounds.getWidth());
//Setting the preserve ratio of the image view
imageView.setPreserveRatio(true);
Label labelOption = new Label();
Button goBack = new Button("Go Back to Main");
goBack.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent event) {
currentPlay.stop();
sceneStart = createStartScene();
stageOne.setScene(sceneStart);
}
});
// Button to the main page.
HBox layoutOp = new HBox(15);
layoutOp.getChildren().addAll(labelOption, goBack);
// Button coordinate.
layoutOp.setTranslateX(1400);
layoutOp.setTranslateY(750);
Group gOption = new Group(imageView, layoutOp, temp);
return new Scene(gOption, 200, 200);
}
I try to make a slide frame looks like powerpoint using imageview and tilepane.
Let's suppose we are in powerpoint. In photo, there are blue background panel(tilepane) and slide(imageview).
I want make a mark(line) that is red arrow pointed in photo, when I locate mouse cursor where between slide5 and slide6. Can I make?
And how to get the each hgap area's information?
ex) Which hgap clicked?
I can get the each slide(imageview) value, but I can't find how to get the hgap's information.
This is my partial code.
String[] imageName = {"slide1.png", "slide2.png", "slide3.png", "slide4.png",
"slide5.png", "slide6.png", "slide7.png", "slide8.png"};
Image img = null;
for (int i = 0; i < imageName.length; i++) {
try {
img = new Image(getClass().getResourceAsStream(imageName[i]));
} catch (Exception e) {
System.out.println("exception : " + e);
}
ImageView imageview = new ImageView(img);
imageview.setUserData(imageName[i]);
imageview.setFitWidth(widthImageView);
imageview.setFitHeight(heightImageView);
HBox hbox= new HBox();
hbox.getChildren().add(imageview);
tile1.getChildren().add(hbox); }
The hgap and vgap parameters are used for calculating the space between the nodes. You can't put a node in there. You should evaluate your requirements and consider using a different layout like e. g. GridPane.
I want to add Multiple images in Scollpane by clicking button i try below code but it will not display image any idea about that?
#FXML private void OnClick(ActionEvent ae)
{
getGalleryView();
}
public void getGalleryView()
{
ScrolPane sp=new ScroPane();
Hbox hb=new Hbox();
Image [] images=new Image[5];
ImageView []pics=new ImageView[5];
final String [] imageNames = new String [] {"fw1.jpg", "fw2.jpg",
"fw3.jpg", "fw4.jpg", "fw5.jpg"};
for (int i = 0; i < 5; i++) {
images[i] = new Image(getClass().getResourceAsStream(imageNames[i]));
pics[i] = new ImageView(images[i]);
pics[i].setFitWidth(100);
pics[i].setPreserveRatio(true);
hb.getChildren().add(pics[i]);
sp.setContent(hb);
}
}
You need to add the scrollpane to the scene:
#FXML private void OnClick(ActionEvent ae)
{
getGalleryView(ae);
}
public void getGalleryView(ActionEvent ae)
{
ScrolPane sp=new ScroPane();
Hbox hb=new Hbox();
Image [] images=new Image[5];
ImageView []pics=new ImageView[5];
final String [] imageNames = new String [] {"fw1.jpg", "fw2.jpg",
"fw3.jpg", "fw4.jpg", "fw5.jpg"};
for (int i = 0; i < 5; i++) {
images[i] = new Image(getClass().getResourceAsStream(imageNames[i]));
pics[i] = new ImageView(images[i]);
pics[i].setFitWidth(100);
pics[i].setPreserveRatio(true);
hb.getChildren().add(pics[i]);
sp.setContent(hb);
}
Scene scene = ((Node) ae.getSource()).getScene();
((Pane) scene.getRoot()).getChildren().add(sp);
}
I assumed here that your root node is a Pane or one of its subclasses.
ScrolPane sp=new ScroPane(); error?
EDIT:
I was developing similar method. Mine works fine. You can check if you want to.
private List<String> listFileNames(File folder) throws NullPointerException{
List<String> list = new ArrayList<>();
for (File file : folder.listFiles()) {
if (file.isDirectory())
listFileNames(file);
else {
System.out.println(file.getName());
list.add(file.getName());
}
}
return list;
}
private void insertImages(List<String> list, Hero thisHero) {
int column = 0;
int row = 0;
for (String path:list) {
String fullPath = "file:"+thisHero.getHeroClass().getFile()+"\\"+path;
ToggleButton button = new ToggleButton();
button.setBackground(Background.EMPTY);
button.setGraphic(new ImageView(new Image(fullPath)));
grid.add(button,column,row);
column++;
if (column == 5) {
row++;
column = 0;
}
}
}
I can write more if you want. I use Lists because of it's ease of adding items.
You can use first method to just get all file names to list, from your folder filled with image files.
Second method does the job of making new ImageViews filled with ToggleButtons with graphic. I just changed the concept to buttons, so sorry about my laziness of not changing code to exactly fit your needs.
Path is the exact file name, thisHero.getHeroClass().getFile() returns path to the directory which contains this image.
grid.add(button, column, row) adds this button to the grid pane which i made before. It's my app, so sorry for not sharing all the code, but i thought that this snippet could be usefull.
EDIT2: You could also provide us with error information if there is any.
In my JavaFx application I need to have a word or two rendered in boldface in the whole sentence. Currently the sentence is rendered as a JavaFx Label but upgrading component also would not allow me set the text as so that I can have the words "Sample" displayed in bold.
String s = "This is a <b>Sample</b> sentence"
Label label = new Label(s);
output
This is a Sample sentence
JavaFx Text also does not allow this. Is there any component where I can have a portion of the text in boldface?
I am not sure if JavaFx WebView is a good idea for rendering many small sentences in a window.
It is possible to use TextFlow container from JavaFX8.
Then you can easily add differently styled Text nodes inside it.
TextFlow flow = new TextFlow();
Text text1=new Text("Some Text");
text1.setStyle("-fx-font-weight: bold");
Text text2=new Text("Some Text");
text2.setStyle("-fx-font-weight: regular");
flow.getChildren().addAll(text1, text2);
TextFlow container will automatically wrap content Text nodes.
Since the previous answers did not include FXML code, I'll post an additional one.
As suggested by #Ernisto, you can use a TextFlow that contains Text parts, where each part can be styled differently.
Example FXML file content:
<TextFlow>
<Text text="Normal text and "/>
<Text text="bold text and " style="-fx-font-weight: bold"/>
<Text text="italic text and " style="-fx-font-style: italic"/>
<Text text="red text." style="-fx-stroke: red"/>
</TextFlow>
Output:
Update: JavaFX 8 provides new control for the rich text: TextFlow
Unfortunately there is no such feature in 2.2, although it may be included into next release.
For now you can try to use next approaches:
HBox with several Label or Text components
WebView
Canvas with several Text components drawn
public class UtilsDialog {
private static final String TAG = "UtilsDialog";
private static boolean sIsShowing = false;
public static void showDialogShowError(String title, String msg, String defaultStyle,
#Nullable String customStyle, String... styledWords) {
if (sIsShowing) return;
Stage dialogStage = new Stage(StageStyle.UTILITY);
dialogStage.initModality(Modality.APPLICATION_MODAL);
dialogStage.setWidth(400);
dialogStage.setHeight(220);
BorderPane borderPane = new BorderPane();
borderPane.setPadding(new Insets(15));
borderPane.setPrefWidth(Integer.MAX_VALUE);
borderPane.setPrefHeight(Integer.MAX_VALUE);
Scene scene = new Scene(borderPane);
dialogStage.setScene(scene);
sIsShowing = true;
dialogStage.show();
UtilsGui.closeOnEsc(borderPane, scene);
scene.addEventHandler(KeyEvent.KEY_PRESSED, t -> {
if (t.getCode() == KeyCode.ESCAPE) {
sIsShowing = false;
}
});
// Top
Text textTitle = new Text(title);
textTitle.setStyle("-fx-font-size: 18px;");
HBox hBoxTop = new HBox(10);
hBoxTop.getChildren().addAll(textTitle);
borderPane.setTop(hBoxTop);
// Center
TextFlow textFlow = new TextFlow();
List<String> words = Arrays.asList(msg.split(" "));
List<String> styledWordsList = Arrays.asList(styledWords);
for (String word : words) {
Text tmpWord = new Text(word);
if (styledWordsList.contains(word
.replace(".", "")
.replace(",", "")
.replace("?", "")
.replace("!", "")
.replace(";", "")
.replace("\n", "")
)) {
tmpWord.setStyle(customStyle);
} else {
if (defaultStyle == null) {
tmpWord.setStyle("");
} else {
tmpWord.setStyle(defaultStyle);
}
}
tmpWord.setText(tmpWord.getText());
textFlow.getChildren().add(tmpWord);
textFlow.getChildren().add(new Text(" "));
}
Text textMsg = new Text(msg);
textMsg.setStyle("-fx-font-size: 14px;");
HBox hBoxInputPane = new HBox(10);
hBoxInputPane.setAlignment(Pos.CENTER);
VBox vBoxCenter = new VBox(10);
vBoxCenter.setPadding(new Insets(25, 0, 15, 0));
vBoxCenter.getChildren().addAll(textFlow);
borderPane.setCenter(vBoxCenter);
JFXButton btnOk = new JFXButton("OK");
btnOk.setAlignment(Pos.CENTER_RIGHT);
btnOk.setStyle("-fx-text-fill: WHITE; -fx-background-color: #5264AE; -fx-font-size: 14px;");
btnOk.setOnAction(event -> {
sIsShowing = false;
dialogStage.close();
});
// Bottom
HBox hBoxBottom = new HBox();
final Pane spacer = new Pane();
HBox.setHgrow(spacer, Priority.ALWAYS);
hBoxBottom.getChildren().addAll(spacer, btnOk);
borderPane.setBottom(hBoxBottom);
// store on close
dialogStage.setOnCloseRequest(event -> sIsShowing = false);
}
}
call:
UtilsDialog.showDialogShowError("Test", "This is the message to show. Does it work?",
null, "-fx-font-weight: bold", "This", "message", "show");