簡體   English   中英

編寫Swing組件:如何添加添加ActionListeners的功能?

[英]Composing Swing Components: How do I add the ability to add ActionListeners?

我想通過組合幾個現有組件來創建一個(簡單的,有希望的)自定義Swing組件。 在我的例子中,它是一個開關開關,由一個JLabel和兩個用於On和Off的JButton組成。 我通過擴展JPanel來開始OnOffSwitch。 構造函數添加子組件,並將其自身設置為按鈕的ActionListener。 該類有一個isOn()方法,用於查詢組件的當前狀態。

我現在想要添加將ActionListeners添加到OnOffSwitch類的功能。 我希望通過擴展像JPanel這樣的Swing組件來免費提供這個功能,但是JPanel沒有這個功能。 通過源代碼的外觀,具有此功能的每個Swing組件都會自行重新實現它:向列表添加偵聽器,觸發ActionEvents等等。

實現我想要的正確方法是什么? 我可以從各種Swing組件中復制/粘貼該代碼(或重寫其中的要點),或者我可以實現自己的OnOffSwitchListener接口。 為了保持一致,似乎所有組件都應該使用ActionListeners。

我會使用一個JToggelButton ,如圖所示這里 ,或委托給包含的按鈕,如@duffymo建議。 如果您確實需要自定義OnOffSwitchEvent ,則會在EventListenerList概述標准接線,其實例包含在每個JComponent

附錄:這是委托給包含兩個按鈕的ButtonGroup的示例。 標簽用符號裝飾,但Icon任何實現都更加靈活。

BttonGroupTest iamge

import java.awt.Color;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.ButtonGroup;
import javax.swing.JComponent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JToggleButton;

/** @see https://stackoverflow.com/questions/6035834 */
public class ButtonGroupTest extends JComponent {

    private static final String ON = "On";
    private static final String OFF = "Off";
    private final JToggleButton bOn = new JToggleButton(ON);
    private final JToggleButton bOff = new JToggleButton(OFF);
    private final JLabel label = new JLabel(" \u2301 ");
    private final ButtonHandler handler = new ButtonHandler();

    public ButtonGroupTest() {
        this.setLayout(new FlowLayout());
        label.setOpaque(true);
        label.setBackground(Color.red);
        label.setFont(label.getFont().deriveFont(36f));
        ButtonGroup bg = new ButtonGroup();
        this.add(bOn);
        bg.add(bOn);
        bOn.setSelected(true);
        bOn.addActionListener(handler);
        this.add(label);
        this.add(bOff);
        bg.add(bOff);
        bOff.addActionListener(handler);
    }

    public void addActionListener(ActionListener listener) {
        bOn.addActionListener(listener);
        bOff.addActionListener(listener);
    }

    private class ButtonHandler implements ActionListener {

        @Override
        public void actionPerformed(ActionEvent e) {
            String cmd = e.getActionCommand();
            if (ON.equals(cmd)) {
                label.setBackground(Color.red);
            } else {
                label.setBackground(Color.black);
            }
        }
    }

    private void display() {
        JFrame f = new JFrame("ButtonGroupTest");
        f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        f.add(this);
        f.pack();
        f.setLocationRelativeTo(null);
        f.setVisible(true);
    }

    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                new ButtonGroupTest().display();
            }
        });
    }
}

我個人認為你不需要自定義Swing組件。 您的UI類不需要擴展任何Swing類; 你不太可能提供很多自定義行為。 (我可能會承認組成其他人的JPanel。)

我寧願構圖而不是繼承。 擁有一個具有Swing數據成員的UI類,並為其提供在需要時添加和刪除Listener的方法。 您可以通過這種方式更改行為,而無需重寫UI類。 它只不過是一個容器。

public class MyUI
{
    private Button b = new Button();

    public void addButtonListener(ActionListener listener) { this.b.addActionListener(listener); }
}

通過源代碼的外觀,每個具有此[ActionListener]功能的Swing組件都會自行重新實現它:向列表添加偵聽器,觸發ActionEvents等等。

是的。 這就是你在編寫自定義Swing組件時必須要做的事情。

如您所說,您可以從現有的Swing組件復制ActionListener代碼,

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM