I have a jframe that has a jcmbobox with three state (three item, from 0 to 2).
i want when user select second item(1) my jlabel should be display!
But now, when i select second item, Don't show it!
public class LoginFrame extends javax.swing.JFrame {
public LoginFrame() {
initComponents();
this.setTitle("Library Management System Login");
this.setLocation(300, 50);
this.setResizable(false);
if (jComboBox1.getSelectedIndex() == 1) {
jLabel4.setVisible(true);
}
else{
jLabel4.setVisible(false);
}
}
My selected index number in my IDE menu is 0.
Any code in the constructor will not reflect changes made to the selected item in the JComboBox. You need to use a Listener such as an ActionListener to detect these changes:
jComboBox1.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
jLabel4.setVisible(jComboBox1.getSelectedIndex() == 1);
}
});
Aside: A slight improvement can be made by making the statement use the comparison expression directly in the setVisible statement as shown.
See Handling Events on a Combo Box
You should use ActionListener to do this:
jComboBox1.addActionListener(this);
...
jLabel4.setVisible(jComboBox1.getSelectedIndex() == 1);
Related
I'm very aware on how to do it if you have just one button, but for a Computer Science project I am making a Keno game GUI. To make the JButtons I made a for loop like so:
for(int i=1 ; i <= 80; i++)
{
num.add(1) ;
btn = new JButton(String.valueOf(i)) ;
btn.setBackground(Color.BLUE);
btn.setForeground(Color.YELLOW);
btn.setActionCommand(String.valueOf(i));
btn.addActionListener(new ButtonHandler());
panel.add(btn);
}
public class ButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
//Button Code if I click one button it goes here. I have set ID's via ActionCommand
}
}
https://i.gyazo.com/637f74422de5f4bf6e52155dcdfbd482.png [JButton Output]
So what I wanted to do, was for when I clicked a specific number, it turn RED so it would indicate that it's been clicked. To do this, would I have to define EACH button? Or can I somehow adjust just one button this way! Any information would be greatly appreciated!
Zachary Smith
If you want it to turn red after you've clicked (and stay red), you can just add that to the ButtonHandler
public class ButtonHandler implements ActionListener {
#Override
public void actionPerformed(ActionEvent event) {
JButton b = (JButton)event.getSource();
b.setBackground(Color.RED);
}
//Button Code if I click one button it goes here. I have set ID's via ActionCommand
}
it's really simple. I want to populate a jcomboBox but only after the user press the arrow on the combobox.
I think the code is right cause i test it in a separate button and it populate the Combobox but when i create an action listener for the combobox itself it doesn't populate, Here are the code.
comboBox.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent e) {
comboBox.addItem("Item");
comboBox.addItem("Second Item");
}
It's a country city neighborhood situation . What i want is the second to be populated when the first is selected .
The first box is easy to populate (The country box) But the second box (City) I added a switch for it but it just won't populate , What i want to know is there an action i should put my code into for it to populate ?
I want to populate a jcomboBox but only after the user press the arrow on the combobox.
Why would the user look at an empty combo box and then click on the arrow? If the contents of the combo box are based on some other user Action, then that Action should cause the combo box to be populated.
Anyway, maybe you are trying to popuplate the combo box when the dropdown is displayed?
That is the user could click anywhere on the combo box, not just the down arrow.
In this case you can use a PopupMenuListener
comboBox.addPopupMenuListener(new PopupMenuListener()
{
public void popupMenuWillBecomeVisible(PopupMenuEvent e)
{
JComboBox comboBox = (JComboBox)e.getSource();
comboBox.addItem("Item1");
comboBox.addItem("Item2");
comboBox.addItem("Item3");
comboBox.addItem("Item4");
}
public void popupMenuCanceled(PopupMenuEvent e) {}
public void popupMenuWillBecomeInvisible(PopupMenuEvent e) {}
});
Edit:
It's a country city neighborhood situation .
Which is a requirement that should have been included with your original question. As people has suggested your approach is wrong. The child combo boxes should be updated when the parent is changed, not when you click the child.
See How to Update Multiple Combo Boxes for a better solution. The example there only shows 2 combo boxes, but the concept is the same for the second and third.
Pressing a JComboBox arrow doesn't trigger the ActionListener. Only making a selection does, and so your combo box will need to be populated before the arrow has been pressed. You'll have to re-think your design such as populating the combo box before the user interacts with it.
If you absolutely needed to add an action listener to the arrow button, it can be done, such as via a recursive method:
import java.awt.Component;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.*;
public class Foo extends JPanel {
private JComboBox<String> combo = new JComboBox<>();
public Foo() {
add(combo);
combo.addMouseListener(new MouseAdapter() {
#Override
public void mousePressed(MouseEvent e) {
// this doesn't work!!!
System.out.println("mouse pressed");
super.mousePressed(e);
}
});
recursiveAddAxnListener(combo);
}
private void recursiveAddAxnListener(Component comp) {
if (comp instanceof AbstractButton) {
((AbstractButton) comp).addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent evt) {
System.out.println("added to combo's button");
}
});
} else if (comp instanceof Container) {
Component[] comps = ((Container) comp).getComponents();
for (Component component : comps) {
recursiveAddAxnListener(component);
}
}
}
private static void createAndShowGUI() {
Foo paintEg = new Foo();
JFrame frame = new JFrame("Foo");
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add(paintEg);
frame.pack();
frame.setLocationRelativeTo(null);
frame.setVisible(true);
}
public static void main(String[] args) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
createAndShowGUI();
}
});
}
}
But do I recommend it? No, not at all.
Edit
You have edited your question and have added:
It's a country city neighborhood situation . What i want is the second to be populated when the first is selected .
The first box is easy to populate (The country box) But the second box (City) I added a switch for it but it just won't populate , What i want to know is there an action i should put my code into for it to populate ?
You may be asking an XY-Problem type question where you ask how do I solve X code problem when the best solution is to use an entirely different approach. In this situation I strongly recommend that you not populate the second combobox on mouse press, but rather populate it only once and do it when the first combobox selection has been made. In other words, populate the 2nd combo box in the first combo box's ActionListener. This will simplify things greatly and prevent re-population of the 2nd combobox unnecessarily.
Thank you all for your help , you have been just awesome.
I found the problem I had to have the combobox.removeallItems(); before the switch not in the switch.
This is the testing version of it.and it worked.
JComboBox comboBox = new JComboBox();
comboBox.addItem("");
comboBox.addItem("first");
comboBox.addItem("second");
comboBox.addItem("third");
comboBox.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
comboBox_1.removeAllItems();
String test = comboBox.getSelectedItem().toString();
switch (test) {
case "first":
comboBox_1.addItem("Tesing");
break;
case "second":
comboBox_1.addItem("Tesing2");
break;
case "third":
comboBox_1.addItem("Tesing three");
break;
default:
break;
}
}
});
Again , i appreciate all the help , Thank you so much.
I'd like to be able to switch between two possible JPanels in my frame by selecting a certain JMenuItem. What I tried so far:
Action listener in my JMenuBar class:
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource().equals(fullList))
gui.switchToFullList();
else if (e.getSource().equals(history))
gui.switchToHistory();
}
In GUI class:
void switchToFullList() {
remove(history);
add(fullList);
}
void switchToHistory() {
remove(fullList);
add(history);
}
where history and fullList are JPanels.
This doesn't seem to modify my frame in any way.
If you want to show one Panel and hide another, they both should ba childreen of your Frame, then you can acces those Panels by: frame.JpanelName.
Example of removing history and adding fullList:
frame.remove(frame.history);
frame.getContentPane().add(frame.fullList);
frame.validate();
frame.repaint();
help,
my questions are:
why isn't itemStateChanges triggered, I tried to put it in the inner class ButtonHandler and also in RadioButtonHandler Im having trouble with it, what is the right way to do it?
I want to trigger and check the marked JRadioButtons after the user click the "check" button.
What is the right way to check which button was clicked, I feel like comparing the strings is bad programming practise. Maybe using an ID ?
How should I make a "reset" button(start over), I want to uncheck all radio buttons and run the constructor once again.
Thank you for your help !
import java.awt.*;
import java.awt.event.*;
import java.util.ArrayList;
import javax.swing.*;
public class ExamFrame extends JFrame {
static ArrayList<Question> qArrList;
JRadioButton a1,a2,a3,a4;
public ExamFrame() {
super("Quiz");
setLayout(new GridLayout(0, 1));
GridBagConstraints gbc = new GridBagConstraints();
Exam exam = new Exam();
qArrList = exam.getExam();
int count=0;
for(Question q : qArrList){
count++;
JLabel questionLabel = new JLabel(count+". "+q.getQustion()); //swing constant ?
ArrayList<String> ansRand = q.getAllRandomAns();
a1 = new JRadioButton(ansRand.get(0));
a2 = new JRadioButton(ansRand.get(1));
a3 = new JRadioButton(ansRand.get(2));
a4 = new JRadioButton(ansRand.get(3));
add(questionLabel);
add(a1);add(a2,gbc);add(a3);add(a4);
ButtonGroup radioGroup = new ButtonGroup(); //logical relationship
radioGroup.add(a1);radioGroup.add(a2);radioGroup.add(a3);radioGroup.add(a4);
}
//buttons:
JButton checkMe = new JButton("Check Exam");
JButton refresh = new JButton("Start Over");
ButtonHandler handler = new ButtonHandler();
checkMe.addActionListener(handler);
refresh.addActionListener(handler);
add(checkMe);
add(refresh);
}
/** Listens to the radio buttons. */
public class ButtonHandler implements ActionListener
{
public void actionPerformed (ActionEvent e) {
if(e.getActionCommand().equals("Start Over")){ //id?
//how to do this?
}
else{
RadioButtonHandler handler = new RadioButtonHandler();
a1.addItemListener(handler);
System.out.println("success?");
}
JOptionPane.showMessageDialog(ExamFrame.this, String.format("You pressed: %s", e.getActionCommand()));
}
public void itemStateChanged(ItemEvent e) //can i add it here?
{
JOptionPane.showMessageDialog(ExamFrame.this, String.format("yes?"));
System.out.println("success!");
}
}
public class RadioButtonHandler implements ItemListener
{
public void itemStateChanged(ItemEvent e)
{
JOptionPane.showMessageDialog(ExamFrame.this, String.format("radio state changed"));
}
}
}
why "itemStateChanges" isn't triggered, i tried to put it in the inner
class "ButtonHandler" and also in "RadioButtonHandler" Im having
troubles with it, what is the right way to do it? I want to trigger
and check the marked JRadioButtons after the user click the "check"
button.
ButtonHandler is implemented with ActionListener only:
public class ButtonHandler implements ActionListener{}
The itemStateChanged(ItemEvent) function belongs to ItemListener. This function is triggered if state of a source component to which this listener is registered gets changed. So implement the ItemListener. However, one more thing to note, that JButton doesn't respond to ItemListener but JRadioButton will. Because this Item events are fired by components that implement the ItemSelectable interface. Some example of such components are: check boxes, check menu items, toggle buttons and combo boxes including Radio Buttons as mentioned above.
What is the right way to check which button was clicked, i feel like
comparing the strings is wrong programming. Maybe using an ID
Well using the event source function: e.getSource(), check whither the type of the source is your expected type and cast it to appropriate type. And then you can use getName(String) function and check the name you were expecting. Of-course you should assign the name using setName(String) after initialization of component. Or using the component reference directly if it is declared in the Class context and you have direct access to the component.
#Override
public void itemStateChanged(ItemEvent e) {
if(e.getSource() instanceof JCheckBox)
{
JCheckBox checkBox = (JCheckBox)e.getSource();
if(checkBox.getName().equals("expectedName"))
; // do my thing
}
}
How should i make a "reset" button(start over), i want to uncheck all
radio buttons and run the constructor once again.
Well you are working with ButtonGroup. And ButtonGroup has a nice function: clearSelection() to help with whatever(I could not understand the part: run the constructor part) you want.
Edit: As you wanted me to see an ItemListener implemented class, Yes i can see that But:
i can not see that you have actually registered an instance of that class(a1.addItemListener(handler);) to any component before performing any action on the component to which ButtonHandler is registered to: checkMe, refresh
In addition to that, in this action performed function, you are checking with
action command, which you haven't even set with JButton.setActionCommand(String) function. You should not assign a (Item)listener depending on event-occurrence of another (Action)listener.
Tutorial:
How to Write an ItemListener
How to Write an ActionListener
How to Use the ButtonGroup Component
I wanted to create a JDialog which responds to mouse and key actions. The dialog holds a jTable where I want him to select a record. He should be able to select it by double click or by pressing a key (e.g. "2").
So I started by this:
public showDialog(TableModel model) {
super(new JFrame(), "Please select a record...");
table = new JTable(model);
//add JTable with ScrollPane
JScrollPane scrollPane = new JScrollPane();
scrollPane.setPreferredSize(new Dimension(800, Math.min(table.getPreferredSize().height+60, 800)));
scrollPane.getViewport().add(table);
add(scrollPane);
//display
setAlwaysOnTop(true);
toFront();
pack();
setVisible(true);
//mouse
table.addMouseListener(new MouseAdapter() {
#Override
public void mouseClicked(java.awt.event.MouseEvent evt) {
System.out.println("clicked");
}
});
//keys
table.addKeyListener(new KeyAdapter() {
#Override
public void keyTyped(java.awt.event.KeyEvent evt) {}
#Override
public void keyReleased(java.awt.event.KeyEvent evt) {}
#Override
public void keyPressed(java.awt.event.KeyEvent evt) {
System.out.println(evt.getKeyChar() + " pressed");
}
});
}
This works flawlessly.
However if I do the same thing with the statement setModal(true);, the listeners stop working.
How can I make my JDialog modal without losing the functionality of my listeners?
Simple solution: when the JDialog is modal, then setVisible() blocks the current thread, i.e. the Dialog's Constructor. Thus the Listeners are never added (actually only when the Dialog is closed). Therefore no events.
Solution: set 'setVisible(true);' to the end of the CTOR
BTW you should not to modal locking in the CTOR, having an extra method like 'void showTheDialog();' is better.
If you had done this from the beginning, the listeners would have been there and everything would have worked ;-)
Edit: Or use something like a Factory method, that's even better.
BTW PLEASE PLEASE stick to naming conventions, it took me 10 seconds to figure out that with 'public showDialog(TableModel model) {' you had not forgotten the method return type but that this would actually have been the CTOR itself :-)
I think this can cause a problem:
super(new JFrame(), "Please select a record...");
Why are you creating a new JFrame, you have to specify an existing one.
Btw, you should call super in constructor of your class which extends JDialog, not in some other method.
remove MouseListener is useless for your goal
remove KeyListener is useless for your goal
set proper ListSelectionMode to JTable
add ListSelectionListener to JTable