2016-09-08 7 views
0

javafxのカスタムセルファクトリを使用して、現在の時刻とチェック時間に基づくアラートステータスに基づいてセルをスタイルします。javafxのカスタムセルファクトリを使用したフェードトランジション

すべて正常に動作しますが、フェードトランジションなどを追加して、チェックタイムを変更して確認応答が出るまで行を実質的に点滅させます。

私がのために多くのコードを追加することができると思うよりも少し複雑ですので、私は私のセルファクトリクラスを掲載する予定

public class FormattedTableCellFactory<S, T> implements Callback<TableColumn<S, T>, TableCell<S, T>> { 
    private TableCell<S, T> cell = null; 
    private FadeTransition ft; 

    public FormattedTableCellFactory() { 
    } 

    @Override 
    public TableCell<S, T> call(TableColumn<S, T> p) { 
     cell = new TableCell<S, T>() { 
      @Override 
      protected void updateItem(Object item, boolean empty) { 
       super.updateItem((T) item, empty); 

       // CSS Styles 
       String cssStyle; 

       Person person = null; 

       if(getTableRow() != null) { 
        person = (Person) getTableRow().getItem(); 
       } 

       ft = new FadeTransition(Duration.millis(500), cell); 
       ft.setFromValue(1.0); 
       ft.setToValue(0.1); 
       ft.setCycleCount(Timeline.INDEFINITE); 
       ft.setAutoReverse(true); 
       //Remove all previously assigned CSS styles from the cell. 



       //Determine how to format the cell based on the status of the container. 

       if(person != null){ 
        switch(PersonAlert.getAlert(person)){ 
         case WARNING: 
          ft.stop(); 
          cssStyle = "warning"; 
          break; 
         case PAST_DUE: 
          ft.stop(); 
          cssStyle = "pastdue"; 
          break; 
         case ERC_PAST_DUE: 
          ft.stop(); 
          cssStyle = "ercpastdue"; 
          break; 
         case OVERDUE: 
          ft.playFromStart(); 
          cssStyle = "overdue"; 
          break; 
         case OVERNIGHT: 
          ft.stop(); 
          cssStyle = "overnight"; 
          break; 
         default: 
          ft.stop(); 
          cssStyle = "normal"; 
          break; 
        } 
       }else{ 
        ft.stop(); 
        setText(""); 
        return; 
       } 

       //Set the CSS style on the cell and set the cell's text. 
       getStyleClass().setAll(cssStyle); 
       if(item != null) { 
        setText(item.toString()); 
       }else{ 
        setText(""); 
       } 
      } 
     }; 
     return cell; 
    } 
} 

人が特定のステータスを持っている時はいつでもこのコードは、正常に動作します細胞の色が適切に変化する。ここでの唯一の問題はフェードトランジションです。最初に実行されるたびにフェードトランジションはうまく動作しますが、別のスタイルに変更すると、停止せずに点滅し続けます。

フェードトランジションを停止できません。これは、このupdateItemが呼び出されるたびに、フェードトランジションの新しいインスタンスが作成されるため、stopを呼び出すと、それが現在のトランジションで呼び出され、以前のトランジションでは呼び出されないからです。私は上のトランジションを初期化することでこれを取り除こうとしましたが、それでも点滅しません。

私はこれを編集して、ストップが呼び出されたときにフェードトランジションを停止する方法、またはセルファクトリを使ってセル/行を「点滅」させる方法がありますか?

答えて

0

あなたは間違ったレベルのものをスコープしています。

各セルには1つのフェードトランジションが必要です。現在、セル上でupdateItem()が呼び出されるたびに、新しいフェードトランジションを作成します。ファクト全体(単一のリファレンス、作成されたセルの数に関係なく)には、単一のリファレンスを保持します。これは、最近作成されたフェードトランジションのみを参照します。

同様に、何らかの理由で、工場で最も最近作成されたセルへのリファレンスを保持していますが、おそらく実際には使用していないと思います。

