I've looked around and everything always end with www.google.com looking like this: Webpage bug?
How can I open a webpage within a JFrame/JPanel and have it so that it looks like the normal whole page?
This is what I last tried:
JEditorPane website = null;
try {
website = new JEditorPane("http://www.google.com/");
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
website.setEditable(false);
JFrame frame = new JFrame("Google");
frame.add(new JScrollPane(website));
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.pack();
}
As MadProgrammer suggested I took a look into JavaFX and found it was just what I wanted with this creating a basic webpage:
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class WebViewSample extends Application {
private Scene scene;
#Override public void start(Stage stage) {
// create the scene
stage.setTitle("Web View");
scene = new Scene(new Browser(),750,500, Color.web("#666970"));
stage.setScene(scene);
stage.show();
}
public static void main(String[] args){
launch(args);
}
}
class Browser extends Region {
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
public Browser() {
//apply the styles
getStyleClass().add("browser");
// load the web page
webEngine.load("http://www.oracle.com/products/index.html");
//add the web view to the scene
getChildren().add(browser);
}
private Node createSpacer() {
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
return spacer;
}
#Override protected void layoutChildren() {
double w = getWidth();
double h = getHeight();
layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
}
#Override protected double computePrefWidth(double height) {
return 750;
}
#Override protected double computePrefHeight(double width) {
return 500;
}
}
Related
So I have written a Controller that is supposed to navigate between multiple scenes, however, when the second scene is instantiated java.lang.NullPointerException. Here is my Controller below with a View1() and View2() in a single file mre so you can understand what is happening. My goal is just to have multiple screens and multiple models and using a switch case set different scenes on the stage.
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.canvas.*;
import javafx.scene.image.Image;
public class Controller extends Application {
private Scene scene1, scene2;
public static void main(String[] args) {
launch(args);
}
public void start(Stage theStage) {
this.scene1 = new Scene(new Group(new View1()));
this.scene2 = new Scene(new Group(new View2()));
new AnimationTimer() {
int page = 2;
#Override
public void handle(long currentNanoTime){
// System.out.println(currentNanoTime);
switch (page){
case 2:
page = 1;
theStage.setScene(scene1);
break;
case 1:
page = 2;
theStage.setScene(scene2);
break;
}
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}.start();
theStage.show();
}
}
class View1 extends Group {
public View1() {
Image img = new Image("https://i.imgur.com/8tcxHWh.jpg");
Canvas canvas = new Canvas(img.getWidth(), img.getHeight());
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight());
getChildren().add(canvas);
}
}
class View2 extends Group {
public View2() {
Image img = new Image("https://i.imgur.com/BF3ty6o.jpg");
Canvas canvas = new Canvas(img.getWidth(), img.getHeight());
GraphicsContext gc = canvas.getGraphicsContext2D();
gc.drawImage(img, 0, 0, canvas.getWidth(), canvas.getHeight());
getChildren().add(canvas);
}
}
I would suggest against using AnimationTimer. I would suggest you use Buttons to load different displays. This app demos one way of using Buttons to switch between displays.
Main
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
final StackPane mainDisplay = new StackPane();
final ViewOne viewOne = new ViewOne();
final ViewTwo viewTwo = new ViewTwo();
mainDisplay.getChildren().add(viewOne);//Load first view.
Button btnStageOne = new Button("View One");
Button btnStageTwo = new Button("View Two");
btnStageOne.setOnAction((event) -> {
if(!mainDisplay.getChildren().get(0).equals(viewOne))//If sceneone is not loaded, load it.
{
mainDisplay.getChildren().set(0, viewOne);
}
});
btnStageTwo.setOnAction((event) -> {
if(!mainDisplay.getChildren().get(0).equals(viewTwo))//If scenetwo is not loaded, load it.
{
mainDisplay.getChildren().set(0, viewTwo);
}
});
HBox hbButtonPanel = new HBox(btnStageOne, btnStageTwo);
VBox root = new VBox(mainDisplay, hbButtonPanel);
Scene scene = new Scene(root);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
ViewOne
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
/**
*
* #author sedrick
*/
public final class ViewOne extends StackPane{
Label label = new Label();
public ViewOne() {
label.setText("Scene One!");
getChildren().add(label);
}
}
ViewTwo
import javafx.scene.control.Label;
import javafx.scene.layout.StackPane;
/**
*
* #author sedrick
*/
public final class ViewTwo extends StackPane{
Label label = new Label();
public ViewTwo() {
label.setText("Scene Two!");
getChildren().add(label);
}
}
I have written code to render my html page( html page is from my local machine) in JavaFX application and now I would like to reload webview whenever the html page(specified) gets modified.
And html modification is done by other application.
Can anyone please let me know how to reload the webview .
Here's the my code :
package view;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URI;
import java.util.Timer;
import java.util.TimerTask;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.parser.Parser;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
public class ProgressView extends Application {
private Scene scene;
Browser br = new Browser("E:\\Developer-Job\\test.html");
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Web View");
scene = new Scene(br,750,500, Color.web("#666970"));
stage.setScene(scene);
//scene.getStylesheets().add("webviewsample/BrowserToolbar.css");
stage.show();
}
class Browser extends Region {
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
public Browser(String url) {
//apply the styles
getStyleClass().add("browser");
// load the web page
String strXml = "";
String strBuilt ="";
try {
File f = new File(url);
webEngine.load(f.toURI().toURL().toString());
//add the web view to the scene
getChildren().add(browser);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Node createSpacer() {
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
return spacer;
}
#Override protected void layoutChildren() {
double w = getWidth();
double h = getHeight();
layoutInArea(browser,0,0,w,h,0, HPos.CENTER, VPos.CENTER);
}
#Override protected double computePrefWidth(double height) {
return 750;
}
#Override protected double computePrefHeight(double width) {
return 500;
}
}
}
Thanks in advance.
What about checking for changes periodically?
import javafx.animation.Animation;
import javafx.animation.KeyFrame;
import javafx.animation.Timeline;
import javafx.application.Application;
import javafx.geometry.HPos;
import javafx.geometry.VPos;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import javafx.scene.layout.Region;
import javafx.scene.paint.Color;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import javafx.stage.Stage;
import javafx.util.Duration;
import java.io.File;
import java.io.IOException;
public class ProgressView extends Application {
#Override
public void start(Stage stage) throws Exception {
stage.setTitle("Web View");
Browser br = new Browser("E:\\Developer-Job\\test.html");
Scene scene = new Scene(br, 750, 500, Color.web("#666970"));
stage.setScene(scene);
//scene.getStylesheets().add("webviewsample/BrowserToolbar.css");
stage.show();
}
class Browser extends Region {
final WebView browser = new WebView();
final WebEngine webEngine = browser.getEngine();
public Browser(String url) {
getChildren().add(browser);
//apply the styles
getStyleClass().add("browser");
// load the web page
String strXml = "";
String strBuilt = "";
load(url);
Timeline timeline = new Timeline(new KeyFrame(
Duration.millis(2500),
ae -> load(url)));
timeline.setCycleCount(Animation.INDEFINITE);
timeline.play();
}
private void load(String url) {
try {
File f = new File(url);
webEngine.load(f.toURI().toURL().toString());
//add the web view to the scene
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private Node createSpacer() {
Region spacer = new Region();
HBox.setHgrow(spacer, Priority.ALWAYS);
return spacer;
}
#Override
protected void layoutChildren() {
double w = getWidth();
double h = getHeight();
layoutInArea(browser, 0, 0, w, h, 0, HPos.CENTER, VPos.CENTER);
}
#Override
protected double computePrefWidth(double height) {
return 750;
}
#Override
protected double computePrefHeight(double width) {
return 500;
}
}
}
I've found an answer using below code:
webEngine.documentProperty().addListener(new ChangeListener<Document>() {
#Override
public void changed(ObservableValue<? extends Document> observableValue, Document document, Document newDoc) {
if (newDoc != null) {
//webEngine.documentProperty().removeListener(this);
try {
webEngine.load(f.toURI().toURL().toString());
} catch (MalformedURLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
});
I hava a javafx application where the user enters some details in test fields and it is shown on a listview. I now have a button to print using the printjob but everytime I hit the print button the printer prints garbage data like jhsjs6sh3#uhbsbkahi instead of the real values from the ListView. below is my codes for the print functon
public void print (final Node node) {
Printer printer = Printer.getDefaultPrinter();
PageLayout pageLayout = printer.createPageLayout(Paper.A4, PageOrientation.PORTRAIT, Printer.MarginType.HARDWARE_MINIMUM);
final double scaleX = pageLayout.getPrintableWidth() / node.getBoundsInParent().getWidth();
final double scaleY = pageLayout.getPrintableHeight() / node.getBoundsInParent().getHeight();
node.getTransforms().add(new Scale(scaleX, scaleY));
PrinterJob job =PrinterJob.createPrinterJob();
if (job != null ){
boolean success = job.printPage(node);
System.out.println("printed");
if (success){
System.out.println(success);
job.endJob();
}
}
}
#FXML
private void printOps(ActionEvent event){
print(billingDataList);
}
I use a MacBook for my development and HP printer.
You will have to figure out the scaling. This prints using SnapShot and awt. Using code from here.
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.awt.print.PageFormat;
import static java.awt.print.Printable.NO_SUCH_PAGE;
import static java.awt.print.Printable.PAGE_EXISTS;
import java.awt.print.PrinterException;
import java.awt.print.PrinterJob;
import java.io.File;
import java.io.IOException;
import javafx.application.Application;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Scene;
import javafx.scene.SnapshotParameters;
import javafx.scene.control.Button;
import javafx.scene.control.ListView;
import javafx.scene.image.Image;
import javafx.scene.image.WritableImage;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import javax.imageio.ImageIO;
/**
*
* #author blj0011
*/
public class JavaFXApplication61 extends Application
{
#Override
public void start(Stage primaryStage)
{
ListView<String> list = new ListView<>();
ObservableList<String> items = FXCollections.observableArrayList("A", "B", "C", "D");
list.setItems(items);
VBox root = new VBox();
Button btn = new Button();
btn.setText("Say 'Hello World'");
btn.setOnAction((event) ->
{
WritableImage image = list.snapshot(new SnapshotParameters(), null);
File file = new File("nodeImage.png");
try
{
ImageIO.write(SwingFXUtils.fromFXImage(image, null), "png", file);
Image imageToPrint = new Image(file.toURI().toString());
BufferedImage bufferedImage = SwingFXUtils.fromFXImage(imageToPrint, null);
printImage(bufferedImage);
}
catch (IOException ex)
{
System.out.println(ex.toString());
}
});
root.getChildren().add(btn);
root.getChildren().add(list);
Scene scene = new Scene(root, 1080, 720);
primaryStage.setTitle("Hello World!");
primaryStage.setScene(scene);
primaryStage.show();
}
/**
* #param args the command line arguments
*/
public static void main(String[] args)
{
launch(args);
}
private void printImage(BufferedImage image)
{
PrinterJob printJob = PrinterJob.getPrinterJob();
printJob.setPrintable((Graphics graphics, PageFormat pageFormat, int pageIndex) ->
{
// Get the upper left corner that it printable
int x = (int) Math.ceil(pageFormat.getImageableX());
int y = (int) Math.ceil(pageFormat.getImageableY());
if (pageIndex != 0)
{
return NO_SUCH_PAGE;
}
graphics.drawImage(image, x, y, image.getWidth(), image.getHeight(), null);
return PAGE_EXISTS;
});
try
{
printJob.print();
}
catch (PrinterException e1)
{
e1.printStackTrace();
}
}
}
I'm trying to use the Magnifier from jfxtras-labs 2.2 to see more details on an image. At the same time, I want to draw a rectangle on top of this image. The problem is, that the Magnifier blocks all other events.
Here is my sample code:
package magnifiertest;
import java.io.File;
import javax.imageio.ImageIO;
import javafx.application.Application;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.StackPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;
import jfxtras.labs.scene.control.Magnifier;
public class TestMagnifier extends Application {
Group groupForRectangles;
ImageView pageImageView;
private boolean new_rectangle_is_being_drawn;
private Rectangle new_rectangle;
private double starting_point_x;
private double starting_point_y;
public static void main(String[] args) {
launch();
}
#Override
public void start(Stage primaryStage) throws Exception {
StackPane root = new StackPane();
groupForRectangles = new Group();
groupForRectangles = new Group();
pageImageView = new ImageView();
pageImageView.setPreserveRatio(true);
pageImageView.setFitHeight(800);
pageImageView.setFitWidth(600);
pageImageView.setImage(SwingFXUtils.toFXImage(ImageIO.read(new File("/sample/Penguins.jpg")), null));
groupForRectangles.setOnMouseDragged(event -> {
setOnMouseDragged(event);
});
groupForRectangles.setOnMousePressed(event -> {
setOnMousePressed(event);
});
groupForRectangles.setOnMouseReleased(event -> {
setOnMouseReleased(event);
});
//If you outcomment the following lines, the rectangle drawing works
Magnifier m = new Magnifier(pageImageView);
groupForRectangles.getChildren().add(pageImageView);
groupForRectangles.getChildren().add(m);
root.getChildren().add(groupForRectangles);
primaryStage.setScene(new Scene(root, 800, 600));
primaryStage.show();
}
public void setOnMousePressed(MouseEvent event) {
System.out.println("mouse pressed");
if (new_rectangle_is_being_drawn == false) {
starting_point_x = event.getX();
starting_point_y = event.getY();
System.out.println(starting_point_x + " ; " + starting_point_y);
groupForRectangles.getChildren().remove(new_rectangle);
new_rectangle = new Rectangle();
new_rectangle.setFill(Color.TRANSPARENT);
new_rectangle.setStroke(Color.BLACK);
groupForRectangles.getChildren().add(new_rectangle);
new_rectangle_is_being_drawn = true;
}
}
public void setOnMouseDragged(MouseEvent event) {
if (new_rectangle_is_being_drawn == true) {
double current_ending_point_x = event.getX();// - sub.getLayoutX();
double current_ending_point_y = event.getY();// - sub.getLayoutY();
adjust_rectangle_properties(starting_point_x, starting_point_y, current_ending_point_x,
current_ending_point_y, new_rectangle);
}
}
public void setOnMouseReleased(MouseEvent event) {
if (new_rectangle_is_being_drawn == true) {
new_rectangle.setFill(Color.TRANSPARENT);
new_rectangle_is_being_drawn = false;
}
}
void adjust_rectangle_properties(double starting_point_x, double starting_point_y, double ending_point_x,
double ending_point_y, Rectangle given_rectangle) {
given_rectangle.setX(starting_point_x);
given_rectangle.setY(starting_point_y);
given_rectangle.setWidth((ending_point_x - starting_point_x));
given_rectangle.setHeight((ending_point_y - starting_point_y));
if (given_rectangle.getWidth() < 0) {
given_rectangle.setWidth(-given_rectangle.getWidth());
given_rectangle.setX(given_rectangle.getX() - given_rectangle.getWidth());
}
if (given_rectangle.getHeight() < 0) {
given_rectangle.setHeight(-given_rectangle.getHeight());
given_rectangle.setY(given_rectangle.getY() -
given_rectangle.getHeight());
}
}
}
Thanks.
I am having one code that send command to server.
public static void createAndSendCommand(String action, byte[] data) {
if (action.equals(OE_Constants.ACTION_UPDATE)) {
File file = new File(OE_Constants.FILE_BACKUP_TOPOLOGY);
Command command = ConnectionManager.populateData(file);
FrontEndClient.sendCommandToServer(command);
}
}
and
public static boolean sendCommandToServer(Command command) {
try {
outStream.writeObject(command);
return true;
} catch (Exception e) {
e.printStackTrace();
}
return false;
}
And I am receiving result like below.
public void receiveResultFromServer() {
try {
while(!clientSocket.isClosed()) {
CommandExecResult result;
try {
result = (CommandExecResult) inStream.readObject();
ConnectionManager.parseCommandExecutionResult(result);
} catch (ClassNotFoundException e) {
e.printStackTrace();
}catch (IOException e) {
e.printStackTrace();
}
}
}
}
Now I want to wait for command to be successfully executed on server till the result of it is received by client. I want to show some Progress indicator type of UI ....how to do that?
Thanks!
Use a Task or a Service for your long running server calls.
Use Task.updateProgress() to inform on the current progress / work done.
Bind the progressProperty of your running Task to a ProgressBar or ProgressIndicator.
You specified the tags java and javafx. Here is my solution for javafx. It is a simple dialog that can be updated from 'outside' via binding.
WorkingDialog.java:
package stackoverflow.progress;
import java.net.URL;
import java.util.ResourceBundle;
import java.util.logging.Logger;
import javafx.application.Platform;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.ProgressBar;
import javafx.scene.layout.BorderPane;
import javafx.scene.layout.GridPane;
import javafx.stage.Modality;
import javafx.stage.Stage;
import javafx.stage.StageStyle;
import javafx.stage.WindowEvent;
public final class WorkingDialog extends Stage implements Initializable {
private static final Logger LOG = Logger.getLogger(WorkingDialog.class.getName());
public SimpleDoubleProperty progress = new SimpleDoubleProperty(0);
public WorkingDialog(String title, Stage owner) {
super();
setTitle(title);
initStyle(StageStyle.UTILITY);
initModality(Modality.APPLICATION_MODAL);
initOwner(owner);
double w = 300;
double h = 200;
setWidth(w);
setHeight(h);
double dx = (owner.getWidth() - w) / 2;
double dy = (owner.getHeight() - h) / 2;
setX(owner.xProperty().get() + dx);
setY(owner.yProperty().get() + dy);
setResizable(false);
showDialog(progress);
}
public void hideDialog() {
Platform.runLater(() -> {
hide();
});
}
public void setTitleText(String title) {
Platform.runLater(() -> {
setTitle(title);
});
}
private void showDialog(SimpleDoubleProperty progress) {
//scene : gridPane : 0,0->progressbar,0,1->borderpane : center->button
GridPane gridPane = new GridPane();
gridPane.setGridLinesVisible(false);
gridPane.setPadding(new Insets(10));
gridPane.setHgap(5);
gridPane.setVgap(5);
setOnCloseRequest((WindowEvent e) -> {
e.consume();
});
ProgressBar pb = new ProgressBar(-1);
pb.setPrefWidth(300);
pb.progressProperty().bind(progress);
BorderPane borderPane = new BorderPane(pb);
gridPane.add(borderPane, 0, 0);
Scene scene = new Scene(gridPane);
setScene(scene);
sizeToScene();
show();
}
#Override
public void initialize(URL location, ResourceBundle resources) {
}
}
Example for usage (WorkingDialogTest.java):
package stackoverflow.progress;
import java.util.logging.Logger;
import javafx.application.Application;
import static javafx.application.Application.launch;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.event.ActionEvent;
import javafx.scene.Group;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.layout.HBox;
import javafx.stage.Stage;
public class WorkingDialogTest extends Application {
private static final Logger LOG = Logger.getLogger(WorkingDialogTest.class.getName());
#Override
public void start(Stage primaryStage) {
Group group = new Group();
Scene scene = new Scene(group);
primaryStage.setTitle("Dialogs");
primaryStage.setWidth(600);
primaryStage.setHeight(400);
Button button = new Button("function");
button.setOnAction((ActionEvent e) -> {
WorkingDialog wd = new WorkingDialog("title", primaryStage);
new Thread(() -> {
int counter = 10;
for (int i = 0; i < counter; i++) {
try {
wd.progress.set(1.0 * i / (counter - 1));
Thread.sleep(1000); //<-------- do more useful stuff here
} catch (InterruptedException ex) {
}
}
wd.hideDialog();
}).start();
});
HBox hbox = new HBox(button);
group.getChildren().addAll(hbox);
primaryStage.setScene(scene);
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
It looks like this: