如何一次更新所有JavaFX元素?

时间:2018-12-02 15:08:54

标签: java javafx

我有一个简单的javaFX应用程序,其中包含一些组合框和Textareas。

Combobox1具有arraylist中的所有客户端。当我通过buttonclick删除客户端时,它将从列表中删除该客户端,所有其他fx元素(例如Textareas和组合框)都应应用此更改。

我的方法是为每个元素再次加载客户列表。例如

clientTextArea.setText(MyClass.getAllclients());

当我对2个fx元素执行此操作时还可以,但是10或100会变得超级混乱。 通知所有其他相关fx元素重新加载clientarray的正确方法是什么?

示例

    public class Worker {

    private String name;

    public Worker(String name){
        this.name = name;
    }

    public void setName(String name)
    {
        this.name = name;
    }

    public String getName(){
        return name;
    }
}

public class Work {

    private ArrayList<Worker> workerList = new ArrayList<>();

    public void addWorker(Worker worker){
            workerList.add(worker);
    }

    public boolean removeWorker(Worker worker) {
        for(Worker work: workerList) {
            if(worker.equals(work)){
                workerList.remove(work);
                return  true;
            }
        }
        return false;
    }
}

public class WorkerFX {

    Work work = new Work();

    @FXML
    private Button add, remove;

    @FXML
    private ComboBox<Worker> workerComBobox;

    @FXML
    private TextArea workerTextArea;

    @FXML
    private TextField workerTextField;

    public void addWorker(){
       Worker newWorker = new Worker(workerTextField.getText());
       work.addWorker(newWorker);
       workerComBobox.getItems().add(newWorker);
       //now the Textfield schould automaticly also add the Worker too
    }

}

1 个答案:

答案 0 :(得分:2)

将列表声明为ObservableList,然后向其中添加一个侦听器,其中包含对控件的所有必要更新。像这样:

 @IBDesignable class TriangleView2: UIView {

override init(frame: CGRect) {
    super.init(frame: frame)
}

required init?(coder aDecoder: NSCoder) {
    super.init(coder: aDecoder)
}
let gradient = CAGradientLayer()
override func draw(_ rect: CGRect) {

    //draw the line of UIBezierPath

    let path1 = UIBezierPath()
    path1.move(to: CGPoint(x: rect.minX - 100, y: rect.maxY - 80))
    path1.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
    path1.addLine(to: CGPoint(x: (rect.maxX + 90  ), y: rect.minY/2 ))
    path1.close()

    // add clipping path. this draws an imaginary line (to create bounds) from the
    //ends of the UIBezierPath line down to the bottom of the screen
    let clippingPath = path1.copy() as! UIBezierPath
    clippingPath.move(to: CGPoint(x: rect.minX - 100, y: rect.maxY - 80))
    clippingPath.addLine(to: CGPoint(x: rect.maxX, y: rect.maxY))
    clippingPath.addLine(to: CGPoint(x: (rect.maxX + 90  ), y: rect.minY/2 ))
    clippingPath.close()

    clippingPath.addClip()

    // create and add the gradient
    let colors = [theme.current.profile_start_view1.cgColor, theme.current.profile_end_view1.cgColor]

    let colorSpace = CGColorSpaceCreateDeviceRGB()        
    let colorLocations:[CGFloat] = [0.0, 1.0]        
    let gradient = CGGradient(colorsSpace: colorSpace,
                              colors: colors as CFArray,
                              locations: colorLocations)

    let context = UIGraphicsGetCurrentContext()
    let startPoint = CGPoint(x: 1, y: 1)
    let endPoint = CGPoint(x: 1, y: bounds.maxY)
    // and lastly, draw the gradient.
    context!.drawLinearGradient(gradient!, start: startPoint, end: 
  endPoint, options: CGGradientDrawingOptions.drawsAfterEndLocation)
    }
}

如果您有10或100个元素,则仍需要显式定义其更新行为。这是不可避免的,但是通过这样做,您不必担心在不同更改源上调用更新。

某些控件,例如ObservableList<SomeClass> myList = FXCollections.observableArrayList(); myList.addListener(l -> { // do what you need with your controls here }); 公开了items属性,您可以将其绑定到列表,而不必在侦听器中对其进行更新。 Here's a guide to JavaFX property binding。无论哪种方式,您仍然需要在某处显式定义每个控件的更新行为。