getStyleClass().setAll(...)を呼び出すことはお勧めできません。セルからすべてのデフォルトのスタイルクラス(たとえば、.table-cell)が削除されるため、デフォルトのスタイル処理をすべて削除することがあります。スタイルクラスはリストとして実装されているので扱いにくいですが、明示的に望ましくないものをすべて削除し、必要なものを重複しないようにする必要がありますあなたが本当にそれをやろうとしない限り)。また、(キャスティングによって)テーブルビューのタイプがPersonであると仮定しているので、行タイプを一般的にすることに意味がありません。

import java.util.Arrays; 
import java.util.List; 

import javafx.animation.FadeTransition; 
import javafx.animation.Timeline; 
import javafx.scene.control.TableCell; 
import javafx.scene.control.TableColumn; 
import javafx.util.Callback; 
import javafx.util.Duration; 

public class FormattedTableCellFactory<T> implements Callback<TableColumn<Person, T>, TableCell<Person, T>> { 

    private static final List<String> ALL_STYLES = Arrays.asList(
     "warning", "pastdue", "ercpastdue", "overnight", "normal" 
    ); 

    @Override 
    public TableCell<Person, T> call(TableColumn<Person, T> p) { 
     TableCell<Person, T> cell = new TableCell<Person, T>() { 

      private FadeTransition ft ; 

      { 
       ft = new FadeTransition(Duration.millis(500), this); 
       ft.setFromValue(1.0); 
       ft.setToValue(0.1); 
       ft.setCycleCount(Timeline.INDEFINITE); 
       ft.setAutoReverse(true); 
      } 

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

       // CSS Styles 
       String cssStyle = ""; 

       Person person = null; 

       if(! isEmpty()) { 
        // avoid casting here, if you prefer: 
        person = getTableView().getItems().get(getIndex()); 
       } 

       //Remove all previously assigned CSS styles from the cell. 

       getStyleClass().removeAll(ALL_STYLES); 


       //Determine how to format the cell based on the status of the container. 

       if(person != null){ 
        switch(PersonAlert.getAlert(person)){ 
         case WARNING: 
          ft.stop(); 
          setOpacity(1.0); 
          cssStyle = "warning"; 
          break; 
         case PAST_DUE: 
          ft.stop(); 
          setOpacity(1.0); 
          cssStyle = "pastdue"; 
          break; 
         case ERC_PAST_DUE: 
          ft.stop(); 
          setOpacity(1.0); 
          cssStyle = "ercpastdue"; 
          break; 
         case OVERDUE: 
          ft.playFromStart(); 
          cssStyle = "overdue"; 
          break; 
         case OVERNIGHT: 
          ft.stop(); 
          setOpacity(1.0); 
          cssStyle = "overnight"; 
          break; 
         default: 
          ft.stop(); 
          setOpacity(1.0); 
          cssStyle = "normal"; 
          break; 
        } 
       }else{ 
        ft.stop(); 
        setOpacity(1.0); 
        setText(""); 
       } 

       //Set the CSS style on the cell and set the cell's text. 
       if(item != null) { 
        getStyleClass().add(cssStyle); 
        setText(item.toString()); 
       }else{ 
        setText(""); 
       } 
      } 
     }; 
     return cell; 
    } 


} 
+0

YES:それはあなたがテストするために任意のコードを提供しなかったとして、私がテストすることは不可能だが

だから、あなたはおそらく、これらの線に沿って何かをしたいです!これはまさに私が欲しいものです。私は間違ってフェードトランジションを作成していることを知っていましたが、それを正しく行う方法を理解できませんでした。どうもありがとうございました。 –

+0

セルの実装としてスタンドアロンクラスを作成し、その列にセルファクトリを設定するときにラムダ式を使用するだけでは、おそらくもっとうれしいでしょう。私。あなたが 'someColumn.setCellFactory(p - > new FormattedTableCell ());'(またはその列にどのような型を持っていても)を実行するだけで使用すると、 'public class FormattedTableCell はTableCellを拡張します。少なくとも、2レベルのインデントを保存します。 –

+0

fxmlにcellFactoryを設定しています。それが何か変わるかどうかはわかりません。 –