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;
}
});
Related
I am trying to create an action on a JButton release and I am not sure how to accomplish this. I can make an action just fine when the button is pressed. When the button is pressed it will change the image to a red dot and when released it should change back to a default green dot.
My button press code is below if someone can point me in the direction on how to create an action when the button is released that would be most helpful. Thanks!
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == change1) {
p1a.setIcon(CLR); // THIS IS THE IMAGE WHEN BUTTON PRESSED
// WOULD LIKE TO CHANGE BACK TO DEFAULT IMAGE HERE WHEN BUTTON IS RELEASED
}
}
I'm not looking for an Icon on the button itself to change I am looking for the image to change in a JPanel....same concept though
Nice to have that information available ahead of time
One approach might be to attach a listener to the ButtonModel and monitor for it's state changes...
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.Graphics2D;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.image.BufferedImage;
import javax.swing.ButtonModel;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.border.EmptyBorder;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
EventQueue.invokeLater(new Runnable() {
#Override
public void run() {
JFrame frame = new JFrame();
frame.add(new TestPane());
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
});
}
public class TestPane extends JPanel {
private Icon normalIcon;
private Icon pressedIcon;
public TestPane() {
setBorder(new EmptyBorder(16, 16, 16, 16));
normalIcon = makeIcon(Color.GREEN);
pressedIcon = makeIcon(Color.RED);
setLayout(new GridBagLayout());
GridBagConstraints gbc = new GridBagConstraints();
gbc.gridwidth = GridBagConstraints.REMAINDER;
JLabel label = new JLabel(normalIcon);
JButton btn = new JButton("Pressy");
add(btn, gbc);
add(label, gbc);
btn.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
ButtonModel model = btn.getModel();
if (model.isArmed()) {
label.setIcon(pressedIcon);
} else {
label.setIcon(normalIcon);
}
}
});
}
protected Icon makeIcon(Color color) {
BufferedImage img = new BufferedImage(25, 25, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = img.createGraphics();
g2d.setColor(color);
g2d.fillOval(0, 0, 25, 25);
g2d.dispose();
return new ImageIcon(img);
}
}
}
When the button is pressed it will change the image to a red dot and when released it should change back to a default green dot.
This can be entirely achieved within the JButton. See things like setPressedIcon(Icon) ..
E.G.
import javax.swing.*;
import java.net.*;
public class ButtonIcons {
ButtonIcons() throws MalformedURLException {
ImageIcon redIcon = new ImageIcon(new URL(
"https://i.stack.imgur.com/wCF8S.png"));
ImageIcon grnIcon = new ImageIcon(new URL(
"https://i.stack.imgur.com/T5uTa.png"));
JButton button = new JButton("Click me!", grnIcon);
button.setPressedIcon(redIcon);
JOptionPane.showMessageDialog(null, button);
}
public static void main(String[] args) {
Runnable r = () -> {
try {
ButtonIcons o = new ButtonIcons();
} catch (MalformedURLException ex) {
ex.printStackTrace();
}
};
SwingUtilities.invokeLater(r);
}
}
I have the following JButton on the GUI interface I'm building.
I want to make the border around the button more thicker so it will stand out from the background. Is it possible to do this in Java?
You could simply use a LineBorder
JButton btn = ...;
btn.setBorder(BorderFactory.createLineBorder(Color.BLACK, 4));
Take a look at How to Use Borders for more details and ideas
Updating the border state based on the model state
import java.awt.Color;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.Border;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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 static class TestPane extends JPanel {
protected static final Border NORMAL_BORDER = BorderFactory.createLineBorder(Color.BLACK, 4);
protected static final Border ROLLOVER_BORDER = BorderFactory.createLineBorder(Color.RED, 4);
public TestPane() {
JButton btn = new JButton("Click me!");
btn.setContentAreaFilled(false);
btn.setBorder(NORMAL_BORDER);
btn.getModel().addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent e) {
if (btn.getModel().isRollover()) {
btn.setBorder(ROLLOVER_BORDER);
} else {
btn.setBorder(NORMAL_BORDER);
}
}
});
setLayout(new GridBagLayout());
add(btn);
}
}
}
Create a Border first -
Border border = new LineBorder(Color.WHITE, 13);
Then create a JButton and set the Border -
JButton button = new JButton("Button Name");
button.setBorder(border);
Hope it will Help.
Thanks a lot.
I am a beginner at java so am attempting to create a minesweeper game. I have a grid full of JButtons that when clicked reveal numbers or mines.
I want to add "flags" so when I right click on any button it changes colour - showing it has been flagged and is 'locked' so it cannot be clicked on unless right clicked.
Here are my buttons
public void buttons()
{
// Creating the grid with buttons
grid.setLayout(new GridLayout(20,20));
// Button grid
for (int x = 0; x < buttons.length; x++)
{
for (int y = 0; y < buttons.length; y++)
{
buttons[x][y] = new JButton();
buttons[x][y].addActionListener(this);
grid.add(buttons[x][y]);
}
}
I attempted to create this right click functionality but I am currently stuck and would like some help.
public void flag()
{
buttons.addMouseListener(new MouseAdapter()
{
public void mousePressed(MouseEvent e)
{
JButton rightClick = new JButton("Right Click");
rightClick.addActionListener(this);
}
});
}
Typically, you would process user events on a button via the button's ActionListener, what you want to try and do is stop the user from trigger the buttons ActionListener, the easiest way that you can do this is disable the button...
Normally, I don't like using MouseListeners on buttons as this is not normally the best way to ascertain user interaction, but in this case, it's the requirement
import java.awt.BorderLayout;
import java.awt.EventQueue;
import java.awt.GridBagLayout;
import java.awt.Insets;
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.JPanel;
import javax.swing.SwingUtilities;
import javax.swing.UIManager;
import javax.swing.UnsupportedLookAndFeelException;
import javax.swing.border.EmptyBorder;
public class Test {
public static void main(String[] args) {
new Test();
}
public Test() {
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 {
private JButton btn;
public TestPane() {
setBorder(new EmptyBorder(8, 8, 8, 8));
setLayout(new GridBagLayout());
btn = new JButton("O");
btn.setMargin(new Insets(8, 8, 8, 8));
add(btn);
btn.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
System.out.println("You clicked me");
}
});
btn.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(MouseEvent e) {
if (SwingUtilities.isRightMouseButton(e)) {
btn.setEnabled(!btn.isEnabled());
if (btn.isEnabled()) {
btn.setText("O");
} else {
btn.setText("X");
}
}
}
});
}
}
}
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.
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);
}
}
}