2012-05-05 76 views
0

我想擴展一些Swing組件並覆蓋與其狀態交互的方法(JComboBox的setSelectedIndex,JCheckBox的setSelected等)。 JCheckBox有問題。我已經覆蓋了setSelected方法,但它似乎並沒有調用當用戶通過UI更改JCheckBox狀態。我可以通過調用方法來更改JCheckBox狀態,但似乎GUI使用另一種方式來更改它的狀態。我怎麼能在我的課堂上發現這個事件? 與其他類的Swing一切正常,所有重寫的方法都能正常工作。javax.swing.JCheckBox setSelected不從GUI調用

public class MyCheckBox extends JCheckBox { 
    @Override 
    public void setSelected(boolean selected) { 
     //Method is not performed when MyCheckBox is clicked 
     super.setSelected(selected); 
    } 
} 

UP: 我做了它具有支持組件包'撤銷/重做的行動。我只是將addUndoableEditListener(UndoableEditListener l)方法添加到所有組件,因此實現隱藏在我的組件中。這就是爲什麼我擴展Swing組件而不是使用動作偵聽器的原因。

+0

我的第一個問題:爲什麼擴展這些組件而不是簡單地使用它們? –

+1

爲什麼你認爲GUI調用這種方法來設置值?如果您想在發生更改時啓動某個操作,則應該使用適當的偵聽器。 – SJuan76

+0

我自己,我會擴展我添加到我的JCheckBox的AbstractAction。 –

回答

2

如果你想簡單地聽這種變化 - 使用的ItemListener(它會聽甚至由ButtonGroup的變化作出或的setSelected方法調用事件):

checkBox.addItemListener (new ItemListener() 
{ 
    public void itemStateChanged (ItemEvent e) 
    { 
     System.out.println (isSelected()); 
    } 
}); 

或者,如果你想添加一個ActionListener僅從「UI」接收更改。

但是,如果你真的想知道複選框如何改變從「UI」的狀態......

JCheckBox的是比每個國家適當的圖標簡單的按鈕沒有礦石,所以我們應該看到的JButton事件

沒有任何關於聽着一個JButton類鼠標 - 其當前ButtonUI

裏面藏在BasicButtonUI類,你可以找到監聽器添加到它:

protected void installListeners(AbstractButton b) { 
    BasicButtonListener listener = createButtonListener(b); 
    if(listener != null) { 
     b.addMouseListener(listener); 
     b.addMouseMotionListener(listener); 
     b.addFocusListener(listener); 
     b.addPropertyChangeListener(listener); 
     b.addChangeListener(listener); 
    } 
} 

在BasicButtonListener在鼠標釋放:

public void mouseReleased(MouseEvent e) { 
if (SwingUtilities.isLeftMouseButton(e)) { 
    // Support for multiClickThreshhold 
     if (shouldDiscardRelease) { 
     shouldDiscardRelease = false; 
     return; 
    } 
    AbstractButton b = (AbstractButton) e.getSource(); 
    ButtonModel model = b.getModel(); 
    model.setPressed(false); 
    model.setArmed(false); 
    } 
} 

因此該事件被髮送到按鈕的內部設置ButtonModel的。要捕捉它,你將不得不更換ButtonModel的按鈕內部/檢查自己的一個:

check.setModel (new DefaultButtonModel() 
{ 
    public void setSelected (boolean b) 
    { 
     super.setSelected (b); 
    } 
}); 
+0

謝謝,現在我開始明白它是如何工作的。 – user1376983

+0

請記住,每個Swing組件都有它自己的UI類,並且可能會有一些/ all/none動作/鼠標/鍵監聽器。這僅取決於組件類型以及Swing開發人員創建的方式。無論如何,如果您將JDK資源追加到您的IDE並在需要時查看它們,那麼找到任何相關信息都相當簡單。 –

1

儘管所有的評論都是相關的,並且有可能是沒有必要擴展這些組件,我做了一個快速測試確定單擊按鈕時遵循的代碼路徑(出於好奇)。以下代碼片段

import javax.swing.JCheckBox; 
import javax.swing.JFrame; 
import javax.swing.JToggleButton; 
import java.awt.EventQueue; 

public class JCheckBoxTest { 

    private static JCheckBox createCheckBox(){ 
    JCheckBox checkBox = new JCheckBox(); 
    checkBox.setModel(new JToggleButton.ToggleButtonModel(){ 
     @Override 
     public void setSelected(boolean b) { 
     Thread.dumpStack(); 
     super.setSelected(b); 
     } 
    }); 
    return checkBox; 
    } 

    public static void main(String[] args) { 
    EventQueue.invokeLater(new Runnable() { 
     @Override 
     public void run() { 
     JFrame testFrame = new JFrame("TestFrame"); 
     testFrame.add(createCheckBox()); 
     testFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
     testFrame.pack(); 
     testFrame.setVisible(true); 
     } 
    }); 
    } 
} 

允許在按鈕後面的模型的選定狀態發生變化時確定堆棧跟蹤。堆棧跟蹤顯示以下相關部分

at JCheckBoxTest$1.setSelected(JCheckBoxTest.java:19) 
at javax.swing.JToggleButton$ToggleButtonModel.setPressed(JToggleButton.java:289) 
at javax.swing.plaf.basic.BasicButtonListener.mouseReleased(BasicButtonListener.java:252) 
at java.awt.Component.processMouseEvent(Component.java:6505) 
at javax.swing.JComponent.processMouseEvent(JComponent.java:3321) 

所以基本上聽者直接與按鈕模型進行交互。