簡體   English   中英

如何動態獲取/設置 JRadionButtonMenuItem?

[英]How to get/set JRadionButtonMenuItem dynamically?

此示例的單選按鈕位於子菜單上,如此處所示。

在此處輸入圖像描述

我想做的是,只要按下“更改單選按鈕”按鈕,它就會更改在菜單上選擇了哪個按鈕。 這意味着它必須首先檢索當前設置的內容,然后選擇另一個。

對於這個簡單的示例,可以將單選按鈕設置為實例變量以使事情變得簡單,但是圖像 JMenu 和相關的子菜單和單選按鈕的生成是程序內部的某個類。 直接訪問不是那么直接。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;

public class RadioButtonsOnMenu 
{
    public static void main(final String args[]) 
    {
        JFrame frame = new JFrame("MenuSample Example");
        JButton jButton = new JButton("Change Radio Button");
        jButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                System.out.println("Changing Radion Button");
                //How to change the JButton on the menu?
                //frame.getMenuBar().......
            }
        });

        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

        JPanel jPanel = new JPanel();
        jPanel.add(jButton);
        
        frame.add(jPanel);
        frame.setJMenuBar(buildMenu());
        frame.setSize(350, 250);
        frame.setVisible(true);
    }
    
    public static JMenuBar buildMenu()
    {
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
        menuBar.add(fileMenu);

        JMenuItem newMenuItem = new JMenuItem("New", KeyEvent.VK_N);
        fileMenu.add(newMenuItem);

        JMenu findOptionsMenu = new JMenu("Options");
        findOptionsMenu.setMnemonic(KeyEvent.VK_O);
        fileMenu.add(findOptionsMenu);

        ButtonGroup directionGroup = new ButtonGroup();
        
        JRadioButtonMenuItem forwardMenuItem = new JRadioButtonMenuItem("Forward", true);
        forwardMenuItem.setMnemonic(KeyEvent.VK_F);
        findOptionsMenu.add(forwardMenuItem);
        directionGroup.add(forwardMenuItem);

        JRadioButtonMenuItem backwardMenuItem = new JRadioButtonMenuItem("Backward");
        backwardMenuItem.setMnemonic(KeyEvent.VK_B);
        findOptionsMenu.add(backwardMenuItem);
        directionGroup.add(backwardMenuItem);
        
        return menuBar;
    }
}

目前尚不清楚如何最好地訪問 JButton 操作中的子菜單和相關的單選按鈕設置。

        jButton.addActionListener(new ActionListener(){
            public void actionPerformed(ActionEvent arg0) {
                System.out.println("Changing Radion Button");
                //How to change the JButton on the menu?
                //frame.getMenuBar().......
            }
        });

我可能會從框架中獲取菜單欄並向下鑽取,如果菜單欄有許多項目、子項目甚至多個單選按鈕組,代碼可能會變得混亂。

有沒有更直接的方法來找出菜單上的哪些單選按鈕被選中,以及更直接的方法來改變它們的值?

您可以做的是將狀態保存在布爾值中。 您可以將偵聽器添加到單選按鈕並在每次選擇其中一個時更改布爾值

boolean isForward = true;

因此,當更改為向后時,您將值設置為 false。 這樣你就不需要每次都獲取單選按鈕的狀態。 在您的按鈕動作偵聽器中,您可以執行以下操作:

jButton.addActionListener(new ActionListener(){
    public void actionPerformed(ActionEvent arg0) {
        System.out.println("Changing Radion Button");

            forwardRadioButton.setState(!isForward);
            backwardRadioButton.setState(isForward);
            iSForward = !isForward;
     }
});

“訣竅”是創建一個應用程序模型來保存菜單單選按鈕的值。

這是我創建的 GUI。

菜單示例

我通過調用SwingUtilities invokeLater方法啟動了 Swing 應用程序。 此方法確保在Event Dispatch Thread上創建和執行 Swing 組件。

我創建了一個JFrame和一個JButton JPanel 我將JFrameJPanel的創建分開。

我創建了一個應用程序模型類來保存一個布爾值,它決定是選擇前進還是后退。 JButton ActionListener切換布爾值的狀態。 updateRadioButtonMenu方法更新單選按鈕菜單項的選定狀態。

