How to avoid Multiple Jbutton selections - java

I am using Jbuttons for a game called who wants to be a zillionaire in an assignment. I am using the buttons for selecting an answer. Here is the code for some of the buttons. Code:
}
});
Answer2.setBounds(220, 105, 188, 25);
panel.add(Answer2);
Answer1 = new JButton("A");
Answer1.setBackground(Color.YELLOW);
Answer1.setHorizontalAlignment(SwingConstants.LEFT);
Answer1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Answer1.setBackground(Color.BLUE);
Answer1.setForeground(Color.WHITE);
}
});
Answer1.setBounds(20, 105, 188, 25);
panel.add(Answer1);
Answer4 = new JButton("D");
Answer4.setBackground(Color.YELLOW);
Answer4.setHorizontalAlignment(SwingConstants.LEFT);
Answer4.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Answer4.setBackground(Color.BLUE);
Answer4.setForeground(Color.WHITE);
}
});
At the moment multiple buttons can be selected and I wish to prevent this. It would be helpful if you could show me an example of code that could be used to do this.

Use the setEnable() method to make unwanted buttons disable or make a Boolean class level variable and make it true when the desired button is clicked. Then before invoking other buttons' algorithms simply check whether this variable's value is true.
Edited
public class YourClassName{
static boolean isAnswerSelected = false;
//your codes goes here
Answer1.setHorizontalAlignment(SwingConstants.LEFT);
Answer1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(!isAnswerSelected){ //this line will check whether an answer is already selected
isAnswerSelected = true; // this will make other answers unselectable
Answer1.setBackground(Color.BLUE);
Answer1.setForeground(Color.WHITE);
}
}
});
}
Use the above if statement and isAnswerSelected = true; line for all your actionPerformed() methods for all buttons.

Related

How to open new window by clicking label in java?

I want to open a new window when I click the label. By implementing a key pressed listener. But it is not working. Even nothing is happening.
JLabel lblNewLabel_2 = new JLabel("Create New Account!!!!");
lblNewLabel_2.setForeground(Color.GREEN);
lblNewLabel_2.addKeyListener(new KeyAdapter() {
#Override
public void keyPressed(KeyEvent e) {
Dosomething();
}
});
private void Dosomething() {
hide();
Account account=new Account();
account.visible();
}
protected static void hide() {
frame.hide();
}
You can use JButton as others say and remove its border to make it look like JLabel but if you really want to use JLabel and detect clicks I think you should write a MouseAdapter for it.
JLabel fooLabel = new JLabel("foo");
fooLabel.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
doSomething();
}
}
);
You can also override mouseClicked method but in that case the user must not move the cursor while clicking.

Disable buttons on GUI in Swing

I have buttons on a GUI that execute tests when clicked on in Selenium. They can only be run serially and are currently added to EventQueue. I would like it so that if a button is clicked on and a test is executed, then it will disable the other buttons so that other tests cannot be added to a queue.
Currently a button looks like:
Test1 = new JButton("Test1 ");
Test1.setLocation(290, 30);
Test1.setSize(120, 30);
Test1.addActionListener(this);
Test1.addMouseListener(new MouseAdapter() {
public void mouseClicked(java.awt.event.MouseEvent e) {
if (Test1.isEnabled()) {
Test1.setEnabled(false);
errorLabel.setText("");
service.submit(()->{
Result result = JUnitCore.runClasses(Test1.class);
EventQueue.invokeLater(()->{
errorMessageDisplay(result);
Test1.setEnabled(true);
});
});
}
}
});
buttonPanel.add(Test1);
I have used the EventQueue as it allows me to reset update Pass/Fail error messages on the GUI.
How can I best achieve this?
You should add ActionListener to your button. What's even more important, you should use naming conventions what also means that your objects' names should start with a small letter. Capital letters are reserved for Classes and static fields (all upper case). The following code adds an ActionListener to your JButton and disables it after clicked. If it's not what you're looking for, I'll add another version in a moment.
test1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
test1.setEnabled(false);
}
});
In case, you want to keep the state of your button, but don't disable it, the following code might be a solution:
private final static String ENABLED = "ENABLED";
private final static String DISABLED = "DISABLED";
public static void main(String[] args) {
Map<JButton, String> map = new HashMap<>();
JButton test1 = new JButton();
map.put(test1, ENABLED);
test1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
if (map.get(test1).equals(ENABLED)) {
//do something
} else {
//do something else. I'll enable.
map.remove(test1);
map.put(test1, ENABLED);
}
}
});
}

