I've noticed that ActionEvent would still be triggered within my group of JRadioButtonMenuItem even when specifying the conditional statement:
if(!button.isSelected())
//Do stuff
defaultTheme = new JRadioButtonMenuItem("Default theme");
defaultTheme.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if(!defaultTheme.isSelected())
System.out.println("temp");
}
});
I have multiple theme options within my settings menu, however if a say (say default) is already selected, I don't want to execute any redundant code if the default menu is already selected and the user clicks on the already selected Radio Button.
ActionListener will tell you whenever the button is "actioned" (clicked, pressed, what ever), which doesn't always change it's state. Instead, you could attach a ItemListener to the buttons model, which will tell, more accurately, when the actual state of the button changes, for example...
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import javax.swing.ButtonGroup;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JRadioButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class ButtonTest {
public static void main(String[] args) {
new ButtonTest();
}
public ButtonTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
ButtonGroup bg = new ButtonGroup();
final JRadioButton bananas = new JRadioButton("Bananas");
final JRadioButton apples = new JRadioButton("Apples");
bg.add(bananas);
bg.add(apples);
bananas.getModel().addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
System.out.println("Bananas " + bananas.isSelected());
}
});
apples.getModel().addItemListener(new ItemListener() {
#Override
public void itemStateChanged(ItemEvent e) {
System.out.println("Apples " + apples.isSelected());
}
});
add(bananas, gbc);
add(apples, gbc);
}
}
}
Not sure since I haven't seen the rest of your program, but you have to put all the radiobuttons in a ButtonGroup. Because if you don't it would be impossible to deselect the radiobutton.
Related
I want to set my JToggleButton in a disabled state, i.e. so that the user can't toggle it by clicking. I tried btn.setEnabled(false); but it grays out my icon and I don't want that. Is there any other method which doesn't gray out the icon, but doesn't let the user toggle the button?
but my own custom icon to be displayed.
You can also specify a "disabled icon" to be used by the toggle button. It could be the same Icon you use by default, or a slightly different icon.
When you specify your own Icon you don't get the greyed out effect.
You could disassociate the icon from the button and use appropriate layout constraints to provide a visual clue to the relationship instead, using a JLabel to display the icon instead, for example...
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
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.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
} catch (IOException ex) {
ex.printStackTrace();
}
}
});
}
public class TestPane extends JPanel {
public TestPane() throws IOException {
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
BufferedImage img = ImageIO.read(new File("/Volumes/Disk02/Dropbox/MegaTokyo/thumnails/2.jpg"));
JLabel label = new JLabel(new ImageIcon(img));
add(label, gbc);
JToggleButton btn = new JToggleButton("Click");
btn.setEnabled(false);
add(btn, gbc);
}
}
}
Personally, I'm thinking a JCheckBox might be more appropriate for this style
To allow the JToggleButton to be clicked only once.
If there are N JToggleButtons, declare N number of int class variables equal to 0.
(int jtbIntValue1=0, jtbIntValue1=0 ,...jtbIntValueN = 0)
Before allowing the user to press the JToggle button check if(jtbIntValueN != 0)
when a JToggle button is clicked update the corresponding JToggleButton int value equal to 1. (From jtbIntValueN = 0 to jtbIntValueN = 1).
public class Development1
{
int b1 = 0 ; // For one Button
public Development1()
{
...........
...........
JToggleButton jtb1 = new JToggleButton();
jtb1.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e1)
{
if(b1!=1)
{
if(SwingUtilities.isRightMouseButton(e1) && e1.getClickCount() == 1)
{
jtb1.setIcon(icRight); // Or do whatever you want to
}
else if(SwingUtilities.isLeftMouseButton(e1) && e1.getClickCount() == 1)
{
jtb1.setIcon(icLeft);
}
}
b1 = 1;
}
});
I would like to have Eclipse behavior for mouse clicks outside menus and popup menus in Swing. Basically, in Eclipse, when you press the mouse OUTSIDE the menu, the menu disappears and the mouse press event is forwarded to the component on which you clicked with the mouse.
Irritatingly, Swing does not do this, and I can't find a way around it.
Right now, even with Windows LAF, i have to click a second time to get the component to register the mouse click.
For the sake of the response just do it on a table
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem viewProfile = new JMenuItem("View Profile");
viewProfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
popupMenu.add(viewProfile);
table.setComponentPopupMenu(popupMenu);
EDIT: here is a test code. I don't think it is convenient to add a mouse listener to every simple component so they can register mouse clicks after a popup menu. In the following example, the Table does implement it, but not the Button.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class TestMouse {
public static void main(String[] args) {
new TestMouse();
}
private JLabel counter;
private int count;
private JPanel northPanel;
private JButton clickMe;
public TestMouse() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
DefaultTableModel model = new DefaultTableModel(new Object[] { "A", "B", "B", "B", "B", "B", "B" }, 10);
JTable table = new JTable(model);
northPanel = new JPanel();
clickMe = new JButton("Button");
clickMe.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("clicked");
count++;
}
});
counter = new JLabel("0");
northPanel.add(counter);
northPanel.add(clickMe);
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem viewProfile = new JMenuItem("View Profile");
viewProfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
popupMenu.add(viewProfile);
table.setComponentPopupMenu(popupMenu);
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("clicked");
count++;
counter.setText(String.valueOf(count));
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(northPanel, BorderLayout.NORTH);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
I don't seem to be able to replicate the issue.
When I right click the table, the popup menu appears and when I click the table again (to dismiss the popup), the mouseClicked event is triggered.
Note the counter in the north position...
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JMenuItem;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.table.DefaultTableModel;
public class TestMouse {
public static void main(String[] args) {
new TestMouse();
}
private JLabel counter;
private int count;
public TestMouse() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
DefaultTableModel model = new DefaultTableModel(
new Object[]{"A", "B", "B", "B", "B", "B", "B"},
10
);
JTable table = new JTable(model);
counter = new JLabel("0");
final JPopupMenu popupMenu = new JPopupMenu();
JMenuItem viewProfile = new JMenuItem("View Profile");
viewProfile.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
}
});
popupMenu.add(viewProfile);
table.setComponentPopupMenu(popupMenu);
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
System.out.println("clicked");
count++;
counter.setText(String.valueOf(count));
}
});
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new BorderLayout());
frame.add(counter, BorderLayout.NORTH);
frame.add(new JScrollPane(table));
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
A actual runnable example that demonstrates your problem would involve less guess work and better responses
I had exactly the same problem when closing JMenuBar popups, and this worked for me:
UIManager.put("PopupMenu.consumeEventOnClose", false);
in my program I need to disable my JSlider under certain circumstances, but do not know how. I tried setFocusable(false) but that did not work... Thanks in advance!
You change/restrict user interactions with the JSlider through the use of the enabled property.
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JSlider;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class SliderTest {
public static void main(String[] args) {
new SliderTest();
}
public SliderTest() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
}
final JSlider slider = new JSlider();
final JCheckBox checkBox = new JCheckBox();
checkBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
slider.setEnabled(checkBox.isSelected());
}
});
checkBox.setSelected(true);
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
frame.add(slider, gbc);
frame.add(checkBox, gbc);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
}
Try the setEnabled(boolean) method. All JComponents inherit it by default.
I want help somebody. I want to create a JPanel that will popup when i click on a button, it must appear there where the button is clicked, and it must not affect other components. An example of that is a JDateChooser, when you click on that button, a calendar appears right there, but when you click anywhere else, that panel disappears. what i want is to put a list of names in that panel when it pops. It is similar to JPopupmenu except that when you click anywhere else it must disappear.
I'm not sure what you're doing, but it seems to work just fine for me...
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GridBagLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.DefaultListModel;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JList;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JScrollPane;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
public class ButtonPopup {
public static void main(String[] args) {
new ButtonPopup();
}
public ButtonPopup() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
try {
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException | UnsupportedLookAndFeelException ex) {
ex.printStackTrace();
}
JFrame frame = new JFrame("Testing");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
public TestPane() {
setLayout(new GridBagLayout());
final JPopupMenu popup = new JPopupMenu();
DefaultListModel<String> model = new DefaultListModel<>();
model.addElement("Item 1");
model.addElement("Item 2");
model.addElement("Item 3");
model.addElement("Item 4");
model.addElement("Item 5");
JList list = new JList(model);
popup.setLayout(new BorderLayout());
popup.add(new JScrollPane(list));
final JButton button = new JButton("Pop");
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
Dimension size = popup.getPreferredSize();
int x = (button.getWidth() - size.width) / 2;
int y = button.getHeight();
popup.show(button, x, y);
}
});
list.addListSelectionListener(new ListSelectionListener() {
#Override
public void valueChanged(ListSelectionEvent e) {
popup.setVisible(false);
}
});
add(button);
}
#Override
public Dimension getPreferredSize() {
return new Dimension(200, 200);
}
protected void paintComponent(Graphics g) {
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g.create();
g2d.dispose();
}
}
}
I want enter key to behave like tab key in my swing application.And this class is working fine for JTextFields.How can i do the same for JComboBox and Jspinner or for the other controls on the frame?kindly help.
class MyTextField extends JTextField {
MyTextField(int len) {
super(len);
addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent evt) {
int key = evt.getKeyCode();
if (key == KeyEvent.VK_ENTER)
transferFocus();
}
});
}
}
Enter has special meaning for most components in Swing, for example JTextField will trigger actionPerformed on registered ActionListeners when Enter is pressed. Modifying this behaviour may have unexpected results for your application and may confuse many users...
Having said that, the best way to change the focus traversal keys is to provide a Set of KeyStrokes to the KeyboardFocusManager. This will (mostly) make the key's global.
Some component's supply there own focus traversal keys however, like JTextArea and JTable
Take a look at How to use Focus Subsystem for more details
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.KeyboardFocusManager;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.util.HashSet;
import java.util.Set;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.KeyStroke;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
public class TestFocusTraversal {
public static void main(String[] args) {
new TestFocusTraversal();
}
public TestFocusTraversal() {
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 {
public TestPane() {
setLayout(new GridBagLayout());
for (int index = 0; index < 10; index++) {
JTextField tf = new JTextField(5);
tf.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("...");
}
});
add(tf);
}
add(new JScrollPane(new JTextArea(10, 10)));
KeyStroke enter = KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0);
KeyStroke tab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0);
KeyStroke ctrlTab = KeyStroke.getKeyStroke(KeyEvent.VK_TAB, KeyEvent.CTRL_DOWN_MASK);
Set<KeyStroke> keys = new HashSet<>();
keys.add(enter);
keys.add(tab);
keys.add(ctrlTab);
KeyboardFocusManager.getCurrentKeyboardFocusManager().setDefaultFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys);
}
}
}