diff --git a/.travis.yml b/.travis.yml deleted file mode 100644 index dff5f3a..0000000 --- a/.travis.yml +++ /dev/null @@ -1 +0,0 @@ -language: java diff --git a/ClockJFX.jar b/ClockJFX.jar new file mode 100644 index 0000000..cc7a27a Binary files /dev/null and b/ClockJFX.jar differ diff --git a/META-INF/MANIFEST.MF b/META-INF/MANIFEST.MF new file mode 100644 index 0000000..440fa71 --- /dev/null +++ b/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: sample.Main + diff --git a/automata.jar b/automata.jar new file mode 100644 index 0000000..c80d080 Binary files /dev/null and b/automata.jar differ diff --git a/automata/src/sample/Controller.java b/automata/src/sample/Controller.java new file mode 100644 index 0000000..df7feaa --- /dev/null +++ b/automata/src/sample/Controller.java @@ -0,0 +1,143 @@ +package sample; + +import javafx.collections.FXCollections; +import javafx.collections.ObservableList; +import javafx.fxml.FXML; +import javafx.fxml.Initializable; +import javafx.scene.control.*; +import javafx.scene.control.cell.PropertyValueFactory; +import sample.automata.Automata; +import sample.automata.Product; + +import java.net.URL; +import java.util.ArrayList; +import java.util.List; +import java.util.ResourceBundle; + +public class Controller implements Initializable { + + @FXML + private Button btnOn; + @FXML + private Button btnOff; + @FXML + private Button btnCancel; + @FXML + private Button btnCoin; + @FXML + private Button btnMenu1; + @FXML + private Button btnMenu2; + @FXML + private Button btnMenu3; + @FXML + private Button btnMenu4; + @FXML + private Button btnMenu5; + @FXML + private Button btnCoin1; + @FXML + private Button btnCoin2; + @FXML + private Button btnCoin3; + + @FXML + private TextArea taState; + + @FXML + private TextField tfCash; + @FXML + private TextField tfChange; + + @FXML + private TableView tblvMenu; + @FXML + private TableColumn tcProdNumber; + @FXML + private TableColumn tcProdName; + @FXML + private TableColumn tcProdPrice; + + @FXML + private ProgressBar pbCookingProgress; + + private Automata automata; + + @Override + public void initialize(URL url, ResourceBundle resourceBundle) { + automata = new Automata(); + automata.getMenufromJSON(); + getAutomataState(); + tcProdNumber.setCellValueFactory(new PropertyValueFactory("prodNumber")); + tcProdName.setCellValueFactory(new PropertyValueFactory("prodName")); + tcProdPrice.setCellValueFactory(new PropertyValueFactory("prodPrice")); + } + + private void getAutomataState(){ + taState.textProperty().unbind(); + taState.setText(automata.getState().toString()); + tfCash.setText(automata.getStrCash()); + tfChange.setText(automata.getStrChange()); + } + + private void setMenu(List products){ + ObservableList olProducts = FXCollections.observableArrayList(products); + tblvMenu.setItems(olProducts); + } + + public void coinClick(int coinValue){ + automata.coin(coinValue); + getAutomataState(); + } + + public void setBtnMenu(int prodNumber){ + automata.choice(prodNumber); + pbCookingProgress.progressProperty().bind(automata.getProcess().progressProperty()); + taState.textProperty().bind(automata.getProcess().messageProperty()); + tfCash.setText(automata.getStrCash()); + tfChange.setText(automata.getStrChange()); + } + + public void onClick(){ + automata.on(); + getAutomataState(); + setMenu(automata.getProducts()); + } + + public void offClick(){ + automata.off(); + getAutomataState(); + setMenu(new ArrayList()); + } + + public void coin1Click(){ + coinClick(5); + } + public void coin2Click(){ + coinClick(10); + } + public void coin3Click(){ + coinClick(50); + } + + public void cancelClick(){ + automata.cancel(); + getAutomataState(); + } + + public void setBtnMenu1(){ + setBtnMenu(0); + } + public void setBtnMenu2(){ + setBtnMenu(1); + } + public void setBtnMenu3(){ + setBtnMenu(2); + } + public void setBtnMenu4(){ + setBtnMenu(3); + } + public void setBtnMenu5(){ + setBtnMenu(4); + } +} diff --git a/automata/src/sample/Main.java b/automata/src/sample/Main.java new file mode 100644 index 0000000..d119dca --- /dev/null +++ b/automata/src/sample/Main.java @@ -0,0 +1,31 @@ +package sample; + +import javafx.application.Application; +import javafx.fxml.FXMLLoader; +import javafx.scene.Parent; +import javafx.scene.Scene; +import javafx.stage.Stage; + +import java.io.File; +import java.io.InputStream; +import java.net.URL; + +public class Main extends Application { + protected static String jsnFdir; + + @Override + public void start(Stage primaryStage) throws Exception{ + Parent root = FXMLLoader.load(getClass().getResource("sample.fxml")); + primaryStage.setTitle("Automata coffee"); + primaryStage.setScene(new Scene(root)); + primaryStage.show(); + } + + + public static void main(String[] args) { + launch(args); + } + + + +} diff --git a/automata/src/sample/automata/Automata.java b/automata/src/sample/automata/Automata.java new file mode 100644 index 0000000..1ed20d1 --- /dev/null +++ b/automata/src/sample/automata/Automata.java @@ -0,0 +1,192 @@ +package sample.automata; + +import org.apache.commons.io.FileUtils; +import org.apache.commons.io.IOUtils; +import org.json.JSONArray; +import org.json.JSONObject; +import sample.processes.CookingProcess; +import sample.processes.NeedCoinProcess; +import sample.processes.Process; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.net.URL; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; + +public class Automata { + private STATES state; + private double cash; + private double change; + private String strCash; + private String strChange; + private ArrayList products; + private int prodNumber; + private Process process; + private String jsonFileDirection; + + //constructor + public Automata() { + this.state = STATES.OFF; + this.cash = 0.0; + this.change = 0.0; + this.strCash = ""; + this.strChange = ""; + this.products = new ArrayList<>(); + this.process = new CookingProcess(); + this.jsonFileDirection = jsonFileDirection; + } + + //getters + public ArrayList getProducts(){ + return this.products; + } + public STATES getState(){ + return this.state; + } + public String getStrCash() { return this.strCash; } + public String getStrChange(){ return this.strChange; } + public Process getProcess(){ return this.process; } + + //setters + public void setState(STATES state){ this.state = state; } + public void setCash(double value){ + this.cash += value; + this.strCash = Double.toString(this.cash); + } + public void setChange(double value){ + this.change += value; + this.strChange = Double.toString(this.change); + } + public void setJsonFileDirection(String jsonFileDirection){ + this.jsonFileDirection = jsonFileDirection; + } + + //methods + private double getProdPrice(){ + return products.get(this.prodNumber).getProdPrice(); + } + + public void on(){ + if (this.state == STATES.OFF) { + setState(STATES.WAIT); + setCash(-this.cash); + setChange(-this.change); + } + } + + public void off(){ + if (this.cash == 0){ + setState(STATES.OFF); + this.strCash = ""; + this.strChange = ""; + } + } + + public void coin(double coinValue){ + if (this.state == STATES.WAIT || this.state == STATES.NEEDCOIN){ + setState(STATES.ACCEPT); + setCash(coinValue); + } + else if (this.state == STATES.ACCEPT){ + setCash(coinValue); + } + else{ + setChange(coinValue); + } + } + + public void cancel(){ + if (this.state == STATES.ACCEPT || this.state == STATES.CHECK || this.state == STATES.NEEDCOIN){ + setState(STATES.WAIT); + setChange(this.cash); + setCash(-this.cash); + } + } + + public void choice(int prodNumber){ + if (this.state == STATES.ACCEPT || this.state == STATES.WAIT) { + setState(STATES.CHECK); + setChange(-this.change); + this.prodNumber = prodNumber; + this.check(); + } + } + + private void check(){ + if (this.cash < this.getProdPrice()) + this.needCoin(); + else + this.cook(); + } + + private void needCoin(){ + setState(STATES.NEEDCOIN); + this.process = new NeedCoinProcess(); + Thread thread = new Thread(this.process); + thread.setDaemon(true); + thread.start(); + } + + private void cook(){ + setState(STATES.COOK); + this.process = new CookingProcess(); + Thread thread = new Thread(this.process); + thread.setDaemon(true); + thread.start(); + this.finish(); + } + + private void finish(){ + if (this.state == STATES.COOK) { + setState(STATES.WAIT); + setChange(this.cash - this.getProdPrice()); + setCash(-this.cash); + } + } + + public void getMenufromJSON() { + //File jsfile = new File("./products_and_prices.json"); + File jsfile = this.getResourceAsFile(); + try { + String content = FileUtils.readFileToString(jsfile, "utf-8"); + JSONObject jsList = new JSONObject(content); + JSONArray jsProducts = (JSONArray) jsList.get("products"); + for (Object obj : jsProducts) { + int prodNumber = Integer.parseInt(((JSONObject) obj).get("number").toString()); + String prodName = ((JSONObject) obj).get("name").toString(); + double prodPrice = Double.parseDouble(((JSONObject) obj).get("price").toString()); + Product product = new Product(prodNumber, prodName, prodPrice); + this.products.add(product); + } + } + catch (IOException e) { + } + } + + public File getResourceAsFile() { + try { + InputStream inStream = ClassLoader.getSystemClassLoader() + .getResourceAsStream("sample/products_and_prices.json"); + if (inStream == null) { + return null; + } + File tempFile = File.createTempFile(String.valueOf(inStream.hashCode()), ".tmp"); + tempFile.deleteOnExit(); + + try (FileOutputStream outStream = new FileOutputStream(tempFile)) { + byte[] buffer = new byte[1024]; + int bytesRead; + while ((bytesRead = inStream.read(buffer)) != -1) { + outStream.write(buffer, 0, bytesRead); + } + } + return tempFile; + } catch (IOException e) { + e.printStackTrace(); + return null; + } + } +} \ No newline at end of file diff --git a/automata/src/sample/automata/Product.java b/automata/src/sample/automata/Product.java new file mode 100644 index 0000000..b3a4222 --- /dev/null +++ b/automata/src/sample/automata/Product.java @@ -0,0 +1,17 @@ +package sample.automata; + +public class Product { + private int prodNumber; + private String prodName; + private double prodPrice; + + public Product(int prodNumber, String prodName, double prodPrice) { + this.prodNumber = prodNumber; + this.prodName = prodName; + this.prodPrice = prodPrice; + } + + public int getProdNumber() {return prodNumber;} + public String getProdName() {return prodName;} + public double getProdPrice() {return prodPrice;} +} \ No newline at end of file diff --git a/automata/src/sample/automata/STATES.java b/automata/src/sample/automata/STATES.java new file mode 100644 index 0000000..cb444ab --- /dev/null +++ b/automata/src/sample/automata/STATES.java @@ -0,0 +1,11 @@ +package sample.automata; + +public enum STATES { + OFF, + WAIT, + ACCEPT, + CHECK, + COOK, + NEEDCOIN, + READY +} \ No newline at end of file diff --git a/automata/src/sample/image.jpg b/automata/src/sample/image.jpg new file mode 100644 index 0000000..0842365 Binary files /dev/null and b/automata/src/sample/image.jpg differ diff --git a/automata/src/sample/processes/CookingProcess.java b/automata/src/sample/processes/CookingProcess.java new file mode 100644 index 0000000..cff8e49 --- /dev/null +++ b/automata/src/sample/processes/CookingProcess.java @@ -0,0 +1,41 @@ +package sample.processes; + +import sample.automata.STATES; + +public class CookingProcess extends Process { + + protected final int cookingMaxTime = 10; + protected final int timePart = 500; + + @Override + public Void call() { + cooking(); + return null; + } + + protected void cooking(){ + updateMessage(STATES.COOK.toString()); + for (int i = 0; i <= cookingMaxTime; i++) { + this.updateProgress(i, cookingMaxTime); + try { + Thread.sleep(timePart); + } catch (InterruptedException interrupted) { + System.out.println("Ошибка приготовления"); + return; + } + } + this.updateProgress(0, 0); + for (int i = 0; i < 4; i++) { + try { + updateMessage(STATES.READY.toString()); + Thread.sleep(timePart); + updateMessage(""); + Thread.sleep(timePart); + } catch (InterruptedException interrupted) { + System.out.println("Ошибка приготовления"); + return; + } + } + updateMessage(STATES.WAIT.toString()); + } +} \ No newline at end of file diff --git a/automata/src/sample/processes/NeedCoinProcess.java b/automata/src/sample/processes/NeedCoinProcess.java new file mode 100644 index 0000000..2734c7a --- /dev/null +++ b/automata/src/sample/processes/NeedCoinProcess.java @@ -0,0 +1,15 @@ +package sample.processes; + +import sample.automata.STATES; + +public class NeedCoinProcess extends Process { + @Override + public Void call() { + needCoin(); + return null; + } + + protected void needCoin(){ + updateMessage(STATES.NEEDCOIN.toString()); + } +} \ No newline at end of file diff --git a/automata/src/sample/processes/Process.java b/automata/src/sample/processes/Process.java new file mode 100644 index 0000000..fa5ac8f --- /dev/null +++ b/automata/src/sample/processes/Process.java @@ -0,0 +1,7 @@ +package sample.processes; + +import javafx.concurrent.Task; + +public abstract class Process extends Task { + +} diff --git a/automata/src/sample/products_and_prices.json b/automata/src/sample/products_and_prices.json new file mode 100644 index 0000000..0890950 --- /dev/null +++ b/automata/src/sample/products_and_prices.json @@ -0,0 +1,30 @@ +{ + "products" : + [ + { + "number" : 1 , + "name" : "Эспрессо", + "price" : 40 + }, + { + "number" : 2 , + "name" : "Американо", + "price" : 30 + }, + { + "number" : 3 , + "name" : "Латте", + "price" : 50 + }, + { + "number" : 4 , + "name" : "Шоколад", + "price" : 50 + }, + { + "number" : 5 , + "name" : "Чай", + "price" : 15 + } + ] +} \ No newline at end of file diff --git a/automata/src/sample/sample.fxml b/automata/src/sample/sample.fxml new file mode 100644 index 0000000..f0aebad --- /dev/null +++ b/automata/src/sample/sample.fxml @@ -0,0 +1,219 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/clock/src/sample/Clock.jpg b/clock/src/sample/Clock.jpg new file mode 100644 index 0000000..35905ae Binary files /dev/null and b/clock/src/sample/Clock.jpg differ diff --git a/clock/src/sample/Main.java b/clock/src/sample/Main.java new file mode 100644 index 0000000..96e3829 --- /dev/null +++ b/clock/src/sample/Main.java @@ -0,0 +1,190 @@ +package sample; + +import javafx.animation.*; +import javafx.application.Application; +import javafx.scene.Group; +import javafx.scene.Scene; +import javafx.scene.control.Label; +import javafx.scene.image.Image; +import javafx.scene.image.ImageView; +import javafx.scene.paint.Paint; +import javafx.scene.shape.Circle; +import javafx.scene.shape.Line; +import javafx.scene.text.Font; +import javafx.scene.transform.Rotate; +import javafx.stage.Stage; +import javafx.util.Duration; + +import java.net.URL; +import java.util.Calendar; +import java.util.GregorianCalendar; + +public class Main extends Application { + final int bgH = 600; //background hight + final int bgW = 600; //background width + final int cX = 300; //centre X + final int cY = 150; //centre Y + final int cR0 = 20; //circle0 radius + final int cR1 = 60; //circle0 radius + final int cR2 = 100; //circle0 radius + final int cR3 = 140; //circle0 radius + + @Override + public void start(Stage primaryStage) throws Exception{ + + Calendar myCalendar = new GregorianCalendar(); + double secDegree = myCalendar.get(Calendar.SECOND) * (360 / 60); + double minDegree = (myCalendar.get(Calendar.MINUTE) + secDegree / 360.0) * (360 / 60); + double hourDegree = (myCalendar.get(Calendar.HOUR) + minDegree / 360) * (360 / 12); + +//start drawing + primaryStage.setTitle("My clock"); + URL background = getClass().getResource("Clock.jpg"); + Image im = new Image(background.toString(), bgW, bgH, false, false); + ImageView ivBackground = new ImageView(im); + + Circle circle0 = new Circle(cX,cY,cR0); + circle0.setFill(null); + circle0.setStroke(Paint.valueOf("#FF7F50")); + + Circle circle1 = new Circle(cX,cY,cR1); + circle1.setFill(null); + circle1.setStroke(Paint.valueOf("#FF7F50")); + + Circle circle2 = new Circle(cX,cY,cR2); + circle2.setFill(null); + circle2.setStroke(Paint.valueOf("#FF7F50")); + + Circle circle3 = new Circle(cX,cY,cR3); + circle3.setFill(null); + circle3.setStroke(Paint.valueOf("#FF7F50")); + + Group circles = new Group(circle0,circle1,circle2,circle3); + + Label label1 = new Label("Fury Road"); + label1.layoutXProperty().bind(circle0.centerXProperty().subtract(250)); + label1.layoutYProperty().bind(circle0.centerYProperty().subtract(100)); + label1.setTextFill(Paint.valueOf("#DAA520")); + label1.setFont(new Font("Arial" ,20)); + label1.setRotate(-45); + + Label label2 = new Label("Mad Max"); + label2.layoutXProperty().bind(circle0.centerXProperty().subtract(-150)); + label2.layoutYProperty().bind(circle0.centerYProperty().subtract(100)); + label2.setTextFill(Paint.valueOf("#FF7F50")); + label2.setFont(new Font("Arial" ,20)); + label2.setRotate(45); + + Label label3 = new Label("by asintsov"); + label3.layoutXProperty().bind(circle0.centerXProperty().subtract(-200)); + label3.layoutYProperty().bind(circle0.centerYProperty().subtract(-400)); + label3.setTextFill(Paint.valueOf("#F8F8FF")); + label3.setFont(new Font("Arial" ,15)); + + Group labels = new Group(label1, label2, label3); + + Line lHour = new Line(0, -100, 0, -140); + lHour.setStroke(Paint.valueOf("#DAA520")); + lHour.setStrokeWidth(5); + lHour.layoutXProperty().bind(circle0.centerXProperty()); + lHour.layoutYProperty().bind(circle0.centerYProperty()); + Rotate rotateHour = new Rotate(); + rotateHour.setAngle(hourDegree); + lHour.getTransforms().addAll(rotateHour); + + Line lMin = new Line(0, -60, -0, -100); + lMin.setStroke(Paint.valueOf("#DAA520")); + lMin.setStrokeWidth(5); + lMin.layoutXProperty().bind(circle0.centerXProperty()); + lMin.layoutYProperty().bind(circle0.centerYProperty()); + Rotate rotateMin = new Rotate(); + rotateMin.setAngle(minDegree); + lMin.getTransforms().addAll(rotateMin); + + Line lSec = new Line(0, -20, -0, -60); + lSec.setStroke(Paint.valueOf("#DAA520")); + lSec.setStrokeWidth(5); + lSec.layoutXProperty().bind(circle0.centerXProperty()); + lSec.layoutYProperty().bind(circle0.centerYProperty()); + Rotate rotateSec = new Rotate(); + rotateSec.setAngle(secDegree); + lSec.getTransforms().addAll(rotateSec); + + Group lines = new Group(lHour,lMin, lSec); + + Group ticks = new Group(); + for (int i = 0; i <= 12; i++) { + Line tick = new Line (0,-60,0,-100); + tick.setStrokeWidth(1); + tick.setStroke(Paint.valueOf("#FF7F50")); + tick.layoutXProperty().bind(circle0.centerXProperty()); + tick.layoutYProperty().bind(circle0.centerYProperty()); + tick.getTransforms().add(new Rotate(i*(360/12))); + ticks.getChildren().add(tick); + } + + Group numbs = new Group(); + for (int i = 0; i < 12; i++) { + Label numb = new Label(Integer.toString(i)); + numb.setTextFill(Paint.valueOf("#FF7F50")); + numb.setFont(new Font("Arial" ,15)); + numb.layoutXProperty().bind(circle2.centerXProperty()); + numb.layoutYProperty().bind(circle2.centerYProperty().subtract(-30)); + Rotate rotNumb = new Rotate(i*(360/12)+185); + rotNumb.setPivotY(-30); + numb.getTransforms().add(rotNumb); + numbs.getChildren().add(numb); + } +//end drawing + + final Timeline secTimeline = new Timeline( + new KeyFrame( + Duration.seconds(60), + new KeyValue( + rotateSec.angleProperty(), + 360 + secDegree, + Interpolator.LINEAR + ) + ) + ); + + final Timeline minTimeline = new Timeline( + new KeyFrame( + Duration.minutes(60), + new KeyValue( + rotateMin.angleProperty(), + 360 + minDegree, + Interpolator.LINEAR + ) + ) + ); + final Timeline hourTimeline = new Timeline( + new KeyFrame( + Duration.hours(12), + new KeyValue( + rotateHour.angleProperty(), + 360 + hourDegree, + Interpolator.LINEAR + ) + ) + ); + + secTimeline.setCycleCount(Animation.INDEFINITE); + minTimeline.setCycleCount(Animation.INDEFINITE); + hourTimeline.setCycleCount(Animation.INDEFINITE); + + secTimeline.play(); + minTimeline.play(); + hourTimeline.play(); + + + Group root = new Group(ivBackground, lines, circles, labels, ticks, numbs); + Scene scene = new Scene(root, bgW, bgH); + primaryStage.setScene(scene); + primaryStage.show(); + } + + public static void main(String[] args) { + Application.launch(args); + } +}