这是我发现的一个例子,但不确定这是否是设置UI的最有效方法。如果你能解释任何提高效率的方法,或者有另一种更有效的方式来解决这个问题。
我遗漏了一个名为module的类,因为不需要查看控制器是否有效。
package WRAV;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.Button;
import javafx.scene.control.TextField;
import java.util.ArrayList;
public class Controller {
////////////////////////////////////////////////////////////////////////////////////////
// list of Students
private ArrayList<StudentModel> students;
public ArrayList<StudentModel> getStuds(){ return students;}
// the index of the current student
private IntegerProperty currentIndex = new SimpleIntegerProperty(-1);
// the number of student
private IntegerProperty currentSize = new SimpleIntegerProperty(0);
// the current student being viewed and edited
private Property<StudentModel> currentStudent = new SimpleObjectProperty<>();
// some getter methods for the properties
public int getCurrentIndex() {
return currentIndex.get();
}
public StudentModel getCurrentStudent() {
return currentStudent.getValue();
}
////////////////////////////////////////////////////////////////////////////////////////
//List of all current students modules
private ArrayList<Module> studentModules = new ArrayList<Module>();
// the current module
private Property<Module> currentModule = new SimpleObjectProperty<Module>();
//the index of the current module
private IntegerProperty currentModIndex = new SimpleIntegerProperty(-1);
//the number of modules
private IntegerProperty currentModSize = new SimpleIntegerProperty(0);
// some getter methods for the properties
public int getCurrentModIndex() {return currentModIndex.get();}
public Module getCurrentModule() { return currentModule.getValue() ;}
////////////////////////////////////////////////////////////////////////////////////////
// navigation methods
public void first() {
System.out.println("|<\tFirst.");
if (students.size() > 0)
currentIndex.set(0);
}
public void last() {
System.out.println(">|\tLast.");
if (students.size() > 0)
currentIndex.set(students.size() - 1);
}
public void next() {
System.out.println(">>\tNext.");
if (currentIndex.get() < (students.size() - 1))
currentIndex.set(currentIndex.get() + 1);
currentModIndex.setValue(1);
setUpMod();
}
public void previous() {
System.out.println("<<\tPrev.");
if (currentIndex.get() > 0)
currentIndex.set(currentIndex.get() - 1);
currentModIndex.setValue(1);
setUpMod();
}
public void newStudent() {
System.out.println("[]\tNew.");
// create new student
StudentModel student = new StudentModel("?", "?", "?");
studentModules.clear();
newMod();
// add to student
students.add(student);
// update size property
currentSize.set(students.size());
// set current to last
last();
currentModIndex.setValue(1);
setUpMod();
}
public void removeStudent(){
if (students.size() != 0) {
System.out.println("[]\tRemove.");
// remove current student
students.remove(getCurrentIndex());
System.out.println(students.size());
// update size property
currentSize.set(students.size());
// set current to last
last();
if (students.size() == 0){
newStudent();
}
currentModIndex.setValue(1);
setUpMod();
}
}
private void setupProperties() {
System.out.println("Setting up properties.");
// change the current student if the current index changes
currentIndex.addListener((observable, oldValue, newValue) -> {
// if new index value within the allowed range, get the student
if ((newValue.intValue() >= 0) && (newValue.intValue() < students.size())) {
System.out.printf("Current index changed, old = %s, new = %s\n", oldValue.intValue(), newValue.intValue());
currentStudent.setValue(students.get(newValue.intValue()));
}
});
// update bindings to the current student if it changed
currentStudent.addListener((observable, oldValue, newValue) -> {
System.out.printf("Student changed, old = %s, new = %s\n", oldValue, newValue);
rebindFields(oldValue, newValue);
});
}
////////////////////////////////////////////////////////////////////////////////////////
public void firstMod() {
System.out.println("|<\tFirst Module");
if (studentModules.size() > 0)
currentModIndex.set(0);
}
public void lastMod() {
System.out.println(">|\tLast Module");
if (getCurrentStudent().modules.size() > 0)
currentModIndex.set(getCurrentStudent().modules.size() - 1);
}
public void nextMod() {
System.out.println(">>\tNext Module");
if (currentModIndex.get() < (getCurrentStudent().modules.size() - 1))
currentModIndex.set(currentModIndex.get() + 1);
}
public void previousMod() {
System.out.println("<<\tPrev Module");
if (currentModIndex.get() > 0)
currentModIndex.set(currentModIndex.get() - 1);
}
public void newMod() {
System.out.println("[]\tNew Module");
// create new module
StudentModel cur = getCurrentStudent();
Module add = new Module("?", "?", 0, 0);
// add to contacts
cur.addModule(add);
// update size property
currentModSize.set(studentModules.size());
// set current to last
lastMod();
}
public void removeMod(){
if (studentModules.size() != 0) {
System.out.println("[]\tRemove Module");
// remove current module
studentModules.remove(getCurrentModIndex());
System.out.println(studentModules.size());
// update size property
currentModSize.set(studentModules.size());
// set current to last
last();
if (studentModules.size() == 0){
newMod();
}
}
}
private void setupModProperties() {
System.out.println("Setting up module properties.");
// change the current module if the current index changes
currentModIndex.addListener((observable, oldValue, newValue) -> {
// if new index value within the allowed range, get the module
if ((newValue.intValue() >= 0) && (newValue.intValue() < studentModules.size())) {
System.out.printf("Current module index changed, old = %s, new = %s\n", oldValue.intValue(), newValue.intValue());
currentModule.setValue(studentModules.get(newValue.intValue()));
}
});
// update bindings to the current module if it changed
currentModule.addListener((observable, oldValue, newValue) -> {
System.out.printf("Module changed, old = %s, new = %s\n", oldValue, newValue);
rebindModFields(oldValue, newValue);
});
}
public void setUp(){
System.out.println("|<\tSetup.");
if (students.size() > 0)
currentIndex.set(0);
currentSize.set(students.size());
setUpMod();
}
public void setUpMod(){
studentModules = getCurrentStudent().modules;
if (studentModules.size() > 0)
currentModIndex.set(0);
else {
newMod();
}
currentModSize.set(studentModules.size());
}
public Controller(ArrayList<StudentModel> arrayList) {
students = arrayList;
setupProperties();
setupModProperties();
}
// references to scene's controls///////////////////////////////////////////
private Button btnAddStud;
private Button btnDelStud;
private TextField txtSNum;
private TextField txtSName;
private TextField txtName;
private Label lblSetAVG;
private Button btnStudLeft;
private Button btnStudRight;
private Label lblStudOf;
///////////////////////////////////////////////////////////////////////////
private Button btnAddMod;
private Button btnDelMod;
private TextField txtCode;
private TextField txtDiscrip;
private TextField txtGrade;
private TextField txtYear;
private Label lblSetResult;
private Button btnModLeft;
private Button btnModRight;
private Label lblModOf;
/**
* Unbinds any bindings to the text fields, then rebinds to the current
* properties.
*/
private void rebindFields(StudentModel oldStudent, StudentModel newStudent) {
// remove old bindings to the old student
if (oldStudent != null) {
System.out.println("Removing text field bi-directional bindings from " + oldStudent);
txtName.textProperty().unbindBidirectional(oldStudent.name);
txtSName.textProperty().unbindBidirectional(oldStudent.sname);
txtSNum.textProperty().unbindBidirectional(oldStudent.studentNumber);
lblSetAVG.textProperty().unbindBidirectional(oldStudent.average);
}
// add bindings to new student
if (newStudent != null) {
System.out.println("Adding text field bi-directional bindings to " + newStudent);
txtName.textProperty().bindBidirectional(newStudent.name);
txtSName.textProperty().bindBidirectional(newStudent.sname);
txtSNum.textProperty().bindBidirectional(newStudent.studentNumber);
lblSetAVG.textProperty().bindBidirectional(newStudent.average);
}
}
private void rebindModFields(Module oldModule, Module newModule) {
// remove old bindings to the old module
if (oldModule != null) {
System.out.println("Removing text field bi-directional bindings from " + oldModule);
txtCode.textProperty().unbindBidirectional(oldModule.modCode);
txtDiscrip.textProperty().unbindBidirectional(oldModule.modDiscrip);
txtGrade.textProperty().unbindBidirectional(oldModule.modGrade);
txtYear.textProperty().unbindBidirectional(oldModule.modYear);
lblSetResult.textProperty().unbindBidirectional(oldModule.passed);
}
// add bindings to new module
if (newModule != null) {
System.out.println("Adding text field bi-directional bindings to " + newModule);
txtCode.textProperty().bindBidirectional(newModule.modCode);
txtDiscrip.textProperty().bindBidirectional(newModule.modDiscrip);
txtGrade.textProperty().bindBidirectional(newModule.modGrade);
txtYear.textProperty().bindBidirectional(newModule.modYear);
lblSetResult.textProperty().bindBidirectional(newModule.passed);
}
}
/**
* Bind the UI controls and the controller properties together.
* @param scene
*/
public void connectToUI(Scene scene) {
// obtain references to controls
System.out.println("Obtaining references to scene controls by id.");
txtName = (TextField) scene.lookup("#Name");
txtSNum = (TextField) scene.lookup("#sNum");
txtSName = (TextField) scene.lookup("#SName");
btnStudLeft = (Button) scene.lookup("#StudLeft");
btnStudRight = (Button) scene.lookup("#StudRight");
btnAddStud = (Button) scene.lookup("#AddStud");
btnDelStud = (Button) scene.lookup("#DelStud");
lblSetAVG = (Label) scene.lookup("#SetAVG");
lblStudOf = (Label) scene.lookup("#StudOf");
//////////////////////////////////////////////////////
txtCode = (TextField) scene.lookup("#ModCode");
txtDiscrip = (TextField) scene.lookup("#ModDiscrip");
txtGrade = (TextField) scene.lookup("#ModGrade");
txtYear = (TextField) scene.lookup("#ModYear");
btnModLeft = (Button) scene.lookup("#ModLeft");
btnModRight = (Button) scene.lookup("#ModRight");
btnAddMod = (Button) scene.lookup("#AddMod");
btnDelMod = (Button) scene.lookup("#DelMod");
lblSetResult = (Label) scene.lookup("#SetResult");
lblModOf = (Label) scene.lookup("#ModOf");
System.out.println("Attaching listeners to controls and properties.");
// modify label using a Fluent binding
lblStudOf.textProperty().bind( currentIndex.add(1).asString().concat(" of ").concat(currentSize));
// initialise size - which will initialise the binding
currentSize.set(students.size());
// attach event handlers to the buttons
btnStudLeft.setOnAction(event -> previous());
btnAddStud.setOnAction(event -> newStudent());
btnDelStud.setOnAction(event -> removeStudent());
btnStudRight.setOnAction(event -> next());
// modify label using a binding
lblModOf.textProperty().bind( currentModIndex.add(1).asString().concat(" of ").concat(currentModSize));
// initialise size
currentModSize.set(studentModules.size());
// attach event handlers to the buttons
btnModLeft.setOnAction(event -> previousMod());
btnAddMod.setOnAction(event -> newMod());
btnDelMod.setOnAction(event -> removeMod());
btnModRight.setOnAction(event -> nextMod());
txtGrade.focusedProperty().addListener((arg0, oldPropertyValue, newPropertyValue) -> {
if ( Integer.parseInt(txtGrade.getText()) > 50) {
getCurrentModule().didPass();
lblSetResult.setText("Pass");
}
else {
lblSetResult.setText("Fail");
}
lblSetAVG.setText(getCurrentStudent().calcAverage());
});
}
public void clear(){
students.clear();
}
}
public class StudentModel {
public StringProperty studentNumber = new SimpleStringProperty("");
public StringProperty name = new SimpleStringProperty("");
public StringProperty sname = new SimpleStringProperty("");
public StringProperty average = new SimpleStringProperty("0");
public ArrayList<Module> modules = new ArrayList<>();
@Override
public String toString() {
String sLine = studentNumber.get() + ", " + name.get() + ", " + sname.get() + ", " + average.get();
for (int i = 0; i < modules.size(); i++) {
sLine += "\n " + modules.get(i).toString() + ", ";
}
return sLine;
}
public StudentModel(String studentNumber, String sname, String name) {
this.studentNumber.set(studentNumber);
this.name.set(name);
this.sname.set(sname);
}
public void addModules(NodeList m){
for (int i = 0; i < m.getLength(); i++) {
NodeList children = m.item(i).getChildNodes();
Module add = (new Module(children.item(1).getTextContent(), children.item(3).getTextContent(), Integer.parseInt(children.item(5).getTextContent()), Integer.parseInt(children.item(7).getTextContent())));
modules.add(add);
}
this.average.set(String.valueOf(calcAverage()));
}
public void addModule(Module m){
modules.add(m);
}
public String calcAverage(){
double sum = 0;
for (int i = 0; i < modules.size(); i++) {
sum += Integer.parseInt(modules.get(i).modGrade.getValue());
}
if (modules.size() != 0) {
average.setValue(String.valueOf(1.00 * (sum / modules.size())));
}
return average.getValue();
}
public Element toNode(Document doc){
Element stud = doc.createElement("student");
stud.appendChild(getCompanyElements(doc, stud, "snum", studentNumber.getValue()));
stud.appendChild(getCompanyElements(doc, stud, "surname", sname.getValue()));
stud.appendChild(getCompanyElements(doc, stud, "name", name.getValue()));
Element mods = doc.createElement(("modules"));
for (int i = 0; i < modules.size(); i++) {
mods.appendChild(modules.get(i).toNode(doc));
}
stud.appendChild(mods);
return stud;
}
private static Node getCompanyElements(Document doc, Element element, String name, String value) {
Element node = doc.createElement(name);
node.appendChild(doc.createTextNode(value));
return node;
}
}'
非常感谢谢谢。