So I'm pretty new to JavaFX and have been struggling getting a listener to work properly on my TableView. I've found several different examples, but none seem to work they way I expect, or there's a problem somewhere else in my code that is preventing it from working.
Here's the snippet of the listener code in my initialize method:
bookList.addListener((Change<? extends LibraryBook> c) -> {
while (c.next()) {
if (c.wasAdded()) {
MainController.getInstance().setFieldChange(true);
}
if (c.wasRemoved()) {
MainController.getInstance().setFieldChange(true);
}
if (c.wasUpdated()) {
MainController.getInstance().setFieldChange(true);
}
}
});
tvLibraryTable.setItems(bookList);
bookName.setCellValueFactory(new PropertyValueFactory<>("book"));
quantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
My observableList is currently initialized in my constructor (but I've moved it around a few other places as well:
if(library.getBooks() != null) {
this.newList = new ArrayList<LibraryBook>(library.getBooks());
this.bookList = FXCollections.observableArrayList(library.getBooks());
So in the rest of my controller view, I've got buttons to add and remove books from the list, and if you double click on an item in the list you can update the quantity. I'm using custom modal dialogue boxes for all these options. When I return the results from the dialogue box, I update my bookList and I think that's where my problem might be. Here's my full code for the controller class. And I'm pretty sure the code is pretty rough, but it's functional at the moment...minus the tableview listener.
package app;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.ResourceBundle;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.Font;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfContentByte;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfWriter;
import javafx.beans.Observable;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.geometry.Insets;
import javafx.scene.control.Label;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.control.TextFormatter;
import javafx.scene.control.TextInputDialog;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.image.ImageView;
import javafx.scene.input.MouseButton;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.GridPane;
import javafx.util.Pair;
import javafx.util.converter.NumberStringConverter;
import javafx.scene.control.Alert.AlertType;
import models.Book;
import models.Library;
import models.LibraryBook;
import models.ValidationException;
import view.ViewType;
import javafx.scene.control.Alert;
import javafx.scene.control.Button;
import javafx.scene.control.ButtonBar.ButtonData;
import javafx.scene.control.ButtonType;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Dialog;
public class LibraryDetailViewController implements Initializable {
private static Logger logger = LogManager.getLogger();
private Library library;
private Library origLibrary;
private List<LibraryBook> newList;
private ObservableList<LibraryBook> bookList;
#FXML private TextField tfLibrary;
#FXML private TableView<LibraryBook> tvLibraryTable;
#FXML private TableColumn<LibraryBook, Book> bookName;
#FXML private TableColumn<LibraryBook, Integer> quantity;
#FXML private ComboBox<Book> cbBook;
#FXML private Button saveButton, auditTrail, inventoryReport, addBook, deleteBook;
#FXML private Label saveLabel;
public LibraryDetailViewController(Library library) {
this.library = library;
this.origLibrary = new Library(library);
if(library.getBooks() != null) {
this.newList = new ArrayList<LibraryBook>(library.getBooks());
this.bookList = FXCollections.observableArrayList(library.getBooks());
} else {
this.newList = new ArrayList<LibraryBook>();
this.bookList = FXCollections.observableArrayList();
}
}
//event handler for buttons
#FXML private void handleButtonAction(ActionEvent event) {
Object source = event.getSource();
if (source == saveButton) {
try {
saveLibraryFields();
saveLabel.setText(library.saveLibrary(origLibrary));
origLibrary = library;
} catch (SQLException e) {
logger.error(e);
Alert alert = new Alert(AlertType.ERROR);
alert.setHeaderText("Save Error");
alert.setContentText("Error saving data. Please check fields and try again.");
alert.showAndWait();
//revert to original model data on error
library = origLibrary;
} catch (ValidationException e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setHeaderText(e.getMessage());
alert.showAndWait();
}
} else if(source == auditTrail) {
if(library.getId() == 0) {
Alert alert = new Alert(AlertType.WARNING);
alert.setHeaderText("Audit Trail Error");
alert.setContentText("No audit trail exists! Please save the library first.");
alert.showAndWait();
} else {
MainController.getInstance().changeView(ViewType.LIBRARY_AUDITTRAIL, library);
}
} else if(source == inventoryReport) {
try {
createPdf("Inventory Report.pdf");
Alert alert = new Alert(AlertType.INFORMATION);
alert.setTitle("Success");
alert.setHeaderText(null);
alert.setContentText("The report has been created!");
alert.showAndWait();
} catch (IOException e) {
e.printStackTrace();
} catch (DocumentException e) {
e.printStackTrace();
}
} else if(source == addBook) {
// create modal dialogue box
List<Book> books = new ArrayList<Book>(MainController.getInstance().getBookGateway().getBooks());
Dialog<Pair<Book, String>> dialog = new Dialog<>();
dialog.setTitle("Book List");
dialog.setHeaderText("Add a book to the library");
dialog.setGraphic(new ImageView(this.getClass().getResource("/view/book-stack.png").toString()));
ButtonType okButtonType = new ButtonType("Ok", ButtonData.OK_DONE);
dialog.getDialogPane().getButtonTypes().addAll(okButtonType, ButtonType.CANCEL);
GridPane grid = new GridPane();
grid.setHgap(10);
grid.setVgap(10);
grid.setPadding(new Insets(20, 150, 10, 10));
ObservableList<Book> bookListOptions = FXCollections.observableArrayList(books);
ChoiceBox<Book> cbBooks = new ChoiceBox<Book>(bookListOptions);
TextField tfQuantity = new TextField();
tfQuantity.setTextFormatter(new TextFormatter<>(new NumberStringConverter()));
tfQuantity.setPromptText("Quantity");
grid.add(new Label("Please select a book"), 0, 0);
grid.add(cbBooks, 1, 0);
grid.add(new Label("Please enter a quantity"), 0, 1);
grid.add(tfQuantity, 1, 1);
dialog.getDialogPane().setContent(grid);
// convert results that were selected
dialog.setResultConverter(dialogButton -> {
if (dialogButton == okButtonType) {
return new Pair<>(cbBooks.getSelectionModel().getSelectedItem(), tfQuantity.getText());
}
return null;
});
// return results of dialogue box to main view and reinitialize tableView list
Optional<Pair<Book, String>> result = dialog.showAndWait();
result.ifPresent(book -> {
newList.add(new LibraryBook(book.getKey(), Integer.parseInt(book.getValue()), true));
library.setBooks(newList);
bookList = FXCollections.observableArrayList(library.getBooks());
bookName.setCellValueFactory(new PropertyValueFactory<>("book"));
quantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
tvLibraryTable.setItems(bookList);
});
} else if(source == deleteBook) {
newList.remove(tvLibraryTable.getSelectionModel().getSelectedItem());
library.setBooks(newList);
bookList = FXCollections.observableArrayList(library.getBooks());
bookName.setCellValueFactory(new PropertyValueFactory<>("book"));
quantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
tvLibraryTable.setItems(bookList);
}
}
/**
* event handler for double clicking a book from the ListView
*
* #param event
*/
#FXML private void handleMouseClick(MouseEvent event) {
if(event.getButton().equals(MouseButton.PRIMARY)){
if(event.getClickCount() == 2){
if (tvLibraryTable.getSelectionModel().isEmpty()) {
Alert alert = new Alert(AlertType.WARNING);
alert.setHeaderText("Update Quantity Error");
alert.setContentText("No book was selected!");
alert.showAndWait();
} else {
LibraryBook lb = tvLibraryTable.getSelectionModel().getSelectedItem();
TextInputDialog dialog = new TextInputDialog();
dialog.setTitle("Edit Book");
dialog.setHeaderText("Please enter the new quantity.");
dialog.setContentText("Quantity:");
Optional<String> result = dialog.showAndWait();
result.ifPresent(quantity -> {
lb.setQuantity(Integer.parseInt(quantity));
tvLibraryTable.refresh();
});
}
}
}
}
public void saveLibraryDetail() {
try {
saveLibraryFields();
library.saveLibrary(origLibrary);
origLibrary = library;
} catch (SQLException e) {
logger.error(e);
library = origLibrary;
} catch (ValidationException e) {
Alert alert = new Alert(AlertType.ERROR);
alert.setHeaderText(e.getMessage());
alert.showAndWait();
}
}
public void saveLibraryFields() {
library.setLibraryName(tfLibrary.getText());
library.setBooks(tvLibraryTable.getItems());
}
private class MyFooter extends PdfPageEventHelper {
Font ffont = new Font(Font.FontFamily.UNDEFINED, 18, Font.ITALIC);
public void onEndPage(PdfWriter writer, Document document) {
PdfContentByte cb = writer.getDirectContent();
Phrase header = new Phrase(library.getLibraryName(), ffont);
ColumnText.showTextAligned(cb, Element.ALIGN_CENTER,
header,
(document.right() - document.left()) / 2 + document.leftMargin(),
document.top() + 10, 0);
}
}
public void createPdf(String filename) throws IOException, DocumentException {
Document document = new Document();
PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
MyFooter event = new MyFooter();
writer.setPageEvent(event);
document.open();
//create table with 4 evenly-spaced columns
PdfPTable table = new PdfPTable(4);
table.addCell("Title:");
table.addCell("Author:");
table.addCell("Publisher:");
table.addCell("Quantity:");
table.setHeaderRows(1);
table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_CENTER);
for(int aw = 0; aw < library.getBooks().size(); aw++){
table.addCell(library.getBooks().get(aw).getBook().getTitle());
table.addCell(library.getBooks().get(aw).getBook().getAuthor().getFullName());
table.addCell(library.getBooks().get(aw).getBook().getPublisher());
table.addCell(String.valueOf(library.getBooks().get(aw).getQuantity()));
table.completeRow();
}
document.add(table);
document.close();
}
#Override
public void initialize(URL location, ResourceBundle resources) {
//init field values
tfLibrary.setText(library.getLibraryName());
/*if(library.getBooks() != null) {
ObservableList<LibraryBook> booksList = FXCollections.observableArrayList(library.getBooks());
bookName.setCellValueFactory(new PropertyValueFactory<>("book"));
quantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
tvLibraryTable.setItems(booksList);
}*/
//event listeners for field changes
if(library.getId() == 0) {
MainController.getInstance().setFieldChange(true);
}
tfLibrary.textProperty().addListener(new ChangeListener<String>() {
public void changed(ObservableValue<? extends String> observable,
String oldValue, String newValue) {
MainController.getInstance().setFieldChange(true);
}
});
/**
* Unable to get listener for tableview to work properly :(
*
ObservableList<LibraryBook> bookList = FXCollections.observableArrayList(book ->
new Observable[] {
(Observable) book.getBook(),
book.getObsQuantity()
});
*/
bookList.addListener((Change<? extends LibraryBook> c) -> {
while (c.next()) {
if (c.wasAdded()) {
MainController.getInstance().setFieldChange(true);
}
if (c.wasRemoved()) {
MainController.getInstance().setFieldChange(true);
}
if (c.wasUpdated()) {
MainController.getInstance().setFieldChange(true);
}
}
});
tvLibraryTable.setItems(bookList);
bookName.setCellValueFactory(new PropertyValueFactory<>("book"));
quantity.setCellValueFactory(new PropertyValueFactory<>("quantity"));
}
}
And here's my fxml code:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<?import javafx.scene.control.TableColumn?>
<?import javafx.scene.control.TableView?>
<?import javafx.scene.control.TextField?>
<?import javafx.scene.layout.AnchorPane?>
<?import javafx.scene.text.Font?>
<AnchorPane id="pane-bg" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0" xmlns="http://javafx.com/javafx/8.0.111" xmlns:fx="http://javafx.com/fxml/1">
<children>
<Label layoutX="106.0" layoutY="63.0" text="Library Name:">
<font>
<Font name="Serif Regular" size="18.0" />
</font>
</Label>
<Button fx:id="saveButton" layoutX="465.0" layoutY="126.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Save">
<font>
<Font name="Serif Regular" size="14.0" />
</font>
</Button>
<TextField fx:id="tfLibrary" layoutX="224.0" layoutY="61.0" />
<Label fx:id="saveLabel" layoutX="431.0" layoutY="277.0" textFill="#f20909">
<font>
<Font name="Serif Regular" size="18.0" />
</font>
</Label>
<Button fx:id="auditTrail" layoutX="440.0" layoutY="170.0" mnemonicParsing="false" onAction="#handleButtonAction" text="View Audit Trail" />
<TableView fx:id="tvLibraryTable" editable="true" layoutX="174.0" layoutY="104.0" onMouseClicked="#handleMouseClick" prefHeight="215.0" prefWidth="248.0">
<columns>
<TableColumn fx:id="bookName" prefWidth="169.0" text="Book Name" />
<TableColumn fx:id="quantity" prefWidth="77.0" text="Quantity" />
</columns>
</TableView>
<Button fx:id="inventoryReport" layoutX="437.0" layoutY="215.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Inventory Report" />
<Button fx:id="addBook" layoutX="174.0" layoutY="325.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Add Book">
<font>
<Font name="Serif Regular" size="14.0" />
</font>
</Button>
<Button fx:id="deleteBook" layoutX="331.0" layoutY="325.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Delete Book">
<font>
<Font name="Serif Regular" size="14.0" />
</font>
</Button>
<!-- <Button fx:id="backToListButton" layoutX="309.0" layoutY="286.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Back to Author List" /> -->
</children>
</AnchorPane>
Related
I have a pdf reader developped using Apache PdfBox, my problem is that i have a blurry image after zooming , this problem is only with PDF even if the resolution is very good of the pdf file.
this code working good with png or jpg files, but the problem still with pdf files, i'am really confused, i search on google but i found some solutions that are not complete.
Controller
package application;
import java.nio.file.Paths;
import javafx.beans.InvalidationListener;
import javafx.beans.Observable;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.fxml.FXML;
import javafx.scene.control.ScrollPane;
import javafx.scene.control.ScrollPane.ScrollBarPolicy;
import javafx.scene.image.ImageView;
import javafx.scene.layout.VBox;
public class Controller {
String imagePath = "C:\\Users\\piratack007\\Desktop\\1.jpg";
private ImageView imageView = new ImageView();
String path="C:\\Users\\piratack007\\Desktop\\file.pdf";
private PdfModel model= new PdfModel(Paths.get(path));
private ScrollPane scrollPane = new ScrollPane();
private DoubleProperty zoom = new SimpleDoubleProperty(1.1);
private PageDimensions currentPageDimensions ;
#FXML private VBox vbox;
String cssLayout = "-fx-border-color: red;\n" +
"-fx-border-insets: 5;\n" +
"-fx-border-width: 3;\n" +
"-fx-border-style: dashed;\n";
String scrollCssLayout= "-fx-border-color: green;\n" +
"-fx-border-insets: 5;\n" +
"-fx-border-width: 3;\n" +
"-fx-border-style: dashed;\n"+
//Ne pas afficher le petit trait gris
"-fx-background-color:transparent";
public void initialize() {
afficheImage();
}
void afficheImage() {
/*try {
imageView = new ImageView(new Image(new FileInputStream(imagePath)));
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}*/
//loading the first page
imageView = new ImageView(model.getImage(0));
System.out.print("1-imageView.getFitHeight(): "+imageView.getImage().getHeight()+"\n");
System.out.print("imageView.getFitWidth(): "+imageView.getImage().getWidth()+"\n");
currentPageDimensions = new PageDimensions(imageView.getImage().getWidth(), imageView.getImage().getHeight());
zoom.addListener(new InvalidationListener() {
#Override
public void invalidated(Observable arg0) {
//My problem is in this part of code
int width = (int) (imageView.getImage().getWidth() * zoom.get());
int height = (int) (imageView.getImage().getHeight() * zoom.get());
imageView.setFitWidth(width);
System.out.print("Largeur: "+ (width) +"px\n");
imageView.setFitHeight(height);
System.out.print("Hauteur: "+ height +"px\n");
//==================================================
}
});
imageView.preserveRatioProperty().set(true);
scrollPane.setPannable(true);
scrollPane.setStyle(scrollCssLayout);
scrollPane.setVbarPolicy(ScrollBarPolicy.AS_NEEDED);
scrollPane.setHbarPolicy(ScrollBarPolicy.AS_NEEDED);
scrollPane.setContent(imageView);
vbox.setStyle(cssLayout);
vbox.getChildren().add(scrollPane);
}
#FXML private void zoomIn() {
zoom.set(zoom.get()*1.1);
// System.out.print("zoom.get(): "+zoom.get()*100 +"%\n");
}
#FXML private void zoomOut() {
zoom.set(zoom.get()/1.1);
// System.out.print("zoom.get(): "+zoom.get()*100 +"%\n");
}
#FXML private void zoomFit() {
}
#FXML private void zoomWidth() {
}
private class PageDimensions {
private double width ;
private double height ;
PageDimensions(double width, double height) {
this.width = width ;
this.height = height ;
}
#Override
public String toString() {
return String.format("[%.1f, %.1f]", width, height);
}
}
}
PdfModel
package application;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.nio.file.Path;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.image.Image;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.pdmodel.common.PDRectangle;
import org.apache.pdfbox.rendering.PDFRenderer;
/**
* #author toru
*/
class PdfModel {
//private static final Logger logger = Logger.getLogger(PdfModel.class.getName());
private PDDocument document;
private PDFRenderer renderer;
Path chemin;
PdfModel() {
}
PdfModel(Path path) {
try {
chemin=path;
document = PDDocument.load(path.toFile());
renderer = new PDFRenderer(document);
} catch (IOException ex) {
throw new UncheckedIOException("PDDocument thorws IOException file=" + path, ex);
}
}
int nombreDePages() {
return document.getPages().getCount();
}
PDPage getPage (int num) {
PDPage page = document.getPage(num);
return page;
}
void fermer() {
try {
document.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
void setPath(Path pPays)
{
chemin = pPays;
System.out.println("On est dans la page pdfmodel");
System.out.println("Path: "+pPays);
}
Image getImage(int pageNumber) {
BufferedImage pageImage;
try {
pageImage = renderer.renderImage(pageNumber);
} catch (IOException ex) {
throw new UncheckedIOException("PDFRenderer throws IOException", ex);
}
return SwingFXUtils.toFXImage(pageImage, null);
}
}
ui.fxml
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.layout.VBox?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="10.0" minWidth="10.0" prefHeight="400.0" prefWidth="400.0" xmlns="http://javafx.com/javafx/8.0.171" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
<bottom>
<HBox prefHeight="50.0" prefWidth="400.0" BorderPane.alignment="CENTER">
<children>
<Button mnemonicParsing="false" onAction="#zoomIn" text="+">
<HBox.margin>
<Insets left="5.0" top="5.0" />
</HBox.margin>
</Button>
<Button mnemonicParsing="false" onAction="#zoomOut" text="-">
<HBox.margin>
<Insets left="5.0" top="5.0" />
</HBox.margin>
</Button>
<Button mnemonicParsing="false" onAction="#zoomFit" text="ZoomFit">
<HBox.margin>
<Insets left="5.0" top="5.0" />
</HBox.margin>
</Button>
<Button mnemonicParsing="false" onAction="#zoomWidth" text="ZoomWidth">
<HBox.margin>
<Insets left="5.0" top="5.0" />
</HBox.margin>
</Button>
</children>
</HBox>
</bottom>
<center>
<VBox fx:id="vbox" prefHeight="350.0" prefWidth="400.0" BorderPane.alignment="CENTER" />
</center>
</BorderPane>
Main.java
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;
/**
*#author toru
*/
public class Main extends Application {
#Override
public void start(Stage primaryStage) throws Exception {
final Parent parent = FXMLLoader.load(getClass().getResource("ui.fxml"));
primaryStage.setTitle("Zoom ImageView Demo ");
primaryStage.setScene(new Scene(parent,800, 600));
primaryStage.show();
}
public static void main(String[] args) {
launch(args);
}
}
Best regards
Use the two-parameter renderImage(page, scale) method. 1 is the default scale and is 72 dpi, 4 is 288 dpi which is usually pretty good. So I suggest you start with scale 4, and in a later step you increase when zooming (note that rendering may become slower with higher resolutions).
So a code example for your code would be
pageImage = renderer.renderImage(pageNumber, 4);
This question already has answers here:
The table cells are empty in my tableview. JavaFX + Scenebuilder
(2 answers)
Closed 4 years ago.
In my application Some of the columns in my table are populating like they should be the columns labeled Name Priority and BurstTime have the correct values being added but for some reason the other two ProcessID and State do not update with the values I am adding to my ArrayList.
It looks like my code should be working can anybody see something I have missed?
Here is my controller
package application;
import java.net.URL;
import java.util.ResourceBundle;
import java.io.File;
import java.util.ArrayList;
import java.util.Scanner;
import java.util.StringTokenizer;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.control.cell.PropertyValueFactory;
public class Controller implements Initializable {
private ArrayList<String> buf = new ArrayList<>();
protected ArrayList<PCB> array = new ArrayList<>();
protected ArrayList<Process> arrayP = new ArrayList<>();
ObservableList<Process> processData = FXCollections.observableArrayList();
#FXML
private Button SubmitButton;
#FXML
private Button LoadButton;
#FXML
private TextArea textArea;
#FXML
private TextField inputBox;
#FXML
private TableView<Process> ProcessTable;
#FXML
private TableColumn<Process, String> processIDP;
#FXML
private TableColumn<Process, String> processTypeP;
#FXML
private TableColumn<Process, String> priorityCodeP;
#FXML
private TableColumn<Process, String> burstTimeP;
#FXML
private TableColumn<Process, String> StatusCodeP;
#Override
public void initialize(URL url, ResourceBundle rb) {
processIDP.setCellValueFactory(new PropertyValueFactory<Process, String>("processIDP"));
processTypeP.setCellValueFactory(new PropertyValueFactory<Process, String>("processTypeP"));
priorityCodeP.setCellValueFactory(new PropertyValueFactory<Process, String>("priorityCodeP"));
burstTimeP.setCellValueFactory(new PropertyValueFactory<Process, String>("burstTimeP"));
StatusCodeP.setCellValueFactory(new PropertyValueFactory<Process, String>("StatusCodeP"));
Process p1 = new Process();
p1.setprocessIDP("22");
p1.setProcessTypeP ("Apname");
p1.setPriorityCodeP("1");
p1.setBurstTimeP ("13");
p1.setstatusCodeP("Tada");
arrayP.add(p1);
ProcessTable.getItems().addAll(arrayP.get(0));
ProcessTable.setItems(FXCollections.observableArrayList(arrayP));
Process p2 = new Process();
p2.setprocessIDP("24");
p2.setProcessTypeP ("Bpname");
p2.setBurstTimeP ("15");
p2.setPriorityCodeP("2");
arrayP.add(p2);
ProcessTable.getItems().addAll(arrayP.get(1));
// edit existing cell ?
arrayP.get(1).setPriorityCodeP("8");
arrayP.get(1).setstatusCodeP("This");
arrayP.get(1).setprocessIDP("TEST");
}
public ObservableList<Process> getProcessData() {
return processData;
}
#FXML
private TextField LoadProgram;
#FXML
private void handleButtonAction() {
textArea.appendText(inputBox.getText() + "\n");
StringTokenizer st1 = new StringTokenizer(inputBox.getText(), " ");
switch(st1.nextToken()) {
// case "proc": proc(); break;
case "mem": textArea.appendText("Memory: " + String.valueOf(Memory.getUsedMemory()) + "/" + String.valueOf(Memory.getTotalMemory()) + "\n"); break;
// case "exe": exe(); break;
// case "reset": reset(); break;
case "load": buf.add(inputBox.getText()) ;
// edit existing cell ?
arrayP.get(1).setPriorityCodeP("9");
ProcessTable.refresh();
break;
case "exit": System.exit(0); break;
case "clear": textArea.clear(); break;
default: break;
}
}
#FXML
private void handleLoadAction() {
File infile = new File("files/" + LoadProgram.getText() + ".txt");
if (infile.exists() == true ) {
textArea.appendText("Loading " + LoadProgram.getText() + "\n");
}
//call to read data here
else {
textArea.appendText("No Program named " + LoadProgram.getText() + " found \n");
}}
public class textLine {
private String infile;
private String cmd, value;
private Scanner input;
public void parseFile(String filename) {
this.infile = "files/" + filename + ".txt";
parseFile();
}
public void addbuf(String textline) {
buf.add(textline);
}
private void parseFile() {
buf.clear();
try {
File file = new File(infile);
if (file.exists() == true)
input = new Scanner(file);
while (input.hasNext()) {
buf.add(input.next());
}
} catch (Exception e) {
e.printStackTrace();
}
input.close();
}
}
}
Here is my class for Procsess
package application;
public class Process {
String processTypeP = "";
String priorityCodeP = "0";
int lineCodeP = 0;
String burstTimeP = "0";
String processIDP = "0";
String StatusCodeP = "0";
public Process (){}
public String getProcessTypeP() {
return processTypeP;
}
public void setProcessTypeP(String processTypeP) {
this.processTypeP = processTypeP;
}
public String getPriorityCodeP() {
return priorityCodeP;
}
public void setPriorityCodeP(String priorityCodeP) {
this.priorityCodeP = priorityCodeP;
}
public int getLineCodeP() {
return lineCodeP;
}
public void setLineCodeP(int lineCodeP) {
this.lineCodeP = lineCodeP;
}
public String getBurstTimeP() {
return burstTimeP;
}
public void setBurstTimeP(String burstTimeP) {
this.burstTimeP = burstTimeP;
}
public String getprocessIDP() {
return processIDP;
}
public void setprocessIDP(String processIDP) {
this.processIDP = processIDP;
}
public String getstatusCodeP() {
return StatusCodeP;
}
public void setstatusCodeP(String StatusCodeP) {
this.StatusCodeP = StatusCodeP;
}
}
Here is my main application
package application;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.stage.Stage;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
public class Main extends Application {
#Override
public void start(Stage primaryStage) {
try {
FXMLLoader loader = new FXMLLoader(Main.class.getResource("/Main.fxml"));
// Parent root = FXMLLoader.load(getClass().getResource("/Main.fxml"));
AnchorPane root = (AnchorPane) loader.load(Main.class.getResource("/application/Main.fxml"));
Scene scene = new Scene(root);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
primaryStage.setScene(scene);
primaryStage.show();
} catch(Exception e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
launch(args);
}
}
and my fxml file
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.layout.AnchorPane?>
<AnchorPane xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="application.Controller">
<children>
<TabPane layoutX="4.0" layoutY="4.0" prefHeight="700.0" prefWidth="900.0" tabClosingPolicy="UNAVAILABLE">
<tabs>
<Tab text="Processes">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0">
<children>
<TextField fx:id="inputBox" layoutX="14.0" layoutY="54.0" />
<Button fx:id="SubmitButton" layoutX="109.0" layoutY="94.0" mnemonicParsing="false" onAction="#handleButtonAction" text="Submit" />
<TextArea fx:id="textArea" layoutX="197.0" layoutY="14.0" prefHeight="105.0" prefWidth="493.0" />
<TableView fx:id="ProcessTable" layoutX="36.0" layoutY="157.0" prefHeight="430.0" prefWidth="654.0">
<columns>
<TableColumn fx:id="processIDP" prefWidth="75.0" text="ProccessID" />
<TableColumn fx:id="processTypeP" prefWidth="101.0" text="Name" />
<TableColumn fx:id="priorityCodeP" prefWidth="94.0" text="Priority" />
<TableColumn fx:id="StatusCodeP" prefWidth="119.0" text="State" />
<TableColumn fx:id="burstTimeP" prefWidth="100.0" text="BurstTime" />
</columns>
</TableView>
<TextField fx:id="LoadProgram" layoutX="712.0" layoutY="492.0" />
<Button fx:id="LoadProgramButton" layoutX="725.0" layoutY="531.0" mnemonicParsing="false" onAction="#handleLoadAction" text="Load External Program" />
</children></AnchorPane>
</content>
</Tab>
<Tab text="Scheduler">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
<Tab text="Memory">
<content>
<AnchorPane minHeight="0.0" minWidth="0.0" prefHeight="180.0" prefWidth="200.0" />
</content>
</Tab>
</tabs>
</TabPane>
</children>
</AnchorPane>
Try renaming your getter methods from getprocessIDP and getstatusCodeP to getProcessIDP and getStatusCodeP respectively (note the capital 'S' and 'P'). To avoid problems like this in the future it's a good habit to generate getters, setters and constructors with the IDE instead of doing it manually.
i am trying to transform my previous javafx program into an MVC machine. i actually do not have any compilation error neither do i have runtime errors. but when i run my login application i cannot see the database values in the combobox.
yes of course i can login, it works fine.
This are my codes for the combobox splited into LoginView, LoginController, and LoginModel:
package com.login;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.control.ComboBox;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
* Created by DELL PC on 7/25/2016.
*/
public class LoginModel {
Connection connection;
PreparedStatement preparedStatement = null;
ResultSet resultSet = null;
public LoginModel()
{
connection = SqliteConnection.connector();
if(connection == null)
{
System.exit(1);
}
}
public boolean isDBConnected()
{
try {
return !connection.isClosed();
} catch (SQLException e) {
e.printStackTrace();
return false;
}
}
public ComboBox fillCombobox()
{
try
{
final ObservableList options = FXCollections.observableArrayList();
String query = "SELECT role from admin";
preparedStatement = connection.prepareStatement(query);
resultSet = preparedStatement.executeQuery();
while(resultSet.next())
{
options.add(resultSet.getString("role"));
}
preparedStatement.close();
resultSet.close();
}
catch(SQLException ex)
{
Logger.getLogger(LoginModel.class.getName()).log(Level.SEVERE, null, ex);
}
return null;
}
public boolean isLogin(String user, String pass) throws SQLException
{
String query = "SELECT * FROM admin WHERE username = ? and password = ?";
try {
preparedStatement = connection.prepareStatement(query);
preparedStatement.setString(1, user);
preparedStatement.setString(2, pass);
resultSet = preparedStatement.executeQuery();
if(resultSet.next())
{
return true;
}
else
{
return false;
}
}catch(Exception e){
return false;
}
finally
{
preparedStatement.close();
resultSet.close();
}
}
}
code for Controller
package com.login;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.Scene;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.PasswordField;
import javafx.scene.control.TextField;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
import java.io.IOException;
import java.net.URL;
import java.sql.SQLException;
import java.util.ResourceBundle;
public class LoginController implements Initializable{
public LoginModel loginModel = new LoginModel();
#FXML
private TextField txtusername;
#FXML
private PasswordField pwpaswword;
#FXML
private Label isConnected;
#FXML
private ComboBox comboBox;
#Override
public void initialize(URL location, ResourceBundle resources) {
comboBox.getItems().contains(loginModel.fillCombobox());
if(loginModel.isDBConnected())
{
isConnected.setText("Connected");
}
else
{
isConnected.setText("Not Connected");
}
}
public void Login(ActionEvent event)
{
try {
if (loginModel.isLogin(txtusername.getText(), pwpaswword.getText()))
{
isConnected.setText("Login Successfully ");
((Node)event.getSource()).getScene().getWindow().hide();
Stage window = new Stage();
FXMLLoader loader = new FXMLLoader();
Pane root = loader.load(getClass().getResource("CivilStateView.fxml").openStream());
CivilStateController civilStateController = (CivilStateController)loader.getController();
civilStateController.getUser(txtusername.getText());
Scene scene = new Scene(root);
window.setTitle("Hello World");
window.setScene(scene);
window.show();
}
else
{
isConnected.setText("Login Unsuccessful");
}
} catch (SQLException e) {
isConnected.setText("Exception occurred:" + e);
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
the view is made with fxml:
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.*?>
<?import javafx.scene.text.*?>
<?import javafx.scene.control.*?>
<?import java.lang.*?>
<?import javafx.scene.layout.*?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.layout.GridPane?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Label?>
<AnchorPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="346.0" prefWidth="360.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="com.login.LoginController">
<children>
<Label fx:id="isConnected" layoutX="31.0" layoutY="30.0" prefHeight="36.0" prefWidth="150.0" text="Status" textFill="#f20f0f">
<font>
<Font size="18.0" />
</font>
</Label>
<TextField fx:id="txtusername" layoutX="26.0" layoutY="75.0" prefHeight="48.0" prefWidth="160.0" promptText="Username">
<font>
<Font size="19.0" />
</font>
</TextField>
<PasswordField fx:id="pwpaswword" layoutX="26.0" layoutY="137.0" prefHeight="48.0" prefWidth="160.0" promptText="Password">
<font>
<Font size="19.0" />
</font>
</PasswordField>
<ComboBox fx:id="comboBox" layoutX="26.0" layoutY="196.0" prefHeight="36.0" prefWidth="150.0">
<padding>
<Insets left="20.0" />
</padding>
</ComboBox>
<Button layoutX="26.0" layoutY="245.0" mnemonicParsing="false" onAction="#Login" prefHeight="36.0" prefWidth="68.0" text="Button" />
</children>
</AnchorPane>
I was able to create a test case that runs this though not using any of the DB interaction. The critical parts are:
public class LoginModel {
...
public ObservableList fillCombobox() {
ObservableList options = FXCollections.observableArrayList();
// replace this with your DB code to add the options.
for (int i = 1; i < 10; i++) {
options.add("Role " + i);
}
//
return options;
}
}
public class LoginController implements Initializable {
...
#Override
public void initialize(URL location, ResourceBundle resources) {
comboBox.setItems(loginModel.fillCombobox());
...
}
}
I keep on searching for an answer but still I can't find the right way to do it (or probably the mistakes in my codes). I am using javafx with scenebuilder. mySQL is the database that I am using. help please :(
package cedproject;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.Button;
import javafx.scene.input.MouseEvent;
import javafx.scene.layout.AnchorPane;
import java.sql.*;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.scene.Group;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableView;
import javafx.scene.control.TextField;
import javafx.scene.layout.HBox;
/**
* FXML Controller class
*
* #author My Lightstream
*/
public class FXMLController implements Initializable {
public java.sql.PreparedStatement ps;
public java.sql.ResultSet rs;
#FXML
private AnchorPane donationWindow;
//#FXML
//private TableView<?> tblView;
#FXML
TableView<userdata> tblView= new TableView<>();
#FXML
private TableColumn<?, ?> colOR;
#FXML
private TableColumn<?, ?> colAmount;
#FXML
private Button btnNew;
#FXML
private TextField txtSearch;
private static java.sql.Connection con;
private static Statement stat;
private PreparedStatement prep;
private ObservableList<userdata> data;
#FXML
private Button btnLoad;
#FXML
private Group gp;
// </userdata>
/**
#FXML
private Button btnNew;
#FXML
private AnchorPane donationWindow;
/**
* Initializes the controller class.
*/
#Override
public void initialize(URL url, ResourceBundle rb) {
try{
ps = new Connect().connectDatabase();
ps.execute();
tblView.getItems().setAll(this.data);
}catch(Exception e){
}
lagay();
}
public void lagay(){
try{
String query = "select * from receipt";
tblView.getItems().clear();
ps = con.prepareStatement("select * from receipt");
rs = ps.executeQuery(query);
}catch(Exception e){
System.out.println("mali ka shunga");
}
ObservableList<userdata> data = FXCollections.observableArrayList();
try{
while(rs.next()){
data.add(new userdata(
rs.getInt("ORNUM"),
rs.getInt("AMOUNT")
));}
}catch(Exception e){}
}
public void tableView()throws Exception{
tblView.getItems().clear();
rs = ps.executeQuery("SELECT ORNUM,AMOUNT FROM RECEIPT");
ObservableList<userdata> data = FXCollections.observableArrayList();
TableColumn column1 = new TableColumn("ORNUM");
column1.setCellValueFactory(new javafx.scene.control.cell.PropertyValueFactory<>("ornum"));
TableColumn column2 = new TableColumn("Amount");
column2.setCellValueFactory(new javafx.scene.control.cell.PropertyValueFactory<>("amount"));
tblView.getColumns().addAll(column1,column2);
tblView.getChildrenUnmodifiable();
}
#FXML
public void handleButtonAction2(ActionEvent event) {
}
#FXML
public void activated(MouseEvent event) {
}
private void onClicked(ActionEvent event) throws SQLException {
/* tblView.getItems().clear();
rs = ps.executeQuery("SELECT ORNUM,AMOUNT FROM RECEIPT");
ObservableList<userdata> data = FXCollections.observableArrayList();
TableColumn column1 = new TableColumn("ORNUM");
column1.setCellValueFactory(new PropertyValueFactory<>("ORNUM"));
TableColumn column2 = new TableColumn("Amount");
column2.setCellValueFactory(new PropertyValueFactory<>("Amount"));
tblView.getColumns().addAll(column1,column2);*/
ObservableList<userdata> data = FXCollections.observableArrayList();
try{ String query = "select * from receipt";
tblView.getItems().clear();
ps = con.prepareStatement(query);
rs = ps.executeQuery("SELECT * from receipt");
while(rs.next()){
tblView.getItems().add(new userdata(
rs.getInt("ORNUM"),
rs.getInt("AMOUNT")
));
tblView.setItems(data);
}
ps.close();
rs.close();
}catch(Exception e){
}
}
#FXML
private void onClicked(MouseEvent event) throws Exception {
System.out.println("gawin mo");
ObservableList<userdata> data = FXCollections.observableArrayList();
System.out.println("ginawa");
tableView();
try{
String query = "select * from receipt";
tblView.getItems().clear();
ps = new Connect().connectDatabase();
ps = new Connect().connectDatabase();
rs = ps.executeQuery(query);
while(rs.next()){
tblView.getItems().add(new userdata(
rs.getInt("ORNUM"),
rs.getInt("AMOUNT")
));
tblView.setItems(data);
}
}catch(Exception e){
System.out.print("asdqweasd");
}
}
/**
*
* #param event
*/
/* #FXML
public void konekplis(SortEvent<C> event) {
}*/
}
package cedproject;
import javafx.beans.property.DoubleProperty;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleDoubleProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;
/**
*enter code here
* #author My Lightstream
*/
public class userdata {
public SimpleIntegerProperty Ornum;
public SimpleIntegerProperty Amount;
public userdata(Integer ornum, Integer amount) {
this.Ornum = new SimpleIntegerProperty(ornum);
this.Amount = new SimpleIntegerProperty(amount);
}
userdata(String string) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
userdata(String string, String string0, String string1, String string2, String string3, String string4) {
throw new UnsupportedOperationException("Not supported yet."); //To change body of generated methods, choose Tools | Templates.
}
public Integer getOrnum() {
return Ornum.get();
}
public Integer getAmount() {
return Amount.get();
}
public void setOrnum(Integer ornum) {
this.Ornum.set(ornum);
}
public void setAmount(Integer amount) {
this.Amount.set(amount);
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.scene.effect.*?>
<?import java.lang.*?>
<?import java.net.*?>
<?import java.util.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<AnchorPane id="AnchorPane" fx:id="donationWindow" onDragDetected="#activated" prefHeight="482.0" prefWidth="696.0" styleClass="mainFxmlClass" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1" fx:controller="cedproject.FXMLController">
<stylesheets>
<URL value="#fxml.css" />
</stylesheets>
<children>
<AnchorPane layoutY="8.0" prefHeight="482.0" prefWidth="696.0" AnchorPane.bottomAnchor="0.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0" AnchorPane.topAnchor="0.0">
<children>
<TableView fx:id="tblView" layoutX="21.0" layoutY="87.0" prefHeight="181.0" prefWidth="655.0">
<columns>
<TableColumn fx:id="colOR" prefWidth="326.0" text="OR Number" />
<TableColumn fx:id="colAmount" prefWidth="325.0" text="Amount" />
</columns>
</TableView>
<Button fx:id="btnNew" layoutX="500.0" layoutY="35.0" mnemonicParsing="false" onAction="#handleButtonAction2" prefHeight="25.0" prefWidth="78.0" text="NEW" />
<Button layoutX="587.0" layoutY="35.0" mnemonicParsing="false" prefHeight="25.0" prefWidth="78.0" text="EDIT" />
<TextField fx:id="txtSearch" layoutX="40.0" layoutY="35.0" prefHeight="25.0" prefWidth="204.0" promptText="Search" />
<TextArea editable="false" layoutX="19.0" layoutY="336.0" prefHeight="132.0" prefWidth="655.0">
<effect>
<DropShadow height="14.0" radius="6.5" width="14.0" />
</effect>
</TextArea>
<Label layoutX="26.0" layoutY="305.0" prefHeight="17.0" prefWidth="68.0" text="Description:" />
<Button fx:id="btnLoad" layoutX="424.0" layoutY="35.0" mnemonicParsing="false" onMouseClicked="#onClicked" prefHeight="25.0" prefWidth="68.0" text="Load" />
<Group fx:id="gp" />
</children>
<cursor>
<Cursor fx:constant="DEFAULT" />
</cursor>
</AnchorPane>
</children>
</AnchorPane>
Please help :(
I am working on a new GUI client and we are considering using JavaFX. I was wondering if anyone has a suggestion regarding making a draggable ToolWindow:
(Customer window) in the example. This mini-window should be able to get minimized and dragged out of the parent window, and docked back to it. I really do not want to use netbeans platform (or eclipse or swing for that matter).
You just have to create a custom pane for that:
The complete example is available on gist.
CustomPane.java
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.fxml.FXML;
import javafx.fxml.FXMLLoader;
import javafx.fxml.Initializable;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.layout.AnchorPane;
import javafx.scene.layout.Pane;
import javafx.scene.shape.Rectangle;
public class CustomPane extends AnchorPane implements Initializable {
#FXML Button closePane;
#FXML Button minPane;
#FXML Label title;
#FXML Pane contentPane;
#FXML Rectangle separator;
private boolean restoreFlag = false;
private double prefX;
private double prefY;
public CustomPane(String title){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
"CustomPane.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
this.title.setText(title);
setButtonsLayout();
setStandardLayout();
}
public CustomPane(String title, double y, double x){
FXMLLoader fxmlLoader = new FXMLLoader(getClass().getResource(
"CustomPane.fxml"));
fxmlLoader.setRoot(this);
fxmlLoader.setController(this);
try {
fxmlLoader.load();
} catch (Exception exception) {
throw new RuntimeException(exception);
}
this.title.setText(title);
this.setPrefSize(x, y);
setButtonsLayout();
setStandardLayout();
restoreRoot();
}
#Override
public void initialize(URL location, ResourceBundle resources) {
closePane.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
setInvisible();
}
});
minPane.setOnAction(new EventHandler<ActionEvent>(){
#Override
public void handle(ActionEvent event) {
if(restoreFlag){
restoreFlag = false;
minPane.setText("_");
restoreRoot();
}
else{
restoreFlag = true;
minPane.setText("▭");
minimizeRoot();
}
}
});
}
protected void minimizeRoot() {
this.setPrefSize(prefX/2, title.getPrefHeight() + 5.0);
separator.setWidth(prefX/2 + 5);
this.setLayoutX(0);
this.setLayoutY(prefY-40);
setButtonsLayout();
contentPane.setVisible(false);
}
protected void restoreRoot() {
this.setPrefSize(prefX, prefY);
separator.setWidth(prefX);
contentPane.setVisible(true);
this.setLayoutX(0);
this.setLayoutY(0);
setButtonsLayout();
}
private void setStandardLayout() {
prefX = this.getPrefHeight();
prefY = this.getPrefWidth()-50;
}
public void setButtonsLayout(){
closePane.setLayoutX(this.getPrefWidth()-30);
minPane.setLayoutX(this.getPrefWidth()-55);
}
public void setInvisible(){
this.setVisible(false);
}
public ObservableList<Node> getContent(){
return contentPane.getChildren();
}
}
<?xml version="1.0" encoding="UTF-8"?>
<?import java.lang.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>
<?import javafx.scene.shape.*?>
customPane.fxml
<fx:root prefHeight="400.0" prefWidth="400.0"
type="javafx.scene.layout.AnchorPane" xmlns="http://javafx.com/javafx/8"
xmlns:fx="http://javafx.com/fxml/1">
<children>
<Rectangle fx:id="separator" arcHeight="5.0" arcWidth="5.0" fill="WHITE"
height="33.0" layoutY="1.0" stroke="BLACK" strokeType="INSIDE" width="600.0" />
<Button fx:id="closePane" layoutX="573.0" layoutY="6.0"
mnemonicParsing="false" text="X" />
<Button fx:id="minPane" layoutX="545.0" layoutY="6.0"
mnemonicParsing="false" text="__" />
<Label fx:id="title" layoutX="14.0" layoutY="12.0" text="Title" />
<Pane fx:id="contentPane" layoutY="34.0" prefHeight="366.0"
prefWidth="600.0" />
</children>
</fx:root>