這是完整的可運行代碼。

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;

import javax.swing.BorderFactory;
import javax.swing.ButtonGroup;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JRadioButtonMenuItem;
import javax.swing.SwingUtilities;

public class RadioButtonsOnMenu implements Runnable {

    public static void main(String[] args) {
        SwingUtilities.invokeLater(new RadioButtonsOnMenu());
    }
    
    private ApplicationModel model;
    
    private JRadioButtonMenuItem backwardMenuItem;
    private JRadioButtonMenuItem forwardMenuItem;
    
    public RadioButtonsOnMenu() {
        this.model = new ApplicationModel();
    }

    @Override
    public void run() {
        JFrame frame = new JFrame("MenuSample Example");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setJMenuBar(createMenuBar());

        frame.add(createButtonPanel());
        
        frame.pack();
        frame.setLocationByPlatform(true);
        frame.setVisible(true);
    }
    
    private JMenuBar createMenuBar() {
        JMenuBar menuBar = new JMenuBar();
        JMenu fileMenu = new JMenu("File");
        fileMenu.setMnemonic(KeyEvent.VK_F);
        menuBar.add(fileMenu);

        JMenuItem newMenuItem = new JMenuItem("New", KeyEvent.VK_N);
        fileMenu.add(newMenuItem);

        JMenu findOptionsMenu = new JMenu("Options");
        findOptionsMenu.setMnemonic(KeyEvent.VK_O);
        fileMenu.add(findOptionsMenu);

        ButtonGroup directionGroup = new ButtonGroup();

        forwardMenuItem = new JRadioButtonMenuItem("Forward", model.isForward());
        forwardMenuItem.setMnemonic(KeyEvent.VK_F);
        findOptionsMenu.add(forwardMenuItem);
        directionGroup.add(forwardMenuItem);

        backwardMenuItem = new JRadioButtonMenuItem("Backward", !model.isForward());
        backwardMenuItem.setMnemonic(KeyEvent.VK_B);
        findOptionsMenu.add(backwardMenuItem);
        directionGroup.add(backwardMenuItem);

        return menuBar;
    }
    
    private JPanel createButtonPanel() {
        JPanel panel = new JPanel();
        panel.setBorder(BorderFactory.createEmptyBorder(100, 100, 100, 100));
        
        JButton button = new JButton("Change Radio Button");
        button.addActionListener(new ActionListener() {
            @Override
            public void actionPerformed(ActionEvent event) {
                model.setForward(!model.isForward());
                updateRadioButtonMenu();
            }
        });
        panel.add(button);
        
        return panel;
    }
    
    public void updateRadioButtonMenu() {
        forwardMenuItem.setSelected(model.isForward());
        backwardMenuItem.setSelected(!model.isForward());
    }
    
    public class ApplicationModel {
        
        private boolean isForward;
        
        public ApplicationModel() {
            this.isForward = true;
        }

        public boolean isForward() {
            return isForward;
        }

        public void setForward(boolean isForward) {
            this.isForward = isForward;
        }
        
    }

}

我會說你需要做這兩件事:

由於您似乎有很多物品,因此最好將它們存放在其他地方

1 創建一個類來存儲所有項目,然后只傳遞類

public class myItemHolder{
    //declare all the items here instead of at the main
    JButton jButton = new JButton("Change Radio Button");
    ButtonGroup directionGroup = new ButtonGroup();
    JRadioButtonMenuItem forwardMenuItem = new JRadioButtonMenuItem("Forward", true);
    JRadioButtonMenuItem backwardMenuItem = new JRadioButtonMenuItem("Backward");
    
    myListener(myItemHolder items){
        directionGroup.add(forwardMenuItem);
    }
    public ButtonGroup getButtons() {
        return directionGroup;
    }
    public JButton getClick() {
        return jButton;
    }
}

2 像這樣創建自己的動作監聽器類

public class myListener implements ActionListener{
    myItemHolders items;
    myListener(myItemHolder items){
        this.items=items; 
    }
    @Override
    public void actionPerformed(ActionEvent e) {
        //get the radiobutton like so and do what you want with it
        items.getButtons()
    }
}