Disabling Enabled Effect on JToggleButton

I've got an application that is using Swing for it's UI. I want a button that switch the type of communication that the app is using. I want to use a Toggle Button to identify the type of communication that's selected.
My problem is that I don't want the color of the button to change after it's been clicked. Currently the button looks like this...
Non-Selected
And then when clicked it looks like this...
Selected
The text changing is what I want, but I would prefer them to have the same color / style.
Here's my code for this...
JToggleButton tglbtnCommunicationType = new JToggleButton("AlwaysOn");
tglbtnCommunicationType.setFocusPainted(false);
tglbtnCommunicationType.addChangeListener(new ChangeListener( ) {
public void stateChanged(ChangeEvent tgl) {
System.out.println("ChangeEvent!");
if(tglbtnCommunicationType.isSelected()){
tglbtnCommunicationType.setText("REST");
tglbtnCommunicationType.setBackground(UIManager.getColor("Button.background"));
}
else
{
tglbtnCommunicationType.setText("AlwaysOn");
};
}
});
My thought is that setting the background when it is selected to the standard background color would fix that, but it doesn't look like it. Any ideas?
Thanks!
Answer:
I switched to a JButton instead, thanks for the help everyone!
JButton btnCommunicationType = new JButton("AlwaysOn");
btnCommunicationType.setFocusPainted(false);
btnCommunicationType.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
if(btnCommunicationType.getText().equals("AlwaysOn"))
{
btnCommunicationType.setText("REST");
//TODO: Insert Code for Switching Communication to REST here
}
else if(btnCommunicationType.getText().equals("REST")){
btnCommunicationType.setText("AlwaysOn");
//TODO: Insert Code for Switching Communication to AlwaysOne here
}
}
});
btnCommunicationType.setBounds(275, 199, 97, 25);
thingWorxConnectionPanel.add(btnCommunicationType);
you can do it by using JButton only instead of JToggleButton ,
JButton showButton = new JButton("AlwaysOn");
showButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String currentText = showButton.getText();
if("AlwaysOn".equals(currentText)){
showButton.setText("REST");
}else{
showButton.setText("AlwaysOn");
}
}
});

Java how to assign id to button and retrieve them?

I'm getting stuck while building a forum like application which has a vote button.
I have vote up and vote down button for each content which are automatically generated. I want this button to only display the up and down arrow but not any text or label.. how can i find out which button is pressed?
Automated content..
ImageIcon upvote = new ImageIcon(getClass().getResource("vote_up.png"));
ImageIcon downvote = new ImageIcon(getClass().getResource("vote_down.png"));
JButton vote_up = new JButton(upvote);
JButton vote_down = new JButton(downvote);
vote_up.addActionListener(voting);
vote_down.addActionListener(voting);
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
//What to do here to find out which button is pressed?
}
};
any help is appreciated.
public void a(){
int crt_cnt = 0;
for(ClassA temp : listofClassA)
{
b(crt_cnt);
crt_cnt++;
}
}
public void b(crt_cnt){
//draw button
}
As from above, I have multiple vote_up and vote_down button created by the b function, how can i differentiate which crt_cnt is the button from?
There are multiple ways you might achieve this
You could...
Simply use the source of the ActionEvent
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up) {
//...
} else if (...) {
//...
}
}
};
This might be okay if you have a reference to the original buttons
You could...
Assign a actionCommand to each button
JButton vote_up = new JButton(upvote);
vote_up.setActionCommand("vote.up");
JButton vote_down = new JButton(downvote);
vote_down .setActionCommand("vote.down");
//...
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if ("vote.up".equals(e.getActionCommand())) {
//...
} else if (...) {
//...
}
}
};
You could...
Take full advantage of the Action API and make indiviual, self contained actions for each button...
public class VoteUpAction extends AbstractAction {
public VoteUpAction() {
putValue(SMALL_ICON, new ImageIcon(getClass().getResource("vote_up.png")));
}
#Override
public void actionPerformed(ActionEvent e) {
// Specific action for up vote
}
}
Then you could simply use
JButton vote_up = new JButton(new VoteUpAction());
//...
Which will configure the button according to the properties of the Action and will trigger it's actionPerformed method when the button is triggered. This way, you know 100% what you should/need to do when the actionPerformed method is called, without any doubts.
Have a closer look at How to Use Actions for more details
You can detect by using the method getSource() of your EventAction
Action voting = new AbstractAction(){
#Override
public void actionPerformed(ActionEvent e){
if (e.getSource() == vote_up ) {
// vote up clicked
} else if (e.getSource() == vote_down){
// vote down clicked
}
}
};
hey thanks for all the help and assistance! I've finally got it! I solved it by
assigning a text on the button, +/- for vote up or down, followed by the content id which i required, then change the font size to 0
vote.setText("+"+thistopic.content.get(crt_cnt).get_id());
vote.setFont(heading.getFont().deriveFont(0.0f));
after that i could easily trace which button is pressed by comparing to the
actionEvent.getActionCommand()
which return the text on the button!
I would wrap the JButton similar to this:
JButton createMyButton(final JPanel panel, final String text,
final boolean upOrDown, final int gridx, final int gridy) {
final JButton button = new JButton();
button.setPreferredSize(new Dimension(80, 50));
final GridBagConstraints gbc = Factories.createGridBagConstraints(gridx,
gridy);
panel.add(button, gbc);
button.addActionListener(new ActionListener() {
#Override
public void actionPerformed(final ActionEvent e) {
myActionPerformed(text, upOrDown);
}
});
return button;
}
You could use an int instead of the text, if more convenient.

