I am having trouble designing GUI's in an object oriented manner. The following code will help me express my question more clearly:
import javax.swing;
import java.awt.*;
import java.awt.event.*;
public class QuoteOptionsPanel extends JPanel
{
private JLabel quote;
private JRadioButton comedy, philosophy, carpentry;
private String comedyQuote, philosophyQuote, carpentryQuote;
//-----------------------------------------------------------------
// Sets up a panel with a label and a set of radio buttons
// that control its text.
//-----------------------------------------------------------------
public QuoteOptionsPanel()
{
comedyQuote = "Take my wife, please.";
philosophyQuote = "I think, therefore I am.";
carpentryQuote = "Measure twice. Cut once.";
quote = new JLabel (comedyQuote);
quote.setFont (new Font ("Helvetica", Font.BOLD, 24));
comedy = new JRadioButton ("Comedy", true);
comedy.setBackground (Color.green);
philosophy = new JRadioButton ("Philosophy");
philosophy.setBackground (Color.green);
carpentry = new JRadioButton ("Carpentry");
carpentry.setBackground (Color.green);
ButtonGroup group = new ButtonGroup();
group.add (comedy);
group.add (philosophy);
group.add (carpentry);
QuoteListener listener = new QuoteListener();
comedy.addActionListener (listener);
philosophy.addActionListener (listener);
carpentry.addActionListener (listener);
add (quote);
add (comedy);
add (philosophy);
add (carpentry);
setBackground (Color.green);
setPreferredSize (new Dimension(300, 100));
}
//*****************************************************************
// Represents the listener for all radio buttons.
//*****************************************************************
private class QuoteListener implements ActionListener
{
//--------------------------------------------------------------
// Sets the text of the label depending on which radio
// button was pressed.
//--------------------------------------------------------------
public void actionPerformed (ActionEvent event)
{
Object source = event.getSource();
if (source == comedy)
quote.setText (comedyQuote);
else
if (source == philosophy)
quote.setText (philosophyQuote);
else
quote.setText (carpentryQuote);
}
}
}
The above code simply creates a panel with three radio buttons, each corresponding to a quote. It also creates a label which displays a quote. Whenever a button is selected, the text in the label is set to the corresponding quote. I understand this code just fine. I run into trouble trying to modify it. Let's say I want to create the same program, but with the radio buttons stacked vertically on top of one another. Let's also say that I decide to go about this by adding the radio buttons to a panel with a BoxLayout, which I define in its own BoxPanel class. (I would then add the BoxPanel to my QuoteOptionsPanel, which would still contain my quote JLabel.)
So my BoxPanel code might look something like this:
import java.awt.*;
import javax.swing.*;
public class BoxPanel extends JPanel
{
private JRadioButton comedy, philosophy, carpentry;
public BoxPanel()
{
setLayout (new BoxLayout (this, BoxLayout.Y_AXIS));
setBackground (Color.green);
comedy = new JRadioButton ("Comedy", true);
comedy.setBackground (Color.green);
philosophy = new JRadioButton ("Philosophy");
philosophy.setBackground (Color.green);
carpentry = new JRadioButton ("Carpentry");
carpentry.setBackground (Color.green);
ButtonGroup group = new ButtonGroup();
group.add (comedy);
group.add (philosophy);
group.add (carpentry);
QuoteListener listener = new QuoteListener();
comedy.addActionListener (listener);
philosophy.addActionListener (listener);
carpentry.addActionListener (listener);
}
//*****************************************************************
// Represents the listener for all radio buttons.
//*****************************************************************
private class QuoteListener implements ActionListener
{
//--------------------------------------------------------------
// Sets the text of the label depending on which radio
// button was pressed.
//--------------------------------------------------------------
public void actionPerformed (ActionEvent event)
{
Object source = event.getSource();
I do not know what to do here.
}
}
}
So as you can see, I did not know how to define my QuoteListener class. I want it to perform the same function as in the original program I posted, but am unsure of how to make it do so. The label which displays the quote is located in QuoteOptionsPanel, so I do not have access to it. In essence I am asking for the optimal way to change a label on one panel with an event listener belonging to a component on a different panel. I would be immensely grateful for any help you may be able to provide. Please let me know if I have not expressed my question clearly enough.
There are several ways to solve this, but for most all the key is to get and use references. Say the class that holds the JLabel as a private field has a public method,
public void setQuoteLabelText(String text) {
quoteLabel.setText(text);
}
Then you have to pass the reference to the visualized object of this class to your BoxPanel class, either through a constructor parameter or a setXXX(...) setter method. Then your ActionListener can call methods on the object of this class.
1. You can create an instance of the class whose private instance variable you need to
access.
2. Follow the one of the many use of Encapsulation, that is to have private Instance variable
and public getter-setter for that instance variable.
3. Now you can access the private member, by calling the public method on the instance of
the class.
4. One more thing, try using the Group Layout created by NetBeans team in 2005. Use the Window Builder Pro, now free from google.
Related
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 months ago.
Improve this question
I am trying just to get the button to display some text in the console, but whatever i do it isn't working here is the code for the Button class:
public class Button extends JButton implements ActionListener {
JButton button;
Button (){
button = new JButton();
this.setText("Click NOW");
button.addActionListener(this);
this.setForeground(Color.white);
button.setBounds(300, 100, 100, 50);
this.setBackground(Color.red);
this.setBorder(null);
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource()== button) {
System.out.println("Display if you work");
}
}
}
There are no errors displayed and the code compiles correctly, it just isn't displaying the text in the terminal.
This code creates two JButtons, one the button field inside of the class, that you add the action listener to:
public class Button extends JButton implements ActionListener {
JButton button; // here!
Button (){
button = new JButton(); // here!
this.setText("Click NOW");
button.addActionListener(this); // and add the listener here
and the other which is the instance of this class that extends JButton:
// here !!!
public class Button extends JButton implements ActionListener {
// ....
and which is likely the one that is displayed as elsewhere you likely have this code:
Button button = new Button();
and then add this button to the GUI. Again, this "button" is from your Button class which extends JButton but doesn't have the action listener added to it.
You can solve this in one of two ways:
Don't create the new JButton button field inside of your new class and instead add the ActionListener to the this JButton, the instance of this class,
for example:
public class Button1 extends JButton implements ActionListener {
// JButton button;
Button1() {
// button = new JButton();
this.setText("Click NOW");
// button.addActionListener(this);
this.addActionListener(this);
this.setForeground(Color.white);
// button.setBounds(300, 100, 100, 50); // You really don't want to do
// this
this.setBackground(Color.red);
this.setBorder(null);
}
#Override
public void actionPerformed(ActionEvent e) {
// no need for the if block
// if (e.getSource() == button) {
System.out.println("Display if you work");
// }
}
}
Don't create a class that extends JButton but instead create code that creates a single JButton (not two) and add the ActionListener to the same object that is added to the GUI.
I'd go with number 2 myself and make it a method that returns a button with my properties of interest:
private JButton createMyButton(String text) {
JButton button = new JButton(text);
button.setForeground(Color.WHITE);
button.setBackground(Color.RED);
button.setBorder(null);
button.addActionListener(e -> {
System.out.println("Display if you work");
});
return button;
}
Side notes:
Avoid giving your class names that clash with core Java classes, such as class Button which clashes with the java.awt.Button class.
Avoid use of null layouts and setBounds. While null layouts and setBounds() might seem to Swing newbies like the easiest and best way to create complex GUI's, the more Swing GUI'S you create the more serious difficulties you will run into when using them. They won't resize your components when the GUI resizes, they are a royal witch to enhance or maintain, they fail completely when placed in scrollpanes, they look gawd-awful when viewed on all platforms or screen resolutions that are different from the original one.
For that reason you're far better off learning about and using the layout managers. You can find the layout manager tutorial here: Layout Manager Tutorial, and you can find links to the Swing tutorials and to other Swing resources here: Swing Info.
In your actionPerformed method, use equals in the if statement, like this:
if (e.getSource().equals(button)) {
System.out.println("Display if you work");
}
It should work. == doesn't work in this case.
I've been researching communication, event handling and listening across JPanels for a while. I'm going to try and describe my issue without code first, because I feel it's more a design pattern roadblock.
So I have three custom JPanels inside a custom JFrame, each with their own instance variables and Actionlisteners. The ActionListeners at the moment update variables whenever a change happens within them.
But the catch is, I want the ActionListener in one panel to pay attention to elements in other panels. So if I've a box in Panel B and I change its value, I want the label in Panel C to change too.
I've researched a lot on the topic, from stackoverflow answers to documentation on the topic. But I'm having a hard time putting it all together. Especially when I've divided my custom panels into different classes. Can anyone help sum up how it should look?
Ultimately what you need here is to register an ActionListener on Panel B's text box which updates Panel C's label. The fact that Panel B and Panel C are different classes is just a minor bump in the road. The code that sets up this ActionListener simply needs to be able to get hold of references to 1) the text field whose actions we are interested in observing, and 2) the label whose text we are interested in changing.
Now, if Panel B and Panel C weren't separate classes, we would probably just have references to the text field and label handily laying around in member variables of our JFrame window. But Panel B and Panel C are separate classes, so we'll need to ask for their help. Well, actually, not so much ask as demand by dint of a little reprogramming...
First, have Panel B expose the text field with a getter method:
public class PanelB extends JPanel {
// ...
private JTextField textBox;
// ...
public JTextField getTextBox(){
return textBox;
}
}
Then, expose Panel C's label with a getter method:
class PanelC extends JPanel {
// ...
private JLabel label;
// ...
public JLabel getLabel() {
return label;
}
}
Now you can set up an ActionListener in more or less the usual way:
class MyFrame extends JFrame {
PanelB panelB = new PanelB();
PanelC panelC = new PanelC();
public MyFrame()
{
// ...
final JTextField panelBtf = panelB.getTextBox();
final JLabel panelClabel = panelC.getLabel();
panelBtf.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent ae)
{
panelClabel.setText(panelBtf.getText());
}}
);
}
}
I have a JPanel which consists of a dropdown and a text field inside my JFrame. There is a button in my JFrame, when user clicks on that button, application adds new JPanel with the same components i.e. drop down and a text field. So, for this I have created a function which gets called on clicking on the button using ActionListener.
Everything works fine from GUI side but the problem is when user is done with adding JPanels and entering the values in these drop downs and text fields, it will click on Submit button. Upon clicking on Submit button, I should be able to fetch the values from all drop downs and text fields. This is a challenge, since I am using the same functions to create JPanels, I can't call its name to get the values since that will give me the last JPanel values.
Any suggestion how I should go about this? I have added the screenshot of my JFrame and the function to create the JPanel. Any help is appreciated. Thanks.
public static void AddPanel(final Container pane) {
panel1 = new JPanel();
String text = "<html><b>Property" + nooftimes + " :</b></html>";
JLabel label = new JLabel(text);
label.setPreferredSize(new Dimension(80, 30));
panel1.add(label);
panel1.add(new JLabel("Please enter the property"));
DefaultComboBoxModel<String> model = new DefaultComboBoxModel<String>();
model.addElement("value1");
model.addElement("value2");
model.addElement("value3");
model.addElement("value4");
model.addElement("value5");
final JComboBox<String> comboBox1 = new JComboBox<String>(model);
AutoCompleteDecorator.decorate(comboBox1);
comboBox1.setPreferredSize(new Dimension(120, 22));
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField(
"Please enter your value here");
txtfield1.setPreferredSize(new Dimension(200, 22));
panel1.add(txtfield1);
txtfield1.addFocusListener(new FocusListener() {
public void focusGained(FocusEvent e) {
txtfield1.setText("");
}
public void focusLost(FocusEvent e) {
// nothing
}
});
container.add(panel1);
nooftimes++;
frame.revalidate();
frame.validate();
frame.repaint();
}
Screenshot:
}
You could return the JPanel and store it in a List<JPanel>. When you click your submit-Button you are able to iterate through the JPanels and its Components.
public class Application {
private static List<JPanel> panels = new ArrayList<>();
private static Container someContainer = new Container();
public static void main(String[] args) {
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
panels.add(addPanel(someContainer));
submit();
}
public static JPanel addPanel(final Container pane) {
JPanel panel1 = new JPanel();
// shortened code
final JComboBox<String> comboBox1 = new JComboBox<String>();
panel1.add(comboBox1);
final JTextField txtfield1 = new JTextField("Please enter your value here");
txtfield1.setText(String.valueOf(Math.random()));
panel1.add(txtfield1);
return panel1;
}
private static void submit() {
for (JPanel panel : panels) {
Component[] components = panel.getComponents();
for (Component comp : components) {
// Cast comp to JComboBox / JTextField to get the values
if (comp instanceof JTextField) {
JTextField textField = (JTextField) comp;
System.out.println(textField.getText());
}
}
}
}
}
You could simply have a class (extending JPanel) with specific methods to add your components , and to get inputs from user (i.e. get the combo box selected index and text from textfield ).
Every time you add a panel, you don't call a static method, but you create an instance of this class, keeping the reference somewhere (for example adding it to an arraylist).
But you could consider a different scenario: personally i don't like to add components "on fly", you could have a component (for example another JComboBox), where user can select the number of values he needs.
You decide a default value (for example 4), so at the beginning you create 4 panels of your class, and you can use a simple array containing them.
If the user changes the number of panels, you could dispose frame and create a new one.
Of course this solution does not woork good if you want to keep inputs inserted, or if the frame construction takes a lot of time.
Here there is a screenshot of a gui i created: user can select the number of partials, when the choice changes i just recreate the panels below,containing the textfields (which are memorized in a two-dimensional array).
help,
my questions are:
why isn't itemStateChanges triggered, I tried to put it in the inner class ButtonHandler and also in RadioButtonHandler Im having trouble with it, what is the right way to do it?
I want to trigger and check the marked JRadioButtons after the user click the "check" button.
What is the right way to check which button was clicked, I feel like comparing the strings is bad programming practise. Maybe using an ID ?
How should I make a "reset" button(start over), I want to uncheck all radio buttons and run the constructor once again.
Thank you for your help !
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class ExamFrame extends JFrame {
static ArrayList<Question> qArrList;
JRadioButton a1,a2,a3,a4;
public ExamFrame() {
super("Quiz");
setLayout(new GridLayout(0, 1));
GridBagConstraints gbc = new GridBagConstraints();
Exam exam = new Exam();
qArrList = exam.getExam();
int count=0;
for(Question q : qArrList){
count++;
JLabel questionLabel = new JLabel(count+". "+q.getQustion()); //swing constant ?
ArrayList<String> ansRand = q.getAllRandomAns();
a1 = new JRadioButton(ansRand.get(0));
a2 = new JRadioButton(ansRand.get(1));
a3 = new JRadioButton(ansRand.get(2));
a4 = new JRadioButton(ansRand.get(3));
add(questionLabel);
add(a1);add(a2,gbc);add(a3);add(a4);
ButtonGroup radioGroup = new ButtonGroup(); //logical relationship
radioGroup.add(a1);radioGroup.add(a2);radioGroup.add(a3);radioGroup.add(a4);
}
//buttons:
JButton checkMe = new JButton("Check Exam");
JButton refresh = new JButton("Start Over");
ButtonHandler handler = new ButtonHandler();
checkMe.addActionListener(handler);
refresh.addActionListener(handler);
add(checkMe);
add(refresh);
}
/** Listens to the radio buttons. */
public class ButtonHandler implements ActionListener
{
public void actionPerformed (ActionEvent e) {
if(e.getActionCommand().equals("Start Over")){ //id?
//how to do this?
}
else{
RadioButtonHandler handler = new RadioButtonHandler();
a1.addItemListener(handler);
System.out.println("success?");
}
JOptionPane.showMessageDialog(ExamFrame.this, String.format("You pressed: %s", e.getActionCommand()));
}
public void itemStateChanged(ItemEvent e) //can i add it here?
{
JOptionPane.showMessageDialog(ExamFrame.this, String.format("yes?"));
System.out.println("success!");
}
}
public class RadioButtonHandler implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
JOptionPane.showMessageDialog(ExamFrame.this, String.format("radio state changed"));
}
}
}
why "itemStateChanges" isn't triggered, i tried to put it in the inner
class "ButtonHandler" and also in "RadioButtonHandler" Im having
troubles with it, what is the right way to do it? I want to trigger
and check the marked JRadioButtons after the user click the "check"
button.
ButtonHandler is implemented with ActionListener only:
public class ButtonHandler implements ActionListener{}
The itemStateChanged(ItemEvent) function belongs to ItemListener. This function is triggered if state of a source component to which this listener is registered gets changed. So implement the ItemListener. However, one more thing to note, that JButton doesn't respond to ItemListener but JRadioButton will. Because this Item events are fired by components that implement the ItemSelectable interface. Some example of such components are: check boxes, check menu items, toggle buttons and combo boxes including Radio Buttons as mentioned above.
What is the right way to check which button was clicked, i feel like
comparing the strings is wrong programming. Maybe using an ID
Well using the event source function: e.getSource(), check whither the type of the source is your expected type and cast it to appropriate type. And then you can use getName(String) function and check the name you were expecting. Of-course you should assign the name using setName(String) after initialization of component. Or using the component reference directly if it is declared in the Class context and you have direct access to the component.
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getSource() instanceof JCheckBox)
{
JCheckBox checkBox = (JCheckBox)e.getSource();
if(checkBox.getName().equals("expectedName"))
; // do my thing
}
}
How should i make a "reset" button(start over), i want to uncheck all
radio buttons and run the constructor once again.
Well you are working with ButtonGroup. And ButtonGroup has a nice function: clearSelection() to help with whatever(I could not understand the part: run the constructor part) you want.
Edit: As you wanted me to see an ItemListener implemented class, Yes i can see that But:
i can not see that you have actually registered an instance of that class(a1.addItemListener(handler);) to any component before performing any action on the component to which ButtonHandler is registered to: checkMe, refresh
In addition to that, in this action performed function, you are checking with
action command, which you haven't even set with JButton.setActionCommand(String) function. You should not assign a (Item)listener depending on event-occurrence of another (Action)listener.
Tutorial:
How to Write an ItemListener
How to Write an ActionListener
How to Use the ButtonGroup Component
When displaying a group of JRadioButtons, initially none of them is selected (unless you programmatically enforce that). I would like to be able to put buttons back into that state even after the user already selected one, i.e., none of the buttons should be selected.
However, using the usual suspects doesn't deliver the required effect: calling 'setSelected(false)' on each button doesn't work. Interestingly, it does work when the buttons are not put into a ButtonGroup - unfortunately, the latter is required for JRadioButtons to be mutually exclusive.
Also, using the setSelected(ButtonModel, boolean) - method of javax.swing.ButtonGroup doesn't do what I want.
I've put together a small program to demonstrate the effect: two radio buttons and a JButton. Clicking the JButton should unselect the radio buttons so that the window looks exactly as it does when it first pops up.
import java.awt.Container;
import java.awt.GridLayout;
import java.awt.event.*;
import javax.swing.*;
/**
* This class creates two radio buttons and a JButton. Initially, none
* of the radio buttons is selected. Clicking on the JButton should
* always return the radio buttons into that initial state, i.e.,
* should disable both radio buttons.
*/
public class RadioTest implements ActionListener {
/* create two radio buttons and a group */
private JRadioButton button1 = new JRadioButton("button1");
private JRadioButton button2 = new JRadioButton("button2");
private ButtonGroup group = new ButtonGroup();
/* clicking this button should unselect both button1 and button2 */
private JButton unselectRadio = new JButton("Unselect radio buttons.");
/* In the constructor, set up the group and event listening */
public RadioTest() {
/* put the radio buttons in a group so they become mutually
* exclusive -- without this, unselecting actually works! */
group.add(button1);
group.add(button2);
/* listen to clicks on 'unselectRadio' button */
unselectRadio.addActionListener(this);
}
/* called when 'unselectRadio' is clicked */
public void actionPerformed(ActionEvent e) {
/* variant1: disable both buttons directly.
* ...doesn't work */
button1.setSelected(false);
button2.setSelected(false);
/* variant2: disable the selection via the button group.
* ...doesn't work either */
group.setSelected(group.getSelection(), false);
}
/* Test: create a JFrame which displays the two radio buttons and
* the unselect-button */
public static void main(String[] args) {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
RadioTest test = new RadioTest();
Container contentPane = frame.getContentPane();
contentPane.setLayout(new GridLayout(3,1));
contentPane.add(test.button1);
contentPane.add(test.button2);
contentPane.add(test.unselectRadio);
frame.setSize(400, 400);
frame.setVisible(true);
}
}
Any ideas anyone? Thanks!
You can do buttonGroup.clearSelection().
But this method is available only since Java 6.
The Javadoc of the class ButtonGroup itself gives some hint about how this can be achieved:
From the API doc of class ButtonGroup:
Initially, all buttons in the group are unselected. Once any button is selected, one button is always selected in the group.There is no way to turn a button programmatically to "off", in order to clear the button group. To give the appearance of "none selected", add an invisible radio button to the group and then programmatically select that button to turn off all the displayed radio buttons.
Try adding a third invisible button to the button group. When you want to "deselect", select the invisible one.
Or you can use Darryl's Select Button Group which doesn't require you to use an "invisible button".
You can use a click counter:
private ButtonGroup radioGroup = new javax.swing.ButtonGroup();
private JRadioButton jRadioBtn1 = new javax.swing.JRadioButton();
private int clickCount = 0;
private void jRadioBtn1Clicked(java.awt.event.MouseEvent evt) {
// Remove selection on a second click
if (jRadioBtn1.isSelected()) {
if (++clickCount % 2 == 0) {
radioGroup.clearSelection();
}
}
}
You can use setselected(false) method to unselect the previous selected button.
I don't know if this will help but have you tried to use doClick() method?
jRadioButtonYourObject.doClick();
Input - NONE
Return- void
I had a similar problem and tried everything in this thread to no avail. So I took a look at all the methods of JRadioButton and found that method from JRadioButton's parent class.
In my program, I had two radio button independent of each other and it was programed so that only one was selected.
After the user enters data and hits a button the program clears all text fields and areas and deselects the radio button. The doClick() did the job of deselecting the radio button for me; the method "performs a "click"."
I know yours is different and you probably would have to program the doClick() method for every radio button that is selected.
http://docs.oracle.com/javase/7/docs/api/javax/swing/AbstractButton.html
search for doClick()
When you want to deselect, select invisible. For that you add a third invisible button to the button group.
In my case I use Jgoodies project to bind GUI components to Java model.
The RadioButton component is bound to a field
class Model {
private SomeJavaEnum field; // + getter, setter
}
In such case ButtonGroup.clearSelection doesn't work since the old value still retains in the model. Straightforward solution was to simply setField(null).
Use this helper class SelectButtonGroup.java
direct link to the class source
import java.awt.*;
import java.awt.event.ActionListener;
import javax.swing.*;
public class SelectUnselected extends JPanel {
private static String birdString = "Bird";
private static String catString = "Cat";
private static Integer selectedIndex = -1;
private static AbstractButton hiddenButton = new JRadioButton(catString);
private final static AbstractButton birdButton = new JRadioButton(birdString);
private final static AbstractButton catButton = new JRadioButton(catString);
//Group the radio buttons.
private SelectButtonGroup group = new SelectButtonGroup();
public SelectUnselected() {
super(new BorderLayout());
//Create the radio buttons.
hiddenButton.setVisible(false);
hiddenButton.setSelected(true);
group.add(birdButton);
group.add(catButton);
group.add(hiddenButton);
ActionListener sendListener = e -> {
checkSelectedRadioButten();
};
birdButton.addActionListener(sendListener);
catButton.addActionListener(sendListener);
hiddenButton.addActionListener(sendListener);
//Put the radio buttons in a column in a panel.
JPanel radioPanel = new JPanel(new GridLayout(0, 1));
radioPanel.add(birdButton);
radioPanel.add(catButton);
add(radioPanel, BorderLayout.LINE_START);
setBorder(BorderFactory.createEmptyBorder(20,20,20,20));
}
public void checkSelectedRadioButten(){
System.out.println("selectedIndex = " + selectedIndex + "\ngroup.getSelectedButton() = " + group.getSelectedIndex());
if(group.getSelectedIndex() == selectedIndex){
hiddenButton.setSelected(true);
selectedIndex = -1;
System.out.println("getText = " + group.getSelectedButton().getText());
}else{
selectedIndex = group.getSelectedIndex();
System.out.println("getText = " + group.getSelectedButton().getText());
}
}
public static void main(String[] args) {
JFrame frame = new JFrame("RadioButtonDemo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JComponent newContentPane = new SelectUnselected();
frame.setContentPane(newContentPane);
frame.pack();
frame.setVisible(true);
}
}
You can use your own ButtonGroup (1), or use modified instance (2), like this:
ONLY SINCE JAVA 6:
(1) public class NoneSelectedButtonGroup extends ButtonGroup {
#Override
public void setSelected(ButtonModel model, boolean selected) {
if (selected) {
super.setSelected(model, selected);
} else {
clearSelection();
}
}
}
(2) ButtonGroup chGroup = new ButtonGroup() {
#Override
public void setSelected(ButtonModel m, boolean b) {
if (!b) clearSelection();
else
super.setSelected(m, b);
}
};
take from https://blog.frankel.ch/unselect-all-toggle-buttons-of-a-group/