Ten przykład ma przyciski radiowe znajdujące się w podmenu, jak widać tutaj. To, co chciałbym zrobić, to za każdym razem, gdy zostanie naciśnięty przycisk „Zmień przycisk radiowy”, zmieni to, który przycisk jest wybrany w ...

0
Unhandled Exception 24 czerwiec 2021, 16:08

4 odpowiedzi

Najlepsza odpowiedź

„Sztuczka” polega na stworzeniu modelu aplikacji do przechowywania wartości przycisków opcji menu.

Oto GUI, które stworzyłem.

MenuSample Example

Rozpocząłem aplikację Swing z połączeniem do metody SwingUtilities invokeLater. Metoda ta zapewnia, że składniki huśtawki są tworzone i wykonane na Wątek wysyłki zdarzeń.

Utworzyłem JFrame i JButton JPanel. Oddzieliłem tworzenie JFrame i JPanel.

Stworzyłem klasę modelu aplikacji do przechowywania wartości logicznej, która określa, czy wybrana jest opcja naprzód czy wstecz. JButton ActionListener przełącza stan wartości logicznej. Metoda updateRadioButtonMenu aktualizuje wybrany stan elementów menu przycisku radiowego.

Oto kompletny kod, który można uruchomić.

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
Gilbert Le Blanc 24 czerwiec 2021, 13:40

Co możesz zrobić, to zapisać stan w wartości logicznej. Możesz dodać słuchacza do przycisków radiowych i zmieniać wartość logiczną za każdym razem, gdy zostanie wybrany jeden z nich

boolean isForward = true;

Więc po zmianie na wstecz ustawiasz wartość na false. W ten sposób nie musisz za każdym razem sprawdzać stanu przycisków radiowych. W swoim nasłuchu akcji przycisku możesz wtedy zrobić:

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

            forwardRadioButton.setState(!isForward);
            backwardRadioButton.setState(isForward);
            iSForward = !isForward;
     }
});
1
David 24 czerwiec 2021, 13:34

Powiedziałbym, że musisz zrobić te dwie rzeczy:

Ponieważ wydaje się, że masz dużo przedmiotów, najlepiej przechowywać je w innym miejscu

1 Utwórz klasę do przechowywania wszystkich przedmiotów, a następnie po prostu zdaj klasę

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 Stwórz własną klasę nasłuchiwania akcji, tak

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()
    }
}

Teraz wystarczy to zrobić w głównej mierze:

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

A tam masz łatwy dostęp do wszystkiego :)
Wszystko zależy od tego, gdzie zadeklarujesz swoje rzeczy.
Lub jeśli chcesz wysłać tylko ButtonGroup, możesz to zrobić, zmieniając nieco strukturę, aby nasłuchiwacz akcji żądał tylko ButtonGroup i nadał mu items.getButtons() zamiast items.

1
The Blind Hawk 24 czerwiec 2021, 14:09

Oto inny możliwy sposób na zrobienie tego za pomocą śledzenia stanu Enum. Używam Enum i Mapy do śledzenia przycisku radiowego, który powinien być aktywowany. Pozwala to na dowolnie duże skalowanie dla powiązanych elementów przycisku radiowego w tym samym JMenu.

Menu radia

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;
  }
}
1
Tim Hunter 29 czerwiec 2021, 14:21