現在您只需要主要執行此操作:

public class RadioButtonsOnMenu 
{
    public static void main(final String args[]) 
    {
        myItemHolder items = new myItemHolder();
        items.getClick.addActionListener(new myListener(items));
    }
}

在那里您可以輕松訪問所有內容:)
這完全取決於你在哪里聲明你的東西。
或者,如果您只想發送 ButtonGroup,您可以通過稍微更改結構來做到這一點,以便動作偵聽器只請求 ButtonGroup 並給它 items.getButtons() 而不是 items。

這是使用 Enum 狀態跟蹤的另一種可能的方法。 我使用枚舉和地圖來跟蹤應該激活的單選按鈕。 這使它可以在同一個 JMenu 中為相關的單選按鈕項目縮放到您想要的大小。

收音機菜單

package tools;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.HashMap;

import javax.swing.JMenu;
import javax.swing.JRadioButtonMenuItem;

public class RadioMenu<E extends Enum<E>> extends JMenu {
  private static final long serialVersionUID = 1L;
  
  private E currentState;
  private JRadioButtonMenuItem selectedRadioButton;
  
  private HashMap<E, JRadioButtonMenuItem> stateMap;
  
  public RadioMenu() {
    stateMap = new HashMap<E, JRadioButtonMenuItem>();
  }
  
  public RadioMenu(String name) {
    super(name);
    stateMap = new HashMap<E, JRadioButtonMenuItem>();
  }
  
  public void addRadioButton(E associatedState, JRadioButtonMenuItem radioButton) {
    //Set default to first added button
    if(stateMap.isEmpty()) {
      currentState = associatedState;
      radioButton.setSelected(true);
      selectedRadioButton = radioButton;
    }
    
    add(radioButton);
    stateMap.put(associatedState, radioButton);
    radioButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        setState(associatedState);
      }
    });
  }
  
  public void generateButtonsFromEnum(Class<E> enumType) {
    for(E enumValue : enumType.getEnumConstants()) {
      addRadioButton(enumValue, new JRadioButtonMenuItem(enumValue.toString()));
    }
  }
  
  public E getState() {
    return currentState;
  }
  
  public void setState(E newState) {
    currentState = newState;
    selectedRadioButton.setSelected(false);
    
    selectedRadioButton = stateMap.get(newState);
    selectedRadioButton.setSelected(true);
  }
}

RadioMenuTest

import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JPanel;
import javax.swing.SwingUtilities;

import tools.RadioMenu;

public class RadioMenuTest implements Runnable {

  public enum RadioOptions {
    Forward, Backward, Left, Right
  }
  
  public static void main(String[] args) {
    SwingUtilities.invokeLater(new RadioMenuTest());
  }
  
  private RadioMenu<RadioOptions> optionsMenu;
  
  @Override
  public void run() {
    JFrame frame = new JFrame("RadioMenu Test");
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    
    frame.setJMenuBar(createMenuBar());
    frame.getContentPane().add(createButtonPanel());
    
    frame.pack();
    frame.setLocationByPlatform(true);
    frame.setVisible(true);
  }

  private JMenuBar createMenuBar() {
    JMenuBar menuBar = new JMenuBar();
    JMenu fileMenu = new JMenu("File");
    menuBar.add(fileMenu);
    
    optionsMenu = new RadioMenu<RadioOptions>("Options");
    optionsMenu.generateButtonsFromEnum(RadioOptions.class);
    
    fileMenu.add(optionsMenu);
    
    return menuBar;
  }
  
  private JPanel createButtonPanel() {
    JPanel panel = new JPanel(new FlowLayout());
    
    JButton setBackwardButton = new JButton("Set To Backward");
    setBackwardButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        optionsMenu.setState(RadioOptions.Backward);
      }
    });
    panel.add(setBackwardButton);
    
    JButton setRightButton = new JButton("Set To Right");
    setRightButton.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(ActionEvent e) {
        optionsMenu.setState(RadioOptions.Right);
      }
    });
    panel.add(setRightButton);
    
    return panel;
  }
}

暫無
暫無

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

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