2016-08-27 1 views
0

こんにちは、Gridpaneでクリックされたノード(セル)を取得する方法については、多くのソリューションをオンラインで試してみました。ノードを取得する方法は次のとおりです。私はまた、このメソッドの前にすべてのノードを反復処理することを試みました。私はscenebuilderでグリッドペインを構築しました。下の図のように、列と行がはっきりと表示されています。私はこの解決策を試していますが、上で述べたように、行と列から返される値はnullです。JavaFXのGridPaneの列と行のインデックスにアクセスするとNULLが返され続ける

@FXML 
    private void mouseEntered(MouseEvent e) { 
     Node source = (Node)e.getSource() ; 
     System.out.println(source); 
     Integer colIndex = userSelectionGrid.getColumnIndex(source); 
     Integer rowIndex = userSelectionGrid.getRowIndex(source); 
     if (colIndex == null && rowIndex == null) System.out.println("BOO"); 
     else 
     System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue()); 
    } 

enter image description here

このグリッドを含むFXML

<GridPane fx:id="userSelectionGrid" onMouseClicked="#mouseEntered" prefHeight="44.0" prefWidth="563.0"> 
     <columnConstraints> 
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" /> 
      <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> 
     </columnConstraints> 
     <rowConstraints> 
      <RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> 
     </rowConstraints> 
     <children> 
      <Label text="SAVE" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="0"> 
       <font> 
        <Font name="System Bold" size="13.0" /> 
       </font> 
      </Label> 
      <Label text="CANCEL" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0"> 
       <font> 
        <Font name="System Bold" size="13.0" /> 
       </font> 
      </Label> 
      <Separator orientation="VERTICAL" GridPane.columnIndex="1" /> 
     </children> 
     <VBox.margin> 
      <Insets /> 
     </VBox.margin> 
     </GridPane> 
+0

HAVA:それらはあなたがそれらのノードでイベントをキャッチすることができますGridPaneレイアウト、上の影響を受けることなく、細胞とサイズを変更することができますか? – fabian

+0

私はまだこれは本当に新しいですが、私はあなたがscenebuilderでmouseEnteredメソッドをどこに追加したかを尋ねていると仮定しています。グリッドのコードセクションの下で、私はonMouseClickedメソッドでそれを追加しました –

答えて

2

イベントのソースは、ハンドラが、すなわち、この場合GridPaneにおいて、添加されるNodeです。あなたは正しいとソースNodeためGridPaneの子どもたちにハンドラを追加することができます。また、あなたのオリジナルのFXMLで、この作品を作ることができる

<GridPane fx:id="userSelectionGrid" prefHeight="44.0" prefWidth="563.0"> 
    <columnConstraints> 
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" /> 
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" /> 
    </columnConstraints> 
    <rowConstraints> 
     <RowConstraints minHeight="10.0" vgrow="SOMETIMES" /> 
    </rowConstraints> 
    <children> 
     <Label text="SAVE" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="0" onMouseClicked="#mouseEntered"> 
      <font> 
       <Font name="System Bold" size="13.0" /> 
      </font> 
     </Label> 
     <Label text="CANCEL" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0" onMouseClicked="#mouseEntered"> 
      <font> 
       <Font name="System Bold" size="13.0" /> 
      </font> 
     </Label> 
     <Separator orientation="VERTICAL" GridPane.columnIndex="1" /> 
    </children> 
    <VBox.margin> 
     <Insets /> 
    </VBox.margin> 
</GridPane> 

注意。しかし、あなたが考慮すべきいくつかあります:

  1. nullが、これは、ノードがGridPaneの子ではないという意味ではありませんもGridPane.getRowIndexのための有効な戻り値であり、GridPane.getColumnIndex、それだけで価値がない有することを意味しますデフォルトから変更されました。これは、値0を使用するのと同じ効果があります。
  2. 条件

    if (colIndex == null && rowIndex == null) 
    

    は他の部分にNullPointerExceptionを防ぐにはあまりにも強いです。例えば、 Separatorがクリックされた場合。

  3. イベントのターゲットは、実際にクリックされたノードです(LabelのスキンではNode)。このノードからは、親ノードがGridPaneになるまで親ノードに行き、GridPaneの正しい子を見つけることができます。
@FXML 
private void mouseEntered(MouseEvent e) { 
    Node target = (Node) e.getTarget(); 
    // traverse towards root until userSelectionGrid is the parent node 
    if (target != userSelectionGrid) { 
     Node parent; 
     while ((parent = target.getParent()) != userSelectionGrid) { 
      target = parent; 
     } 
    } 
    Integer colIndex = userSelectionGrid.getColumnIndex(target); 
    Integer rowIndex = userSelectionGrid.getRowIndex(target); 
    if (colIndex == null || rowIndex == null) { 
     System.out.println("BOO"); 
    } else { 
     System.out.printf("Mouse entered cell [%d, %d]%n", colIndex.intValue(), rowIndex.intValue()); 
    } 
} 

あなたはGridPane制約よりも大きな推奨サイズを設定しない限りLabel sがフルGridPaneを記入しないことに注意してください。これにより、GridPaneのレイアウトが崩れます。回避策は、セル内のLabelの後ろにRegionを配置することです。あなたはこのハンドラ( `Node`)を加え

<GridPane fx:id="userSelectionGrid" prefHeight="44.0" prefWidth="563.0" onMouseClicked="#mouseEntered">     
    <columnConstraints> 
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" fillWidth="true" /> 
     <ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" fillWidth="true" /> 
    </columnConstraints> 
    <rowConstraints> 
     <RowConstraints minHeight="10.0" vgrow="SOMETIMES" fillHeight="true" /> 
    </rowConstraints> 
    <children> 
     <Region GridPane.columnIndex="1" GridPane.rowIndex="0"/> 
     <Region GridPane.columnIndex="0" GridPane.rowIndex="0"/> 
     <Label text="SAVE" GridPane.columnIndex="1" GridPane.halignment="CENTER" GridPane.rowIndex="0"> 
      <font> 
       <Font name="System Bold" size="13.0" /> 
      </font> 
     </Label> 
     <Label text="CANCEL" GridPane.columnIndex="0" GridPane.halignment="CENTER" GridPane.rowIndex="0"> 
      <font> 
       <Font name="System Bold" size="13.0" /> 
      </font> 
     </Label> 
     <Separator orientation="VERTICAL" GridPane.columnIndex="1" /> 
    </children> 
    <VBox.margin> 
     <Insets /> 
    </VBox.margin> 
</GridPane> 
+0

私は何かが欠けているようです。私はあなたが上に提出したことを試して、私はそれの背後にある論理を理解すると信じています。しかし、今私が得たのは、個々のグリッドセル内のラベルだけが認識されているということです。私が達成しようとしているのは、ユーザーが何かをするためにラベルが入っているセルにヒットした場合です。実際のラベルそのものを叩く必要はありません。間違っていると私を訂正してください。私は約5日前にこれを始めました。これ以上のことは学ばなければいけませんが、GridPanesのためのヒエラヒではありません。 –

+0

@EdwardLimセルにサイズ変更可能なノードを追加するのが最も簡単です。完全なセルを埋める 'Label'sのサイズ変更の方法は、' GridPane'レイアウトを簡単に駄目にするため、ノードにセルを追加するのが最も簡単です。答えに 'Region'sの例を追加しました。 – fabian

+0

あなたは男です!どうもありがとうございます! hboxでラベルをラップすることになっていたことがはるかによくなった。乾杯! –

関連する問題