2013-06-04 50 views
2

我有以下節點佈局一個JavaFX應用程序:Javafx - 並排TabPanes。如何找到哪個選項卡具有焦點/選擇

  • SplitPane
    • 文本區域
    • SplitPane
      • TabPane
      • TabPane

enter image description here

例如代碼:

SplitPane topBottomSplitPane = new SplitPane(); 

TextArea displayTextArea = new TextArea(); 
SplitPane leftRightSplitPane = new SplitPane(); 

topBottomSplitPane.getItems().addAll(displayTextArea, leftRightSplitPane); 

TabPane leftTabPane = new TabPane(); 
TabPane rightTabPane = new TabPane(); 

leftRightSplitPane.getItems().addAll(leftTabPane, rightTabPane); 

的文本區域,displayTextArea,是顯示一些文本的數據時哪些數據是存在於該打開的懸垂的不可編輯的文本區在兩個TabPanes中的Tab對象,leftTabPane和rightTabPane。 TabPane的SelectionModel是單數,因此每個TabPane每次只能選擇一個Tab。

我遇到的一個限制是,只有一個打開的Tab對象數據應該影響displayTextArea的文本。當只有一個TabPane對象時,通過設置OnSelectionChanged EventHandler並使用isSelected()來確定選擇的更改是選擇更改還是更改,這很容易實現。所選的Tab將是影響displayTextArea的那個Tab。

當有兩個TabPanes我想誰的內容節點當前具有焦點的選項卡,說一個文本字段或形式,其中用戶輸入數據,這將影響displayTextArea的文本。從用戶的角度來看,他們會點擊兩個TabPanes中打開的Tabs,他們點擊的最後一個會影響displayTextArea。但那正是我遇到牆壁的地方。

嘗試和失敗的途徑:其中

  1. 設置某種聽者從選項卡的內容節點的一個通知焦點的改變到另一個選項卡的內容節點,無論TabPane他們都在,然後相應地更新displayTextArea。 - 沒有AddFocusListener方法,我不確定如何使用可用的面向焦點的方法和功能來實現此行爲。

  2. 強制只有1 Tab在多個TabPanes之間的任何時候被選中,並堅持前面提到的OnSelectionChanged EventHandler方法。 - 我不知道該從哪裏開始,我一直無法找到任何東西。

在這種question有改變成焦點在選項卡的內容節點TextField對象的主題,但我無法抓住任何東西從我的後目的是有用的。

我迷失在這裏,不知道如何實現此顯示所需的功能。

回答

2

我想出了一個合理且相當簡單的解決方案:

問題用例:(見圖片中的問題張貼用例參考)

  1. 目前TAB1(位於左TabPane)正在影響顯示。
  2. 用戶單擊Tab4(位於右TabPane中)。

上述用例的問題是,Tab1和Tab4都是當前爲其各自TabPanes選擇的Tabs。因此沒有選項卡的isSelected布爾值已更改,並且它們的onSelectionChanged EventHandler未被觸發。

解決方案是:

  1. 設置的全局引用一個Tab指向影響TextArea的顯示當前標籤。
  2. 對於每個選項卡,在兩個TabPanes中,設置一個onSelectionChanged EventHandler,它首先檢查該選項卡是否成爲選定選項卡或僅丟失選擇。
    1. 如果它只是成爲了選擇的選項卡
      1. 設置全局引用標籤指向自身
      2. 更新根據其內容
    2. 如果不是選擇的標籤 TextArea中顯示
      1. 什麼都不做
  3. 設置一個OnMouseClicked事件處理上都TabPanes
    1. 。如果全球參考選項卡沒有這個TabPane
      1. 設置全局引用標籤內包含指向這個TabPane的當前選擇的選項卡
      2. 更新的文本區顯示根據TabPane當前選擇的Tab的內容
    2. 如果全局引用Tab IS包含在此TabPane中,則不執行任何操作。該onSelectionChanged事件處理程序上的Tab的自己已正確更新文本區域顯示

如果有人需要更多explination或將從編碼示例實現此算法的受益只是發表評論,要求它,我會拋出一個一起爲你真正快速。

0

