Java Swing - Problem in disabling JCheckbox - java

I am disabling a JCheckbox and then enabling it with the help of setEnabled(...) method.
But the problem is if I disable a unselected checkbox, then it becomes selected after I enable it.
I want all of them to have the same state after being enabled that they had before being disabled.

Are you enabling/disabling the JCheckBox using an ActionListener? If so, then that is normal because when you click on the checkbox, the isSelected() status changes.
What you can do is to add checks using isSelected() and the setSelected() methods.

The below code works as you describe:
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class CheckboxTest implements ActionListener{
private JCheckBox checkbox = new JCheckBox();
private JButton btn = new JButton("Enable");
public CheckboxTest(){
JFrame frame = new JFrame();
JPanel panel = new JPanel();
frame.getContentPane().add(panel);
checkbox.setEnabled(false);
btn.addActionListener(this);
panel.add(checkbox);
panel.add(btn);
frame.setSize(400, 400);
frame.setVisible(true);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
}
public static void main(String[] args){
new CheckboxTest();
}
public void actionPerformed(ActionEvent e) {
checkbox.setEnabled(!checkbox.isEnabled());
btn.setText(checkbox.isEnabled()?"Disable":"Enable");
}
}

If you call setEnabled that should not affect the selected state. If it is, then I suggest you reexamine your code to see if there is anything that can account for this behaviour. As someone else suggested, maybe if you post a code sample that may be helpful.
Update:
To make it perfectly clear, there are only two ways the selected state of a checkbox can be changed.
A call to setSelected
User clicks on the checkbox
A call to setEnabled does not change the selected state.
Thus, there must be something odd in your code that is causing this.

Related

How to make a JButton that will create other buttons in java Swing?

I am creating a user system to hold multiple details of multiple users, so I would like to create a button that would be able to create another button. When the second button is pressed a form will open for the user to fill. I have already created the form for the user to fill but I cannot manage to make the button to create more buttons to work. I have coded this but it does not show the button on the JPanel.
I have created the following code:
private void mainButtonActionPerformed(java.awt.event.ActionEvent evt) {
JButton b=new JButton("Click Here");
b.setBounds(50,100,95,30);
jPanel3.add(b);
b.setVisible(true);
}
I want to know what is the correct code to write in the events / mouseClick of the button.
When you add or remove components from a JPanel, you need to make that JPanel redraw itself. Just adding or removing a component does not make this happen. Hence, after adding or removing a component from a JPanel, you need to call method revalidate followed by a call to repaint.
Refer to Java Swing revalidate() vs repaint()
Also note that the following line of your code is not required since the visible property is true by default.
b.setVisible(true);
Also, it is recommended to use a layout manager which means you don't need to call method setBounds as you have in this line of your code.
b.setBounds(50,100,95,30);
EDIT
As requested, a sample application. Clicking on the Add button will add another button. Note that the ActionListener for the Add button is implemented as a method reference.
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.FlowLayout;
import java.awt.event.ActionEvent;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class ButtonAd {
private static final String ADD = "Add";
private JFrame frame;
private JPanel buttonsPanel;
private void addButton(ActionEvent event) {
JButton button = new JButton("Added");
buttonsPanel.add(button);
buttonsPanel.revalidate();
buttonsPanel.repaint();
}
private JPanel createAddButton() {
JPanel addButtonPanel = new JPanel();
JButton addButton = new JButton(ADD);
addButton.addActionListener(this::addButton);
addButtonPanel.add(addButton);
return addButtonPanel;
}
private void createAndDisplayGui() {
frame = new JFrame("Add Buttons");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.add(createButtonsPanel(), BorderLayout.CENTER);
frame.add(createAddButton(), BorderLayout.PAGE_END);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
private JPanel createButtonsPanel() {
buttonsPanel = new JPanel(new FlowLayout(FlowLayout.LEADING));
buttonsPanel.setPreferredSize(new Dimension(450, 350));
return buttonsPanel;
}
public static void main(String[] args) {
EventQueue.invokeLater(() -> new ButtonAd().createAndDisplayGui());
}
}

Swing: grayable multi-line JCheckBox?

I want to have a checkbox with multi-line text and I want to disable it sometimes.
Simple JCheckBox works fine and gets disabled, but it's not multiline.
Putting <html>line1<br>line2</html> provides correct size and layout, but when I disable the control, only the checkbox itself is grayed, the text remains black.
I know I can change the HTML text color to gray, but this will not work for the "Classic Windows" look-and-feel where disabled text should rendered as "sunken". Or, actually, it will work, but the appearance will differ from other disabled controls nearby, which is not good.
I can create a simple JCheckBox containing the first line of text and a JLabel with the second line and disable them simultaneously, but clicking the second line (the JLabel) doesn't activate the checkbox, and clicking the checkbox displays the keyboard focus only around the first line which confuses the user.
Is it possible to have a checkbox and its label as separate controls and have some kind of link between them, as in HTML? Probably I would be able to cook something from this.
Is it possible to subclass JButton and override something there, for example, to change the way the focus rectangle is drawn? The rectangle is drawn by com.sun.java.swing.plaf.windows.WindowsButtonUI but I'm kinda afraid of subclassing that class because it's too deep in the standard library and my application may break with a new JRE.
EDIT 04.02.2015: The above applies to Java 1.6. In Java 1.7 and higher, disabling a multi-line checkbox changes its appearance, but it still looks not the same as a disabled single-line checkbox; in particular, on Classic Windows theme the text doesn't become sunken.
(source: keep4u.ru)
I might be missing something, but I just disable the JCheckBox and the JLabel.
Using Java 1.7 and Windows Vista.
Here's the code
package com.ggl.testing;
import java.awt.BorderLayout;
import javax.swing.JCheckBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JToggleButton;
import javax.swing.SwingUtilities;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
public class CheckBoxTest implements Runnable {
private JCheckBox checkBox;
private JLabel multiLineLabel;
private JFrame frame;
#Override
public void run() {
frame = new JFrame("Check Box Test");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JPanel mainPanel = new JPanel();
mainPanel.setLayout(new BorderLayout());
JPanel checkBoxPanel = new JPanel();
checkBox = new JCheckBox();
checkBoxPanel.add(checkBox);
String s = "<html>When in the course of human events it becomes"
+ "<br>necessary for one people to dissolve the political"
+ "<br>bands which have connected them with another and to"
+ "<br>assume among the powers of the earth, the separate"
+ "<br>and equal station to which the Laws of Nature and"
+ "<br>of Nature's God entitle them, a decent respect to the"
+ "<br>opinions of mankind requires that they should declare"
+ "<br>the causes which impel them to the separation.";
multiLineLabel = new JLabel(s);
multiLineLabel.setLabelFor(checkBox);
checkBoxPanel.add(multiLineLabel);
mainPanel.add(checkBoxPanel, BorderLayout.CENTER);
JPanel toggleButtonPanel = new JPanel();
JToggleButton toggleButton = new JToggleButton("Disable Checkbox");
toggleButton.addChangeListener(new ChangeListener() {
#Override
public void stateChanged(ChangeEvent event) {
JToggleButton toggleButton = (JToggleButton) event.getSource();
if (toggleButton.isSelected()) {
checkBox.setEnabled(false);
multiLineLabel.setEnabled(false);
} else {
checkBox.setEnabled(true);
multiLineLabel.setEnabled(true);
}
}
});
toggleButtonPanel.add(toggleButton);
mainPanel.add(toggleButtonPanel, BorderLayout.SOUTH);
frame.add(mainPanel);
frame.pack();
frame.setLocationByPlatform(true);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new CheckBoxTest());
}
}

