Seminár z programovania v sieťach
Téma 1: Java FX »
zdroj: Java FX 8 tutorial
1) Čo potrebujeme
2) Konfigurácia Eclipse
name: e(fx)clipse
location: http://download.eclipse.org/efxclipse/updates-released/2.0.0/site
zaškrtnúť e(fx)clipse - install, doinštalovať a reštartovať
Ďalej potrebujeme povedať Eclipsu aby používal JDK 8 a kde nájde Scene Builder
Tu nastavíme aby sa defaultne používalo jre1.8.0_60 (teda nastavíme k nemu cestu a ostatné odstránime)
Tu nastavíme verziu compilera na 1.8
Nastavíme si cestu k Scene Builder-u
3) Vytvorenie projektu a tvorba používateľského prostredia
4) Naplnenie tabuľky údajmi
medzi inštančné premenné pridáme private ObservableList
medzi metódy pridáme konštruktor a novú metódu zdroj tu
PersonOverviewController controller = loader.getController();
controller.setMainApp(this);
5) Interakcia s užívateľom
private void showPersonDetails(Person person) { if (person != null) { // Fill the labels with info from the person object. firstNameLabel.setText(person.getFirstName()); lastNameLabel.setText(person.getLastName()); streetLabel.setText(person.getStreet()); postalCodeLabel.setText(Integer.toString(person.getPostalCode())); cityLabel.setText(person.getCity()); birthdayLabel.setText(DateUtil.format(person.getBirthday())); } else { // Person is null, remove all the text. firstNameLabel.setText(""); lastNameLabel.setText(""); streetLabel.setText(""); postalCodeLabel.setText(""); cityLabel.setText(""); birthdayLabel.setText(""); } }
private void initialize() { // Initialize the person table with the two columns. firstNameColumn.setCellValueFactory(cellData -> cellData.getValue() .firstNameProperty()); lastNameColumn.setCellValueFactory(cellData -> cellData.getValue() .lastNameProperty()); showPersonDetails(null); // Listen for selection changes and show the person details when // changed. personTable.getSelectionModel().selectedItemProperty() .addListener((observable, oldValue, newValue) -> showPersonDetails(newValue)); }
@FXML private void handleDeletePerson() { int selectedIndex = personTable.getSelectionModel().getSelectedIndex(); if (selectedIndex >= 0) { personTable.getItems().remove(selectedIndex); } else { // Nothing selected. Alert alert = new Alert(AlertType.WARNING); alert.initOwner(mainApp.getPrimaryStage()); alert.setTitle("No Selection"); alert.setHeaderText("No Person Selected"); alert.setContentText("Please select a person in the table."); alert.showAndWait(); } }
public boolean showPersonEditDialog(Person person) { try { // Load the fxml file and create a new stage for the popup dialog. FXMLLoader loader = new FXMLLoader(); loader.setLocation(MainApp.class.getResource("PersonEditLayout.fxml")); AnchorPane page = (AnchorPane) loader.load(); // Create the dialog Stage. Stage dialogStage = new Stage(); dialogStage.setTitle("Edit Person"); dialogStage.initModality(Modality.WINDOW_MODAL); dialogStage.initOwner(primaryStage); Scene scene = new Scene(page); dialogStage.setScene(scene); // Set the person into the controller. PersonEditLayoutController controller = loader.getController(); controller.setDialogStage(dialogStage); controller.setPerson(person); // Show the dialog and wait until the user closes it dialogStage.showAndWait(); return controller.isOkClicked(); } catch (IOException e) { e.printStackTrace(); return false; } }
@FXML private void handleNewPerson() { Person tempPerson = new Person(); boolean okClicked = mainApp.showPersonEditDialog(tempPerson); if (okClicked) { mainApp.getPersonData().add(tempPerson); } } @FXML private void handleEditPerson() { Person selectedPerson = personTable.getSelectionModel().getSelectedItem(); if (selectedPerson != null) { boolean okClicked = mainApp.showPersonEditDialog(selectedPerson); if (okClicked) { showPersonDetails(selectedPerson); } } else { // Nothing selected. Alert alert = new Alert(AlertType.WARNING); alert.initOwner(mainApp.getPrimaryStage()); alert.setTitle("No Selection"); alert.setHeaderText("No Person Selected"); alert.setContentText("Please select a person in the table."); alert.showAndWait(); } }
6) Export do spustiteľného .jar súboru
pri id="fxant" pridáme ako 3.riadok medzi tag filelist tento riadok <file name="${basedir}"/>
pri id="appRes" pridáme ako 3.riadok <fx:fileset dir="dist" includes="resources/**"/>
pri id="fxApplication" pridáme ako 3.riadok version="1.0"
Téma 2: SVG »
zdroje:
http://rvlasveld.github.io/blog/2013/07/02/creating-interactive-graphs-with-svg-part-1/
SVG (scalable vector graphics)
Výhody
Vkladanie na stránku
Základné útvary v SVG a ich použitie
Kontajner na zoskupovanie útvarov
<g>
.
.
.
</g>
Základné atribúty útvarov
<circle stroke="red" />
<rect x="80" y="60" width="250" height="250" rx="20"/>
- x, y -> súradnica ľavého horného okraja obdĺžnika - rx, ry -> zaokrúhlenie rohov obdĺžnika v x-ovej a y-ovej osi
- width, height -> rozmery obdĺžnika
<line x1="0" y1="0" x2="200" y2="200" />
- x1, y1 -> súradnica začiatočného vrchola - x2, y2 -> súradnica koncového vrchola
<path d="M150 0 L75 200 L225 200 Z" />
- d -> dáta o ceste, aká sa má nakresliť - M x, y-> presunúť kresliace pero na súradnicu (move to)
- L x, y-> nakresliť čiaru k danej súradnici (line to)
- Z -> uzavrieť cestu
Príklad
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN"
"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg xmlns="http://www.w3.org/2000/svg"
width="467" height="462">
<rect x="80" y="60" width="250" height="250" rx="20"
style="fill:#ff0000; stroke:#000000;stroke-width:2px;" />
<rect x="140" y="120" width="250" height="250" rx="40"
style="fill:#0000ff; stroke:#000000; stroke-width:2px;
fill-opacity:0.7;" />
</svg>
Grafy v SVG
Chceme za pomoci html, svg a css vytvoriť graf podobný tomuto: graf, ktorý bude zobrazovať hodnoty RTT z pingu na vybraný server (napr. google.sk)."Súčiastky" nášho grafu budú
- mriežka prerušovaných čiar, pomáhajúcich interpretovať hodnoty dátových bodov
- dátové body, každý pozostávajúci z času odoslania príkazu ping a získanej hodnoty RTT
- textové popisky určujúce rozsah a hodnoty grafu
- oblasť pod dátovými bodmi
Mriežka
- vytvoríme si súbor graf.html kód tu, do ktorého vložíme element svg v ktorom vytvoríme pomocou útvaru line mriežku
- okrem toho si vytvoríme súbor graf.css, kde budeme definovať vzhľad komponentov (ide to aj priamo v kóde ale nakoľko máme veľa komponentov, bude to pohodlnejšie), tam si nateraz nakopírujeme kód ktorý nastaví pozadie komponentu a vzhľad mriežky:
svg {
background-color: #000000;
}
svg.graph {
height: 500px;
width: 800px;
}
svg.graph .grid {
stroke: yellow;
stroke-dasharray: 1 2;
stroke-width: 1;
}
svg.graph .grid.double {
stroke-opacity: 0.4;
}
- potom nastavíme v html súbore v časti head, aby bolo toto css použité
<link rel="stylesheet" href="graph.css" type="text/css" media="screen" />
Dátové body
- nateraz si do html súboru nakopírujeme napevno zopár dátových bodov:
<g class="first_set points" data-setname="Our first data set">
<circle cx="113" cy="374" data-value="5" r="5"></circle>
<circle cx="259" cy="316" data-value="20" r="5"></circle>
<circle cx="405" cy="350" data-value="10" r="5"></circle>
<circle cx="551" cy="273" data-value="30" r="5"></circle>
<circle cx="697" cy="150" data-value="62" r="5"></circle>
</g>
- okrem toho si v css zadefinujeme vzhľad dátových bodov:
svg.graph .points {
stroke: white;
stroke-width: 3;
}
svg.graph .first_set {
fill: #0000ff;
}
Labely
- určíme si rozsah nášho grafu a jeho hodnôt a podľa nich zadáme nasledovné labely:
<g class="labels x-labels">
<text x="113" y="430">10:00</text>
<text x="259" y="430">10:05</text>
<text x="405" y="430">10:10</text>
<text x="551" y="430">10:15</text>
<text x="697" y="430">10:20</text>
</g>
<g class="labels y-labels">
<text x="80" y="45">90</text>
<text x="80" y="103">75</text>
<text x="80" y="161">60</text>
<text x="80" y="219">45</text>
<text x="80" y="277">30</text>
<text x="80" y="335">15</text>
<text x="80" y="393">0</text>
<text x="110" y="15">RTT čas v MS</text>
</g>
- v css dodefinujeme vzhľad labelov:
svg.graph .labels {
stroke: white;
font-family: Arial;
font-size: 14px;
kerning: 1;
}
svg.graph .labels.x-labels {
text-anchor: middle;
}
svg.graph .labels.y-labels {
text-anchor: end;
}
Oblasť pod dátovými bodmi
- s využitím útvaru path pospájame dátové body a vytvoríme z nich a rohov grafu polygón:
<g class="surfaces">
<path class="first_set" d="M113,390 L113,374 L259,316 L405,350 L551,273 L697,150 L697,390 Z"></path>
</g>
- do css pridáme kód pre vzhľad tejto časti:
svg.graph .surfaces {
fill-opacity: 0.5;
}
Teraz máme graf hotový, je ale čisto statický. Teraz by sme ho chceli "oživiť" tak, že budeme mať možnosť do neho vložiť novú hodnotu a graf sa sám aktualizuje (resp. vypadne z neho najstaršia hodnota a ostatné sa posunú).
Najprv si teda vytvoríme komponenty, cez ktoré budeme vkladať nové hodnoty:
<br/>
Čas odoslania pingu:<br/>
<input id="cas" type="time" name="date">
<br>
RTT čas:<br/>
<input id="hodnota" type="number" name="time" min="0" max="90">
<br/>
<input id="button1" type="button" value="Pridať novú hodnotu" onclick="addNew()" />
Nakoniec ešte pridáme skript, ktorý zariadi pridanie novej hodnoty do grafu:
<script>
function addNew() {
document.getElementById("lbl1").textContent=document.getElementById("lbl2")
.textContent;
document.getElementById("point1").setAttribute("cy",document.getElementById("point2")
.getAttribute("cy"));
document.getElementById("lbl2").textContent=document.getElementById("lbl3")
.textContent;
document.getElementById("point2").setAttribute("cy",document.getElementById("point3")
.getAttribute("cy"));
document.getElementById("lbl3").textContent=document.getElementById("lbl4")
.textContent;
document.getElementById("point3").setAttribute("cy",document.getElementById("point4")
.getAttribute("cy"));
document.getElementById("lbl4").textContent=document.getElementById("lbl5")
.textContent;
document.getElementById("point4").setAttribute("cy",document.getElementById("point5")
.getAttribute("cy"));
document.getElementById("lbl5").textContent=document.getElementById("cas").value;
var v = "390.0";
var v2 = "3.88";
var hodnota= ""+document.getElementById("hodnota").value;
document.getElementById("point5").setAttribute("cy",v-(hodnota*v2));
document.getElementById("line").setAttribute("d","M113,390 "+"L"
+document.getElementById("point1").getAttribute("cx")+","
+document.getElementById("point1").getAttribute("cy")
+" L"+document.getElementById("point2").getAttribute("cx")+","
+document.getElementById("point2").getAttribute("cy")+" L"
+document.getElementById("point3").getAttribute("cx")+","
+document.getElementById("point3").getAttribute("cy")
+" L+"+document.getElementById("point4").getAttribute("cx")+","
+document.getElementById("point4").getAttribute("cy")+" L"
+document.getElementById("point5").getAttribute("cx")+","
+document.getElementById("point5").getAttribute("cy")+" L697,390 Z");
}
</script>