How would I go about setting the number of selectable items of JRadioButtons?
I tried adding the radiobuttons to a buttongroup, and overriding the buttongroup class, but cant figure which method to modify.
Basically, I want to allow selection of only two radiobuttons. I am aware this is possible using checkboxes, but I need the "roudness" of the radiobuttons, and figure this should be an easier way to go, instead of modifying the look and feel of the checkbox.
Thanks a bunch! :)
Here is an example:
package com.haraj.test.java;
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.util.LinkedList;
import java.util.Queue;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.SwingUtilities;
public class JRadioButtonTest
{
public static void main(String[] args)
{
SwingUtilities.invokeLater(new Runnable()
{
#Override
public void run()
{
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel contentPane = (JPanel) frame.getContentPane();
contentPane.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
contentPane.setLayout(new GridLayout());
final Queue<JRadioButton> selectedButtons = new LinkedList<JRadioButton>();
ItemListener listener = new ItemListener()
{
#Override
public void itemStateChanged(ItemEvent e)
{
JRadioButton newButton = (JRadioButton) e.getSource();
if(e.getStateChange() == ItemEvent.DESELECTED) selectedButtons.remove(newButton);
else
{
if(selectedButtons.size() == 2)
{
JRadioButton oldButton = selectedButtons.poll();
if(oldButton != newButton) oldButton.setSelected(false);
}
selectedButtons.add(newButton);
}
}
};
JRadioButton[] buttons = new JRadioButton[6];
for(int i = 0; i < buttons.length; i++)
{
buttons[i] = new JRadioButton();
buttons[i].addItemListener(listener);
contentPane.add(buttons[i]);
}
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
});
}
}
One way would be to add an ActionListener to each individual radiobutton which updates a counter if the button is selected.
You can read about jRadioButton functions HERE.
You can then do a function if the counter hits two which makes the other buttons grey (unclickable) using:
.setActionCommand("disable");
You can find more info about the possible methods in the API.
Related
I'm not sure what exactly I am doing wrong but I keep getting an error with the ButtonHandler. I have a GUI class and a GUI Test class. The GUI class is the first one and the GUI_Test class is at the bottom. I am using NetBeans IDE 11.0. Everything else works on here but the ButtonHandler. I believe I followed the directions wrong or something because it just keeps telling me to create a new class for the ButtonHandler or break it up. But neither of those things are what I want.
The checkboxes also will not appear in the output text area when you run it.
package javaapplication20;
import java.awt.FlowLayout;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ButtonGroup;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextArea;
public class Week3GUI extends JFrame {`
//variables
private JRadioButton radCoffee, radTea;
private JCheckBox chkFootball, chkBasketball, chkBaseball;
private JTextArea txtMessage;
public Week3GUI()
{
//instantiate the GUI components
// this sets 5 rows, 20 columns as default size
txtMessage = new JTextArea(5,20);
radCoffee =new JRadioButton("Coffee");
radTea =new JRadioButton("Tea");
//instantiate checkboxes
chkFootball =new JCheckBox("football");
chkBasketball =new JCheckBox("basketball");
chkBaseball =new JCheckBox("baseball");
//create panel for the radio buttons
JPanel p1 =new JPanel();
JPanel p2 =new JPanel();
//set layout for the panel and add the components
p1.setLayout(new FlowLayout());
p1.add(radCoffee);
p1.add(radTea);
// set layout for the panel and add the components
p2.setLayout(new FlowLayout());
p2.add(chkFootball);
p2.add(chkBasketball);
p2.add(chkBaseball);
//need to group the buttons together
ButtonGroup b =new ButtonGroup();
b.add(radCoffee);
b.add(radTea);
//add event handlers for radio buttons
RBHandler rb =new RBHandler();
radCoffee.addItemListener(rb);
radTea.addItemListener(rb);
//use grid layout for the frame
//1 column, multiple rows
setLayout(new GridLayout(0,1));
//first "row" of the frame is the label
add(new JLabel("Which do you like?"));
//next "row" is the panel p1 with radio buttons
add(p1);
//third "row" is the textfield
add(p2);
// fourth "row" is the textfield
add(txtMessage);
} //end constructor
private class RBHandler implements ItemListener
{
#Override
public void itemStateChanged(ItemEvent e)
{
if(radCoffee.isSelected())
txtMessage.setText("You like coffee");
else if(radTea.isSelected())
txtMessage.setText("You like tea");
}
private void processChoices()
{
//"read" the radio buttons first
if(radCoffee.isSelected())
txtMessage.setText("You like\ncoffee");
else if (radTea.isSelected())
txtMessage.setText("You like\ntea");
else
{
JOptionPane.showMessageDialog(null,"Must select a beverage",
"Error",JOptionPane.ERROR_MESSAGE);
return; //do NOT continue this method
}
//now read the check boxes and APPEND to textarea
if(chkFootball.isSelected())
txtMessage.append("\nfootball");
if(chkBasketball.isSelected())
txtMessage.append("\nbasketball");
if(chkBaseball.isSelected())
txtMessage.append("\nbaseball");
}
private class ButtonHandler implements ActionListener
{
ButtonHandler h = new ButtonHandler();
#Override
public void actionPerformed(ActionEvent actionEvent)
{
processChoices();
radCoffee.addActionListener(h);
radTea.addActionListener(h);
chkFootball.addActionListener(h);
chkBaseball.addActionListener(h);
chkBasketball.addActionListener(h);
}
}
}
} //end class
package javaapplication20;
import javax.swing.JFrame;
public class Week3GUI_Test {
public static void main(String[] args)
{
Week3GUI g =new Week3GUI();
g.setSize(300,200);
g.setVisible(true);
g.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
}
I'm failing to understand why my yankee and whiskey JButtons aren't working. Right now I only want them to close the program when romeo is greater than 1 and sierra is greater than 1.
import java.awt.*;
import java.lang.*;
import javax.swing.*;
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.InputEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.SwingUtilities;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.image.BufferedImage;
import java.io.*;
import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.JPanel;
import java.util.Scanner;
public class AlphaMenu extends JFrame /*implements actionPerformed*/
{
private GraphicsDevice gamma;
public JButton charlie, zulu, yankee, xray;
public JFrame beta;
public JPanel delta, echo, foxtrot, golf, hotel;
public JTextArea whiskey, victor;
public BorderLayout uniform;
public ImageIcon bg;
public JLabel tango;
public int sierra, romeo;
public Integer quebec, papa;
public ActionEvent oscar;
public ActionEvent november;
public AlphaMenu()
{
//Initialization of Objects
charlie = new JButton("EXIT");
zulu = new JButton("Enter Time");
yankee = new JButton("Enter Amount of Money");
xray = new JButton("Calculate");
sierra = 0;
romeo = 0;
quebec = new Integer(0);
papa = new Integer(0);
whiskey = new JTextArea(2, 15);
victor = new JTextArea(2, 15);
bg = new ImageIcon("background.gif");
beta = new JFrame();
delta = new JPanel();
echo = new JPanel();
foxtrot = new JPanel();
golf = new JPanel();
hotel = new JPanel();
uniform = new BorderLayout();
ImageIcon bg = new ImageIcon("background.gif");
tango = new JLabel("");
tango.setIcon(bg);
//Modification of panels
beta.add(delta, uniform.PAGE_END);
beta.add(golf, uniform.PAGE_START);
beta.add(echo, uniform.LINE_START);
beta.add(foxtrot, uniform.LINE_END);
beta.add(hotel, uniform.CENTER);
golf.add(tango);
//Modification of JButton charlie & adding of JButtons
charlie.setPreferredSize(new Dimension(100, 50));
delta.add(charlie);
charlie.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
System.exit(0);
}
});
echo.add(whiskey);
echo.add(yankee);
foxtrot.add(victor);
foxtrot.add(zulu);
//Modification of JFrame beta
beta.setUndecorated(true);
beta.setExtendedState(JFrame.MAXIMIZED_BOTH);
beta.setResizable(false);
beta.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
beta.setVisible(true);
}
public void buttonSetup() throws NumberFormatException
{
//Modification of JButton yankee & JTextArea whiskey & int sierra
romeo = quebec.parseInt(whiskey.getText());
yankee.setPreferredSize(new Dimension(300, 50));
yankee.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent oscar)
{
System.exit(0);
}
});
//Modification of JButton zulu & JTextArea victor & int romeo
sierra = papa.parseInt(victor.getText());
zulu.setPreferredSize(new Dimension(300, 50));
zulu.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent november)
{
System.exit(0);
}
});
}
public void actionPerformed(ActionEvent e)
{
}
public static void main(String[] args)
{
new AlphaMenu();
}
}
So, you have two JTextArea (JTextField would probably be better) and a button. you want some buttons to execute exit when the text of both textareas is an integer greater than 1.
seems that your buttonSetup() function isn't called anywhere.
Anyway, I'd create an ActionListener that reads the texts, converts to integer, tests your condition and executes exit(). This ActionListener should be added to all the buttons you want to perform the action
final ActionListener al = new ActionListener() {
public void actionPerformed(ActionEvent event) {
try {
final int intRomeo = Integer.parseInt(romeo.getText());
final int intSierra = Integer.parseInt(sierra .getText());
if (intRomeo > 1 && intSierra > 1) {
// whatever you want to do
System.exit(0);
}
} catch (/*NumberFormat*/ Exception e) {
// ...not integers
}
};
}
whiskey.addActionListener(al);
yankee.addActionListener(al);
I have to add: the variable names you are using are really bad. Consider choosing something more significative.
For starters, readability...it would probably help the "sloppiness" if you used more appropriate names for your variables, indented different sections of code, and used comments to help describe sections in layman's terms. Maybe "btnExit" and "btnCalculate" would help make things a little easier to navigate.
Moving forward, you also don't have two different classes here, you have one class with several methods. Which is fine but wanted to inform you of that. I think maybe you need to add the buttons to their panels after your action listeners and formatting for each button. I'm just getting into some swing stuff myself and I've noticed moving the .add() functions around in the code has helped when I run into issues like this. Try the following bellow. I indented and used new naming conventions for the comments, but the code uses your convention.
//add the pnlEcho to frmBeta
beta.add(echo, uniform.LINE_START);
//format btnYankee
yankee.setPreferredSize(new Dimension(300, 50));
//btnYankee action listener
yankee.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) { //default action event
System.exit(0); //you could use this
beta.dispose(); //or you could dispose the frame and
//do more work after it is gone
}
});
//add btnYankee to pnlEcho
echo.add(yankee);
I'm failing to understand why my yankee and whiskey JButtons aren't
working
The variable wiskey is not JButton type but JTextArea type.
I am writing an application in Java and am using Netbeans IDE. I have set two JCheckBox (chk1 and chk2) and two JTextField (jtextfield1 and jtextfield2). I want that if I check chk1, jtextfield2 will be set to uneditable and if I chk2, jtextfield2 will be set to editable and vice versa.
How to use JCheckBox to make JTextField editable and vice versa?
With the code below, it works alright but if i check the chk2 all the text fields are set to uneditable.
private void ckDepoActionPerformed(java.awt.event.ActionEvent evt) {
if(ckDepo.isSelected()){
txtDeposit.setEditable(false);
}
else{
txtWithdraw.setEditable(true);
}
}
private void ckWithdrawActionPerformed(java.awt.event.ActionEvent evt) {
transact="withdraw";
if(ckWithdraw.isSelected()){
txtWithdraw.setEditable(false);
}
else{
txtDeposit.setEditable(true);
}
}
Suggestions:
I would use JRadioButtons all added to the same ButtonGroup. This way selecting one JRadioButton will unselect all the others.
I would give each JRadioButton an ItemListener that inside it enabled or disabled its adjacent JTextField.
For example:
import java.awt.GridLayout;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import javax.swing.ButtonGroup;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.JTextField;
public class RadioBtnMayhem {
private static final int COLUMNS = 10;
public static void main(String[] args) {
JPanel mainPanel = new JPanel(new GridLayout(0, 1));
ButtonGroup btnGroup = new ButtonGroup();
int fieldCount = 5;
for (int i = 0; i < fieldCount; i++) {
JRadioButton radioBtn = new JRadioButton();
btnGroup.add(radioBtn);
final JTextField textField = new JTextField(COLUMNS);
textField.setEnabled(false);
radioBtn.addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
textField.setEnabled(e.getStateChange() == ItemEvent.SELECTED);
}
});
JPanel radioFieldPanel = new JPanel();
radioFieldPanel.add(radioBtn);
radioFieldPanel.add(textField);
mainPanel.add(radioFieldPanel);
}
JOptionPane.showMessageDialog(null, mainPanel);
}
}
I want to remove a certain botton using MouseListener from a matrix of bottons and add a JLabel in the empty, so I use:
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
public MyClass(){
object = new Object();
bottons = new JButton[5][5];
labels = new JLabel[5][5];
myPanel = new JPanel();
myPanel.setLayout(new GridLayout(5,5));
click =false;
for(int i = 0 ; i<5 ; i++){
for(int j = 0; j<5 ; j++){
myPanel.add(bottons[i][j] = new JButton());
}
}
}
public void mouseReleased(MouseEvent e)
if(click){
remove(bottons[object.getx][object.gety]);//this is correct? or is there another way?
myJPanel.add(labels[object.getx][object.gety] = new JLabel("1"));
click = false;
}
But nothing happen, haha
Thanks for the help.
When you add/remove components from a visible GUI the basic code is:
panel.remove(...);
panel.add(...);
panel.revalidate();
panel.repaint();
Also "MyJPanel" is not a standard Java variable name. Variable names in Java should NOT start with an upper case character. You didn't do that with your other variables, so be consistent!
Given the fact the i and j have no context in the mouse listener method, no, it's probably not a good idea.
The next question is, what is the mouse listener attached to? If it's attached to the button, then it might be better to use a ActionListener.
In either case you could use the source of the event...
Object source = e.getSource();
if (source instanceof JButton) {
JButton btn = (JButton)source;
//find index of button in array...
remove(btn);
//...
revalidate();
}
Updated
A simpler solution might be to simply dump the buttons and labels into a List, for example...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.ArrayList;
import java.util.List;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class ButtonUpdates {
public static void main(String[] args) {
new ButtonUpdates();
}
public ButtonUpdates() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel implements ActionListener {
private List<JButton> btns = new ArrayList<>(25);
private List<JLabel> lbls = new ArrayList<>(25);
public TestPane() {
setLayout(new GridLayout(5,5));
for (int index = 0; index < 25; index++) {
JButton btn = new JButton(Integer.toString(index));
JLabel lbl = new JLabel(Integer.toString(index));
btns.add(btn);
lbls.add(lbl);
btn.addActionListener(this);
add(btn);
}
}
#Override
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source instanceof JButton) {
JButton btn = (JButton) source;
int index = btns.indexOf(source);
JLabel lbl = lbls.get(index);
index = getComponentZOrder(btn);
remove(btn);
add(lbl, index);
revalidate();
}
}
}
}
This makes looking up what has being actioned and what needs to be replaced easier.
When switching components, you also need to know where the component needs to be added, for this I simply used getComponentZOrder before I removed the JButton
I have two forms. First one is to decide button numbers by using jslider. Second form is to display jbuttons according to jslider value. When i click jbutton2, the second form shows and display buttons. It is working perfectly. However, I want to create jbutton without clicking jbutton2 in the first form.
Instead, when I change jslider, it should create buttons on the second form at the run time and once i change jslider it should create that amount of button again on the second form and refresh the second form buttons number according to jslider value.
I have tried revalidate();, repaint(); but they do not work, they dont refresh the second form.
So, How can I refresh second form when the jslider ,that is on the first form, changes ?
Actually you should provide a piece of code so we can understand it better.
But generally i think i could understand what you mean (if i'm not wrong).
Basically you need the layout manager on the second form.
here is a code sample, i hope it can generally answer your need.
Code for the first form
import java.awt.BorderLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class FirstForm extends JFrame {
JButton fbtn = new JButton("Show F2");
JSlider fslider = new JSlider(1, 10);
SecondForm fsecond = new SecondForm();
public FirstForm(){
setSize(200,200);
getContentPane().setLayout(new BorderLayout());
getContentPane().add(fbtn,BorderLayout.NORTH);
getContentPane().add(fslider,BorderLayout.CENTER);
setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
fbtn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
fsecond.setVisible(true);
}
});
fslider.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
fsecond.setBtnCount(fslider.getValue());
}
});
}
public static void main(String[] args) {
// TODO code application logic here
java.awt.EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
new FirstForm().setVisible(true);
}
});
}
}
Code for the second form
import java.awt.Component;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.util.Vector;
import javax.swing.JButton;
import javax.swing.JFrame;
public class SecondForm extends JFrame {
Vector fbtns = new Vector();
int fshowbtncount=1;
GridBagConstraints gbc = new GridBagConstraints();
public SecondForm(){
setSize(200, 200);
setLocation(201, 0);
getContentPane().setLayout(new GridBagLayout());
fbtns.add(new JButton("Button ".concat(String.valueOf(fbtns.size()+1))));
invalidateForm();
}
private void invalidateForm(){
gbc.fill = GridBagConstraints.VERTICAL;
for (int i=0; i<fbtns.size(); i++) {
getContentPane().remove((Component)fbtns.get(i));
}
int y=0;
for (int i=0; i<fshowbtncount; i++) {
gbc.gridx=0;
gbc.gridy=y++;
getContentPane().add((Component)fbtns.get(i),gbc);
}
pack();
invalidate();
}
public void setBtnCount(int cnt){
if (cnt>=0 && cnt!=fshowbtncount) {
fshowbtncount = cnt;
while (fbtns.size()<cnt) {
fbtns.add(new JButton("Button ".concat(String.valueOf(fbtns.size()+1))));
}
invalidateForm();
}
}
}
Hope this can help you out.