Not able to enable a button after it is disabled in java swing

I have just started learning java swing and I have been trying to create a simple game. The game is similar to minesweeper. A window with a matrix of bottons with just 1 mine. On clicking a button, if it's not a mine, i disable the button and display green color, and if it's a mine i disable the button and display red color. I have displayed the color by setting the button background to the required color. I have done the implementation so far just fine.
Next i added a reset button, on clicking which i renable all buttons by using : setEnabled(true).
But for some reason, the button is not getting enabled. I have confirmed that the program flow reaches the code for enabling the button, but i'm not able to find the reason why it is not working.
Here is a test program i wrote with a reset button and 1 button. Same issue. Can anyone point out what I maybe doing wrong?
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JButton;
import javax.swing.JFrame;
public class Test implements ActionListener{
JFrame frame = new JFrame("Mine");
JButton buttons = new JButton();
JButton reset = new JButton("Reset");
Container grid = new Container();
public Test(){
frame.setSize(400, 400);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
frame.setLayout(new BorderLayout());
frame.add(reset, BorderLayout.NORTH);
reset.addActionListener(this);
buttons = new JButton();
buttons.addActionListener(this);
frame.add(buttons, BorderLayout.CENTER);
}
public static void main(String[] args){
new Test();
}
#Override
public void actionPerformed(ActionEvent event) {
if(event.getSource().equals(reset))
buttons.setEnabled(true);
else{
if(event.getSource()==buttons){
buttons.setBackground(Color.RED);
buttons.setEnabled(false);
}
}
}
}
Actually it's getting enabled when you click reset, all you forgot to do was reset the color:
#Override
public void actionPerformed(ActionEvent event) {
if(event.getSource().equals(reset)){
buttons.setEnabled(true);
buttons.setBackground(null);
}else{
if(event.getSource()==buttons){
System.out.println("xxx");
buttons.setBackground(Color.RED);
buttons.setEnabled(false);
}
}
}

How to remove minimize button and keep maximize and close button in JFrame