Java Swing: Focus issue

I'm making a level editor for my game. I have a property panel where I can modify the selected object its properties. I also have a Save button to write the level xml.
A field-edit is submitted(*) when the editor component lost the focus or Enter is pressed. This is working great, but the only problem is that when I have this sequence of actions:
Edit a field
Press the save button
Because, what happens is this:
I edit the field
I press the save button
The level is saved
The field lost the focus
The edit is submitted
As you can see, this is the wrong order. Of course I want the field to lose its focus, which causes the submit and then save the level.
Is there a trick, hack or workaround to make the field first lose the focus and then perform the action listener of the save button?
Thanks in advance.
(* submit = the edit to the field is also made in the object property)
EDIT: For the field I'm using a FocusAdapter with focusLost:
FocusAdapter focusAdapter = new FocusAdapter()
{
#Override
public void focusLost(FocusEvent e)
{
compProperties.setProperty(i, getColor());
record(); // For undo-redo mechanism
}
};
And for the button a simple ActionListener with actionPerformed`.
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
// Save the level
}
});
Hmm ... can't reproduce: in the snippet below the lost is always notified before the actionPerfomed, independent on whether I click the button or use the mnemonic:
final JTextField field = new JTextField("some text to change");
FocusAdapter focus = new FocusAdapter() {
#Override
public void focusLost(FocusEvent e) {
LOG.info("lost: " + field.getText());
}
};
field.addFocusListener(focus);
Action save = new AbstractAction("save") {
#Override
public void actionPerformed(ActionEvent e) {
LOG.info("save: " + field.getText());
}
};
save.putValue(Action.MNEMONIC_KEY, KeyEvent.VK_S);
JButton button = new JButton(save);
JComponent box = Box.createHorizontalBox();
box.add(field);
box.add(button);
On the other hand, focus is a tricky property to rely on, the ordering might be system-dependent (mine is win vista). Check how the snippet behave on yours.
If you see the same sequence as I do, the problem is somewhere else
if you get the save before the lost, try to wrap the the save action into invokeLater (which puts it at the end of the EventQueue, so it's executed after all pending events)
Action save = new AbstractAction("save") {
#Override
public void actionPerformed(ActionEvent e) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
LOG.info("save: " + field.getText());
}
});
}
};
Normally, wrapping your save code into an SwingUtilities.invokeLater() should do the trick. As you already mentioned, this doesn't work? Try this:
private boolean editFocus = false;
FocusAdapter focusAdapter = new FocusAdapter()
{
#Override
public void focusGained(FocusEvent e){
editFocus = true;
}
#Override
public void focusLost(FocusEvent e){
compProperties.setProperty(i, getColor());
record(); // For undo-redo mechanism
editFocus = false;
if (saveRequested){
save();
}
}
};
and for your button:
private boolean saveRequested = false;
btnSave.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
if (editFocus){
saveRequested = true;
return;
} else {
save();
}
}
});
and then your save method:
private void save(){
// do your saving work
saveRequested = false;
}
This only works when your focusLost gets called after your button's action. If suddenly the order is correct, this code will get save() called twice.
But again, wrapping your save() code in your original approach should work, because the save code will execute after processing all events. That is after processing your button click and your focusLost events. Because your focusLost code executes immediately (it's not wrapped in an invokeLater()), the focusLost code should be executed always before your save code. This does not mean that the event order will be correct! But the code associated to the events will executed in the right order.

Categories

Resources