2013-12-16 40 views
2

我遇到了一个我无法解决的问题。我想实施进度条设置为组合框:setButtonCell for ComboBox

public class JavaFXApplication4 extends Application 
{ 

    @Override 
    public void start(Stage primaryStage) 
    { 

     double y1 = 15; 
     ProgressBar p1 = new ProgressBar(); 
     p1.setLayoutY(y1); 
     HBox vb1 = new HBox(10); 
     vb1.getChildren().addAll(new Label("Progressbar 1"), p1); 

     double y2 = 15; 
     ProgressBar p2 = new ProgressBar(); 
     p2.setLayoutY(y2); 
     HBox vb2 = new HBox(10); 
     vb2.getChildren().addAll(new Label("Progressbar 2"), p2); 

     double y3 = 15; 
     ProgressBar p3 = new ProgressBar(); 
     p3.setLayoutY(y3); 
     HBox vb3 = new HBox(10); 
     vb3.getChildren().addAll(new Label("Progressbar 3"), p3); 

     TextChooser textChooser = new TextChooser(
      vb1, vb2, vb3 
     ); 

     textChooser.setStyle("-fx-font: 10px \"Verdana\";"); 

     StackPane root = new StackPane(); 
     root.getChildren().add(textChooser); 

     Scene scene = new Scene(root, 300, 250); 

     primaryStage.setTitle("Hello World!"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static class TextChooser extends StackPane 
    { 
     private Label label = new Label(); 

     private ComboBox<HBox> combo = new ComboBox<>(); 

     public TextChooser(HBox... options) 
     { 
      StackPane.setAlignment(label, Pos.CENTER_LEFT); 
      StackPane.setAlignment(combo, Pos.CENTER_LEFT); 

      label.graphicProperty().bind(
       //combo.getSelectionModel().selectedItemProperty() 
       combo.getSelectionModel().selectedItemProperty() 
      ); 
      label.visibleProperty().bind(
       combo.visibleProperty().not() 
      ); 
      //label.setPadding(new Insets(0, 0, 0, 10)); 

      combo.getItems().setAll(options); 

      combo.setCellFactory(new Callback<ListView<HBox>, ListCell<HBox>>() 
      { 
       @Override 
       public ListCell<HBox> call(ListView<HBox> p) 
       { 
        return new ListCell<HBox>() 
        { 
         @Override 
         protected void updateItem(HBox item, boolean empty) 
         { 
          super.updateItem(item, empty); 

          if (item == null || empty) 
          { 
           setGraphic(null); 
          } 
          else 
          { 
           setGraphic(item); 
          } 
         } 
        }; 
       } 
      }); 

      combo.getSelectionModel().select(0); 
      combo.setVisible(true); 

      label.setOnMouseEntered(event -> combo.setVisible(true)); 
      combo.showingProperty().addListener(observable -> 
      { 
       if (!combo.isShowing()) 
       { 
        combo.setVisible(false); 
       } 
      }); 
      combo.setOnMouseExited(event -> 
      { 
       if (!combo.isShowing()) 
       { 
        combo.setVisible(false); 
       } 
      }); 

      getChildren().setAll(label, combo); 
     } 

     public static void main(String[] args) 
     { 
      launch(args); 
     } 
    } 
} 

你能告诉我怎么也以进度条显示在组合框中使用setButtonCell

回答

3

你不应该把节点进入项目列表 - 而是应该将数据存储在那里,然后在您的单元工厂进行渲染。

例如:

public class JavaFXApplication5 extends Application 
{ 
    public static void main(String[] args) 
    { 
     launch(args); 
    } 


    public class ProgressData 
    { 
     private final DoubleProperty progressProp = new SimpleDoubleProperty(); 
     private final StringProperty progressName = new SimpleStringProperty(); 

     public ProgressData(String name, double progress) 
     { 
      progressProp.set(progress); 
      progressName.set(name); 
     } 

     public DoubleProperty progressProperty() 
     { 
      return progressProp; 
     } 

     public StringProperty nameProperty() 
     { 
      return progressName; 
     } 

     @Override 
     // Lazy hack for the combo button. 
     public String toString() 
     { 
      return progressName.get(); 
     } 
    } 


    @Override 
    public void start(Stage primaryStage) 
    { 
     ProgressData vb1 = new ProgressData("Progressbar 1", -1); 
     ProgressData vb2 = new ProgressData("Progressbar 2", 0.2); 
     ProgressData vb3 = new ProgressData("Progressbar 3", 0.3); 

     TextChooser textChooser = new TextChooser(vb1, vb2, vb3); 

     textChooser.setStyle("-fx-font: 10px \"Verdana\";"); 

     StackPane root = new StackPane(); 
     root.getChildren().add(textChooser); 

     Scene scene = new Scene(root, 300, 250); 

     primaryStage.setTitle("Hello World!"); 
     primaryStage.setScene(scene); 
     primaryStage.show(); 
    } 

    public static class TextChooser extends StackPane 
    { 
     private final Label label = new Label(); 

     private final ComboBox<ProgressData> combo = new ComboBox<>(); 

     public TextChooser(ProgressData... options) 
     { 
      StackPane.setAlignment(label, Pos.CENTER_LEFT); 
      StackPane.setAlignment(combo, Pos.CENTER_LEFT); 


      final ProgressBar labelBar = new ProgressBar(); 
      label.visibleProperty().bind(combo.visibleProperty().not()); 
      label.setContentDisplay(ContentDisplay.RIGHT); 
      label.setGraphic(labelBar); 


      combo.getItems().setAll(options); 

      // This will change the label's text and the progress bar value. 
      combo.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<ProgressData>() 
      { 
       @Override 
       public void changed(ObservableValue<? extends ProgressData> observable, ProgressData oldValue, ProgressData newValue) 
       { 
        if (labelBar.progressProperty().isBound()) 
        { 
         labelBar.progressProperty().unbind(); 
        } 

        labelBar.progressProperty().bind(newValue.progressProperty()); 
        label.setText(newValue.nameProperty().get()); 
       } 
      }); 

      combo.setCellFactory(new Callback<ListView<ProgressData>, ListCell<ProgressData>>() 
      { 
       @Override 
       public ListCell<ProgressData> call(ListView<ProgressData> p) 
       { 
        return new ListCell<ProgressData>() 
        { 
         private final ProgressBar cellBar = new ProgressBar(); 
         { 
          cellBar.setMouseTransparent(true); 
          setContentDisplay(ContentDisplay.RIGHT); 
          setGraphic(cellBar); 
         } 

         @Override 
         protected void updateItem(ProgressData item, boolean empty) 
         { 
          super.updateItem(item, empty); 

          if (item != null && ! empty) 
          { 
           if (cellBar.progressProperty().isBound()) 
           { 
            cellBar.progressProperty().unbind(); 
           } 
           cellBar.progressProperty().bind(item.progressProperty()); 
           setText(item.nameProperty().get()); 
          } 
         } 
        }; 
       } 
      }); 

      combo.getSelectionModel().select(0); 
      combo.setVisible(true); 

      label.setOnMouseEntered(new EventHandler<MouseEvent>() 
      { 
       @Override 
       public void handle(MouseEvent event) 
       { 
        combo.setVisible(true); 
       } 
      }); 

      combo.showingProperty().addListener(new InvalidationListener() 
      { 
       @Override 
       public void invalidated(Observable observable) 
       { 
        if (!combo.isShowing()) 
        { 
         combo.setVisible(false); 
        } 
       } 
      }); 

      combo.setOnMouseExited(new EventHandler<MouseEvent>() 
      { 
       @Override 
       public void handle(MouseEvent event) 
       { 
        if (!combo.isShowing()) 
        { 
         combo.setVisible(false); 
        } 
       } 
      }); 

      getChildren().setAll(label, combo); 
     } 

    } 

} 
2

我变化了的代码一点点,因为我没有Java8环境和正常工作: Screenshot

代码:

import javafx.application.Application; 
import javafx.beans.value.ChangeListener; 
import javafx.beans.value.ObservableValue; 
import javafx.event.EventHandler; 
import javafx.geometry.Pos; 
import javafx.scene.Scene; 
import javafx.scene.control.ComboBox; 
import javafx.scene.control.Label; 
import javafx.scene.control.ListCell; 
import javafx.scene.control.ListView; 
import javafx.scene.control.ProgressBar; 
import javafx.scene.input.MouseEvent; 
import javafx.scene.layout.HBox; 
import javafx.scene.layout.StackPane; 
import javafx.stage.Stage; 
import javafx.util.Callback; 

public class JavaFXApplication4 extends Application 
{ 

@Override 
public void start(Stage primaryStage) 
{ 
    double y1 = 15; 
    ProgressBar p1 = new ProgressBar(); 
    p1.setLayoutY(y1); 
    HBox vb1 = new HBox(10); 
    vb1.getChildren().addAll(new Label("Progressbar 1"), p1); 

    double y2 = 15; 
    ProgressBar p2 = new ProgressBar(); 
    p2.setLayoutY(y2); 
    HBox vb2 = new HBox(10); 
    vb2.getChildren().addAll(new Label("Progressbar 2"), p2); 

    double y3 = 15; 
    ProgressBar p3 = new ProgressBar(); 
    p3.setLayoutY(y3); 
    HBox vb3 = new HBox(10); 
    vb3.getChildren().addAll(new Label("Progressbar 3"), p3); 

    TextChooser textChooser = new TextChooser(
     vb1, vb2, vb3 
    ); 

    textChooser.setStyle("-fx-font: 10px \"Verdana\";"); 

    StackPane root = new StackPane(); 
    root.getChildren().add(textChooser); 

    Scene scene = new Scene(root, 300, 250); 

    primaryStage.setTitle("Hello World!"); 
    primaryStage.setScene(scene); 
    primaryStage.show(); 
} 

public static void main(String[] args) { 
    launch(args); 
} 
} 

class TextChooser extends StackPane 
{ 
private Label label = new Label(); 

private ComboBox<HBox> combo = new ComboBox<>(); 

public TextChooser(HBox... options) 
{ 
    StackPane.setAlignment(label, Pos.CENTER_LEFT); 
    StackPane.setAlignment(combo, Pos.CENTER_LEFT); 

    label.graphicProperty().bind(
     //combo.getSelectionModel().selectedItemProperty() 
     combo.getSelectionModel().selectedItemProperty() 
    ); 
    label.visibleProperty().bind(
     combo.visibleProperty().not() 
    ); 
    //label.setPadding(new Insets(0, 0, 0, 10)); 

    combo.getItems().setAll(options); 

    combo.setCellFactory(new Callback<ListView<HBox>, ListCell<HBox>>() 
    { 
     @Override 
     public ListCell<HBox> call(ListView<HBox> p) 
     { 
      return new ListCell<HBox>() 
      { 
       @Override 
       protected void updateItem(HBox item, boolean empty) 
       { 
        super.updateItem(item, empty); 

        if (item == null || empty) 
        { 
         setGraphic(null); 
        } 
        else 
        { 
         setGraphic(item); 
        } 
       } 
      }; 
     } 
    }); 

    combo.getSelectionModel().select(0); 
    combo.setVisible(true); 

    label.setOnMouseEntered(new EventHandler<MouseEvent>() { 

     @Override 
     public void handle(MouseEvent arg0) { 
      combo.setVisible(true); 

     } 

    }); 
    combo.showingProperty().addListener(new ChangeListener<Boolean>() { 

     @Override 
     public void changed(ObservableValue<? extends Boolean> arg0, Boolean arg1, Boolean newVal) { 
      if (!combo.isShowing()) 
      { 
       combo.setVisible(false); 
      }     
     } 
    }); 


    combo.setOnMouseExited(new EventHandler<MouseEvent>() 
    { 
     @Override 
     public void handle(MouseEvent arg0) { 
      if (!combo.isShowing()) 
       { 
        combo.setVisible(false); 
       } 
     } 
    }); 

    getChildren().setAll(label, combo); 
} 
} 
+0

是的,它在JavaFX 2.2中工作,但在Java 8中工作不正常。你有什么想法我可以使用'setButtonCell'? –

+2

我得到了这个建议:'你不应该把节点放入物品清单 - 而是应该将数据存储在那里,然后与你的细胞工厂一起渲染。 –

2

好了,所以用代码重新设计,我们可以回答这个问题,设置按钮电池:

private static class ButtonCell extends ListCell<ProgressData> 
{ 
    @Override 
    protected void updateItem(ProgressData item, boolean empty) 
    { 
     super.updateItem(item, empty); 

     if (item != null && ! empty) 
     { 
      setText(item.nameProperty().get()); 
     } 
    } 
} 

这在以前返工的代码,你会设置附:

combo.setButtonCell(new ButtonCell());