由於displayTextArea一次只能顯示與四個選項卡之一相關的內容,因此您不需要嘗試將兩組選項卡鏈接在一起。相反,每個選項卡窗格都可以對選擇更改有自己的響應。它們之間唯一的共同點是所有的選擇變化都會調用填充displayTextArea的相同方法。對於這個例子的目的,我們可以調用setDisplayTextAreaContent,我們還假設通過傳遞該方法最近選擇的選項卡,它將知道如何填充displayTextArea。使得這些假設,那我理解正確你的問題的假設之後,解決方案可能是這個樣子......

TabPane tabPane1 = new TabPane(); 
    final Tab tab1 = new Tab(); 
    final Tab tab2 = new Tab(); 
    tabPane1.getTabs().addAll(tab1, tab2); 
    tabPane1.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() 
    { 
     @Override 
     public void changed(ObservableValue<? extends Tab> arg0, Tab arg1, Tab mostRecentlySelectedTab) 
     { 
      if (mostRecentlySelectedTab.equals(tab1)) 
      { 
       setDisplayTextAreaContent(tab1); 
      } 
      if (mostRecentlySelectedTab.equals(tab2)) 
      { 
       setDisplayTextAreaContent(tab2); 
      } 
     } 
    }); 

    TabPane tabPane2 = new TabPane(); 
    final Tab tab3 = new Tab(); 
    final Tab tab4 = new Tab(); 
    tabPane2.getTabs().addAll(tab1, tab2); 
    tabPane2.getSelectionModel().selectedItemProperty().addListener(new ChangeListener<Tab>() 
    { 
     @Override 
     public void changed(ObservableValue<? extends Tab> arg0, Tab arg1, Tab mostRecentlySelectedTab) 
     { 
      if (mostRecentlySelectedTab.equals(tab3)) 
      { 
       setDisplayTextAreaContent(tab3); 
      } 
      if (mostRecentlySelectedTab.equals(tab4)) 
      { 
       setDisplayTextAreaContent(tab4); 
      } 
     } 
    }); 

您可以改爲添加一個偵聽到TabPanes的selectedIndexProperty如果工作得更好對你來說(假設你會知道哪些選項卡在其各自TabPanes內的哪個索引處)。我希望這個答案能幫助你。如果您有任何問題,請告訴我,如果可以,我會很樂意回答。

+0

我忘了提,可以有兩個TabPanes標籤之間的任意數字。這張照片只是整體佈局的一個例子。雖然您的方法可能會改變以考慮到這一點,但仍然會出現問題。檢查這個用例:用戶點擊leftTabPane的tab2,然後點擊rightTabPane的tab2。然後用戶想要返回到leftTabPane的tab2,但它已經是當前選定的選項卡,因此不會引發選擇事件的更改。當前選中兩個TabPanes的tab2,因此從一個到另一個不會拋出事件。 – mcdonasm

0

我使用FXML onSelectionChange方法實現了一個簡單的解決方案,如下所示。

首先,我會考慮整個窗格中只有一個控制器,因此使用的標籤位置或數量並不重要。

對於FXML上的每個選項卡(可以編碼),我添加了onSelectionChanged監聽器方法。問題是,在任何選項卡選擇後,JavaFX會通知兩個相關選項卡(按此順序):新選定的選項卡和先前選定的選項卡。所以,我只是放了一個布爾變量來標記這是第一次還是第二次調用。

注意:請注意,如果此通知政策在將來發生更改,此解決方案可能會有風險。我的控制器代碼的

部分:

private boolean tabSelection = false; 

@FXML void reportsTabSelected(Event e) { 
    if (checkTab()) { 
     System.out.println("Reports Tab is Now Selected"); 
    } 
} 
@FXML void configTabSelected(Event e) { 
    if (checkTab()) { 
     System.out.println("Configs Tab is Now Selected"); 
    } 
} 

private boolean checkTab() { 
    tabSelection = !tabSelection; 
    return tabSelection; 
} 

的標籤FXML的部分:

<Tab text="REPORTS" fx:id="reportsTab" onSelectionChanged="#reportsTabSelected"> 
</Tab> 
<Tab text="CONFIGURATIONS" fx:id="configurationsTab" onSelectionChanged="#configTabSelected"> 
</Tab> 
相關問題