代码在jdk7中工作,而不是在jdk8中

时间:2014-04-28 07:51:26

标签: combobox javafx javafx-2 javafx-8 fxml

我从How to create custom components in JavaFX 2.0 using FXML?获取了示例代码。代码在jdk7中工作正常,但复选框和组合框值在jdk8中不起作用。我甚至无法单击复选框并选择下拉列表。

请指导我。 请在下面找到示例代码

包结构

com.example.javafx.choice
  ChoiceCell.java
  ChoiceController.java
  ChoiceModel.java
  ChoiceView.fxml
com.example.javafx.mvc
  FxmlMvcPatternDemo.java
  MainController.java
  MainView.fxml
  MainView.properties

ChoiceCell.java

package com.example.javafx.choice;

import java.io.IOException;
import java.net.URL;
import javafx.fxml.FXMLLoader;
import javafx.fxml.JavaFXBuilderFactory;
import javafx.scene.Node;
import javafx.scene.control.ListCell;

public class ChoiceCell extends ListCell<ChoiceModel>
{
    @Override
    protected void updateItem(ChoiceModel model, boolean bln)
    {
        super.updateItem(model, bln);

        if(model != null)
        {
            URL location = ChoiceController.class.getResource("ChoiceView.fxml");

            FXMLLoader fxmlLoader = new FXMLLoader();
            fxmlLoader.setLocation(location);
            fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());

            try
            {
                Node root = (Node)fxmlLoader.load(location.openStream());
                ChoiceController controller = (ChoiceController)fxmlLoader.getController();
                controller.setModel(model);
                setGraphic(root);
            }
            catch(IOException ioe)
            {
                throw new IllegalStateException(ioe);
            }
        }
    }
}

ChoiceController.java

package com.example.javafx.choice;

import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.CheckBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;

public class ChoiceController
{
    private final ChangeListener<String> LABEL_CHANGE_LISTENER = new ChangeListener<String>()
    {
        public void changed(ObservableValue<? extends String> property, String oldValue, String newValue)
        {
            updateLabelView(newValue);
        }
    };

    private final ChangeListener<Boolean> IS_SELECTED_CHANGE_LISTENER = new ChangeListener<Boolean>()
    {
        public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean newValue)
        {
            updateIsSelectedView(newValue);
        }
    };

    private final ChangeListener<Boolean> IS_VISIBILITY1_CHANGE_LISTENER = new ChangeListener<Boolean>() {
        public void changed(ObservableValue<? extends Boolean> property, Boolean oldValue, Boolean newValue) {
            updateIsVisibleView1(newValue);
        }};

    @FXML
    private Label labelView;

    @FXML
    private CheckBox isSelectedView;

   @FXML
    ComboBox isVisible1;


    private ChoiceModel model;

    public ChoiceModel getModel()
    {
        return model;
    }

    public void setModel(ChoiceModel model)
    {
        if(this.model != null)
            removeModelListeners();
        this.model = model;
        setupModelListeners();
        updateView();

    }

    private void removeModelListeners()
    {
        model.labelProperty().removeListener(LABEL_CHANGE_LISTENER);
        model.isSelectedProperty().removeListener(IS_SELECTED_CHANGE_LISTENER);
         model.isVisibleProperty1().removeListener(IS_VISIBILITY1_CHANGE_LISTENER);
        isSelectedView.selectedProperty().unbindBidirectional(model.isSelectedProperty());
    }

    private void setupModelListeners()
    {
        model.labelProperty().addListener(LABEL_CHANGE_LISTENER);
        model.isSelectedProperty().addListener(IS_SELECTED_CHANGE_LISTENER);
        model.isVisibleProperty1().addListener(IS_VISIBILITY1_CHANGE_LISTENER);
        isSelectedView.selectedProperty().bindBidirectional(model.isSelectedProperty());
    }

    private void updateView()
    {
        updateLabelView();
        updateIsSelectedView();
        updateIsVisibleView1();
    }

    private void updateLabelView(){ updateLabelView(model.getLabel()); }
    private void updateLabelView(String newValue)
    {
        labelView.setText(newValue);
    }

    private void updateIsSelectedView(){ updateIsSelectedView(model.isSelected()); }
    private void updateIsSelectedView(boolean newValue)
    {
        isSelectedView.setSelected(newValue);
    }

    private void updateIsVisibleView1() {
        updateIsVisibleView1(model.isVisible1());
    }
    private void updateIsVisibleView1(boolean newValue) {
        isVisible1.setVisible(newValue);
    }
}

ChoiceModel.java

package com.example.javafx.choice;

import javafx.beans.property.BooleanProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleStringProperty;
import javafx.beans.property.StringProperty;

public class ChoiceModel
{
    private final StringProperty label;
    private final BooleanProperty isSelected;
    private final BooleanProperty isVisible1;

    public ChoiceModel(String label, boolean isSelected, boolean isVisible1)
    {
        this.label = new SimpleStringProperty(label);
        this.isSelected = new SimpleBooleanProperty(isSelected);
        this.isVisible1 = new SimpleBooleanProperty(isVisible1);
    }

    public String getLabel(){ return label.get(); }
    public void setLabel(String label){ this.label.set(label); }
    public StringProperty labelProperty(){ return label; }