I want to remove only minimize button from JFrame
but want maximize and close button in JFrame title bar.
Here I am talking about removing not disabling.
I don't think removing the minimize button is a good thing. But may be you can use the setUndecorated() method to remove the title bar and window edges. And you'll have to add your own close and maximize buttons to perfom those action.
Here is an example :
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.AbstractAction;
import javax.swing.JButton;
public class Example {
public Example() {
JFrame frame = new JFrame();
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setUndecorated(true);//<---- this will disable the frame decorations
JPanel panel = new JPanel();
panel.add(new JLabel("titlebar"));
//Add button maximize
JButton button_max=new JButton("Maximize");
button_max.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent ae) {
if(frame.getExtendedState() == JFrame.NORMAL) {
frame.setExtendedState(JFrame.MAXIMIZED_BOTH);
} else {
frame.setExtendedState(JFrame.NORMAL);
}
}
});
panel.add(button_max);
//Add button close
JButton button_close = new JButton(new AbstractAction("Close") {
private static final long serialVersionUID = -4901571960357967734L;
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
});
panel.add(button_close);
frame.add(panel);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
new Example();
}
}
Edit :
As #peeskillet states in the comment, even with this method the window still can be resized and draged by the user. The ComponentResizer class allows to do that.
Here is a an SO post which gives a good example to use this class with Jframe.
It's a very big hack, which works only with Synthetica L&F because it provides a painted title bar. Note: this L&F is not free to use. So if you use it you must by a license.
When you use this L&F you can iterate over all component starting from root pane to find an instance of SyntheticaTitlePane. On success you can try to access the field iconifyAction using Reflection Framework and use the method Action.setEnabled(false) on it.
I have no idea how to access the standard title bar because it's native. Probably it's impossible.

Prevent FocusEvents when Component is not focused

I have the following sample-code:
import java.awt.event.FocusAdapter;
import java.awt.event.FocusEvent;
import javax.swing.BoxLayout;
import javax.swing.JDialog;
import javax.swing.JFrame;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.WindowConstants;
public class SampleFocus extends JFrame {
public SampleFocus(String titel) {
setTitle(titel);
JTextField txtField1 = new JTextField("default-click");
JTextField txtField2 = new JTextField("alternative-Text");
JTextField txtField3 = new JTextField("own diaolog textfield");
JTextArea dummyLabel = new JTextArea(10, 20);
dummyLabel.setText("empty textarea, which is focusable");
setLayout(new BoxLayout(getContentPane(), BoxLayout.Y_AXIS));
add(txtField1);
add(dummyLabel);
add(txtField2);
JDialog altDialog = new JDialog(this);
altDialog.add(txtField3);
altDialog.setVisible(true);
altDialog.pack();
FocusAdapter myFocusListner = new FocusAdapter() {
#Override
public void focusGained(FocusEvent e) {
if (e.getComponent() instanceof JTextField) {
System.out.println("gained for TextField: "
+ ((JTextField) e.getComponent()).getText());
} else {
System.out.println("gained for component: " + e.getComponent());
}
}
};
txtField1.addFocusListener(myFocusListner);
txtField2.addFocusListener(myFocusListner);
txtField3.addFocusListener(myFocusListner);
// dummyLabel.addFocusListener(myFocusListner);
}
public static void main(String[] args) {
JFrame frame = new SampleFocus("FocusListener - sample");
frame.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
}
When I switch from the Frame to the dialog I get the proper event. When I switch back to the Frame I get as well the proper FocusEvents. My problem is, that when I switch back, I get as well the FocusEvents for components which I am not interested in.
e.g.
Select 'default-click' ==> Dialog/Textfield ==> Frame/'empty textarea'
Result: I get a FocusGained-Event for 'default-click' although the component has NOT the focus.
Desired Result: Either
Component 'default-click' does not get the FocusEvent OR
distinguish if the component really received the Event properly (e.g. I could have clicked into it as well)
Workaround I found:
Attach to the JTextArea as well a FocusListener. Problem is, that this would mean, I need to attach to ALLLL of my components a Listener. Which is hardly possible. Any ideas?
Any ideas how to get the result?
Thx LeO
Its working as intended.
You select "default-click". It gains focus.
You select Dialog. Frame and "default-click" loses focus.
You select Text area. Now, things becomes interesting. Dialog loses focus. Frame gets focus. "default-click" also gains focus, because he had it when Frame was active. And then "default-click" loses focus, textarea gains focus (because you clicked on text area).
Try combine focusGained and focusLost events.
Or tell me more what are you trying to accomplish, maybe I can help.
The way I found the workaround was to check in the focusGained-method if the current component is in an own JDialog and if previous component was a JTextField in a JFrame. If so, then I memorize the gained focused component, change the focus to another component and when I receive a focusLost I request it back to the previously memorized component.
Some kind of hack, but it works.... If there are any better ideas, I am interested in ...

Categories

Resources