    public boolean isSelected(){ return isSelected.get(); }
    public void setSelected(boolean isSelected){ this.isSelected.set(isSelected); }
    public BooleanProperty isSelectedProperty(){ return isSelected; }

    public boolean isVisible1()
    {
        return isVisible1.get();
    }

    public void setVisible1(boolean isVisible1)
    {
        this.isVisible1.set(isVisible1);
    }

    public BooleanProperty isVisibleProperty1()
    {
        return isVisible1;
    }
}

ChoiceView.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.collections.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<HBox xmlns:fx="http://javafx.com/fxml/1" xmlns="http://javafx.com/javafx/2.2" fx:controller="com.example.javafx.choice.ChoiceController">
  <children>
    <CheckBox fx:id="isSelectedView" />
    <Label fx:id="labelView" />
    <ComboBox id="isVisible1" fx:id="isVisible1" value="last 7 digits" visible="false">
      <items>

         <FXCollections fx:factory="observableArrayList">
            <String fx:value="last 10 digits" />
            <String fx:value="last 9 digits" />
            <String fx:value="last 8 digits" />
            <String fx:value="last 7 digits" />
            <String fx:value="last 6 digits" />
            <String fx:value="last 5 digits" />
            <String fx:value="last 4 digits" />
            <String fx:value="last 3 digits" />

        </FXCollections>
      </items>
    </ComboBox>
  </children>
</HBox>

FxmlMvcPatternDemo.java

package com.example.javafx.mvc;

import com.example.javafx.choice.ChoiceController;
import java.util.ResourceBundle;
import javafx.application.Application;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.stage.Stage;

public class FxmlMvcPatternDemo extends Application
{
    public static void main(String[] args) throws ClassNotFoundException
    {
        Application.launch(FxmlMvcPatternDemo.class, args);
    }

    @Override
    public void start(Stage stage) throws Exception
    {
        Parent root = FXMLLoader.load
        (
            FxmlMvcPatternDemo.class.getResource("MainView.fxml"),
            ResourceBundle.getBundle(FxmlMvcPatternDemo.class.getPackage().getName()+".MainView")/*properties file*/

        );
        ChoiceController controller = new ChoiceController();
        stage.setScene(new Scene(root));
        stage.show();
    }
}

MainController.java

package com.example.javafx.mvc;

import com.example.javafx.choice.ChoiceCell;
import com.example.javafx.choice.ChoiceModel;
import java.net.URL;
import java.util.ResourceBundle;
import javafx.collections.FXCollections;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.util.Callback;

public class MainController implements Initializable
{
    @FXML
    private ListView<ChoiceModel> choicesView;

    @Override
    public void initialize(URL url, ResourceBundle rb)
    {
        choicesView.setCellFactory(new Callback<ListView<ChoiceModel>, ListCell<ChoiceModel>>()
        {
            public ListCell<ChoiceModel> call(ListView<ChoiceModel> p)
            {
                return new ChoiceCell();
            }
        });
        choicesView.setItems(FXCollections.observableArrayList
        (
            new ChoiceModel("Tiger", true, false),
            new ChoiceModel("Shark", false, true),
            new ChoiceModel("Bear", false, true),
            new ChoiceModel("Wolf", true, true)
        ));
    }

    @FXML
    private void handleForceChange(ActionEvent event)
    {
        if(choicesView != null && choicesView.getItems().size() > 0)
        {
            boolean isSelected = choicesView.getItems().get(0).isSelected();
            choicesView.getItems().get(0).setSelected(!isSelected);
        }
    }
}

MainView.fxml

<?xml version="1.0" encoding="UTF-8"?>

<?import java.lang.*?>
<?import javafx.scene.*?>
<?import javafx.scene.control.*?>
<?import javafx.scene.layout.*?>

<VBox
    xmlns:fx="http://javafx.com/fxml"
    fx:controller="com.example.javafx.mvc.MainController"

    prefWidth="300"
    prefHeight="400"
    fillWidth="false"
>
    <children>
        <Label text="%title" />
        <ListView fx:id="choicesView" />
        <Button text="Force Change" onAction="#handleForceChange" />
    </children>
</VBox>

MainView.proprties

 title=JavaFX 2.0 FXML MVC demo

1 个答案:

答案 0 :(得分:0)

我没有深入挖掘,但重构如下,应该足够了。仔细检查已连接和已删除侦听器的正确执行情况。

public class ChoiceCell extends ListCell<ChoiceModel> {

    private Node root;
    private ChoiceController controller;

    public ChoiceCell() {

        URL location = ChoiceController.class.getResource("ChoiceView.fxml");
        FXMLLoader fxmlLoader = new FXMLLoader();
        fxmlLoader.setLocation(location);
        fxmlLoader.setBuilderFactory(new JavaFXBuilderFactory());

        try {
            root = (Node) fxmlLoader.load(location.openStream());
            controller = (ChoiceController) fxmlLoader.getController();
        } catch (IOException ioe) {
            throw new IllegalStateException(ioe);
        }
    }

    @Override
    protected void updateItem(ChoiceModel model, boolean bln) {
        super.updateItem(model, bln);

        if (model != null) {
            controller.setModel(model);
            setGraphic(root);
        } else {
            setGraphic(null);
        }
    }
}