JCheckBox List error? - java

I'm coding an enigma machine in java, and when the program launches, I have a JOptionPane appear with 5 JCheckBoxes for the user to select which rotors to use, and in which order.
My problem is, they get added to the popup, but they aren't actually displayed.
Instead I get a massive readout of all 5 checkboxes as if I called their toString method.
I have a few JLabels on the popup that display correctly, along with the OK button at the bottom.
My list is initialized like so:
private final List<JCheckBox> rotorCheckBox = Arrays.asList(new JCheckBox(
"Rotor 1"), new JCheckBox("Rotor 2"), new JCheckBox("Rotor 3"),
new JCheckBox("Rotor 4"), new JCheckBox("Rotor 5"));
I'm not sure why it does this, it worked as an array before, and I've been trying to convert it so I don't have to constantly call Arrays.asList() on it.
I've checked every use of it in my code, nothing is being called toString or creating errors relating to it being in a list.
How can I make it display correctly?

You're adding the List to the JOptionPane, you should add the JCheckBox's to a JPanel and use that instead
So, instead of something like...
JOptionPane.showMessageDialog(null, rotorCheckBox);
You should use something more like...
JPanel panel = new JPanel();
for (JCheckBox cb : rotorCheckBox) {
panel.add(cb);
}
JOptionPane.showMessageDialog(null, panel);
as an example

Related

Can we store JButtons in an array?

I am trying to make a small application in Java Swing using JFrame form. I added buttons from palette to panel in specific positions and now want to add these buttons to an array but I don't know the data type used for array that holds these designed buttons. I searched for it but didn't find anything related to my problem. I am new to coding and have very limited knowledge about Java - any help will be greatly appreciated.
I you want to have a flexible list of buttons, just declare a List of JButton.
List<JButton> listOfButton = new ArrayList<>();
JButton[] buttons = new JButton[10];
Just like any other arrays.
Here i am writing the code by using which i added my buttons to arrayList and getting it back.
// creating an ArrayList
ArrayList<JButton> btn = new ArrayList<JButton>();
// adding Buttons to ArrayList
btn.addAll(Arrays.asList(Button1, Button2, Button3,........));
//instead of writng btn.add(Button1);btn.add(Button2); and so on, use addAll();
// getting buttons from ArrayList
for (int i = 0; i < btn.size(); i++){
btn.get(i);
}

Java: JCheckBox won't stay checked with ItemListener

Ok, I'm new to listeners (still learning the language), and this is my first full-scale attempt to implement them (ie more than just a practice problem in a textbook).
So far, everything is working fine except one big bug: the checkboxes don't stay checked. The ItemListener I assign them runs perfectly (I have a JOptionPane set up to trigger to let me know if it's working or not), but the box itself doesn't stay checked.
I went even further and added conditional logic for if it's state is checked versus unchecked, and found that when I click the box BOTH states get triggered. So I get both JOptionPane popups, the one with the message for if the box is checked and the one for if the box isn't checked.
I'm including my code here. What am I doing wrong?
PS. You'll notice that the code has conditional logic to either add a radio button or a checkbox. When the program finally runs, this component is generated in multiple locations in both formats. The radio button works fine, it's the checkbox ones that I'm having the above issue with.
CODE THAT CREATES THE CHECKBOXES AND ASSIGNS THE LISTENERS:
public OtherField(int voteFor){
this.voteFor = voteFor;
otherPanel = new JPanel();
otherPanel.setLayout(new GridLayout(1, 3));
otherField = new JTextField(10);
otherField.setHorizontalAlignment(SwingConstants.CENTER);
JLabel otherLabel;
otherLabel = new JLabel("Other", SwingConstants.CENTER);
otherRadio = new JRadioButton("", false);
otherRadio.setHorizontalAlignment(SwingConstants.CENTER);
otherRadio.addActionListener(new OtherFieldRadioListener());
otherCheckBox = new JCheckBox("");
otherCheckBox.setHorizontalAlignment(SwingConstants.CENTER);
otherCheckBox.addItemListener(new OtherFieldCheckBoxListener());
otherPanel.add(otherLabel);
otherPanel.add(otherField);
if(voteFor == 1){
otherPanel.add(otherRadio);
}else{
otherPanel.add(otherCheckBox);
}
}
LISTENER CODE (it's a private class in the same class as the code above):
private class OtherFieldCheckBoxListener implements ItemListener{
public void itemStateChanged(ItemEvent e){
String name = otherField.getText();
if(e.getStateChange() == ItemEvent.SELECTED){
JOptionPane.showMessageDialog(null, name);
}else{
JOptionPane.showMessageDialog(null, "Not Selected");
}
}
}
First thing I would try is to set the checkbox either to true or false when you initialize it, i.e
otherCheckBox.setSelected(false)
If this does not work I would check whether OtherField gets called from somewhere else everytime the checkbox is selected and thus the components are redrawn/ the selection is reset (use the debugger and set a breakpoint at the beginning of OtherFields)

Extracting and manipulating data from a multiple interval JList to use in textArea/JOptionPane

As the title says, I have a multiple interval selection JList and i'm having trouble properly manipulating the data. This is my first time using a JList and it's proving difficult for me.
My GUI acts as a ticket ordering interface for a sports team, and the JList i'm referring to holds a list of souvenirs customers can order. Since it's a multiple selection JList, they can select multiple souvenirs if they so choose.
My issue is extracting the items from the JList and properly printing them to a JOptionPane textArea window, which acts as a summary for the user's order. Here is a breakdown of my goals/issues:
Extracting the souvenirs selected, where the names of the souvenirs are stored in a String[] array
Matching a parallel array of prices, stored in a Double[] array
Using the proper methods from the JList event handler to then print the data to the textArea summary
Eliminating duplicates of souvenirs that seem to appear when I try and print the data to the textArea
Here is the creation of my JList:
souvenirList = new JList(itemNames); //itemNames is an array of Strings[] for souvenirs
souvenirList.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
souvenirList.setLayoutOrientation(JList.VERTICAL);
scrollPane = new JScrollPane(souvenirList);
scrollPane.setPreferredSize(new Dimension(200,100));
gbc3.gridx = 1;
gbc3.gridy = 1;
centerPanel.add(scrollPane, gbc3);
c.add(centerPanel, BorderLayout.CENTER);
Here is my event handler for the JList:
private class ListHandler implements ListSelectionListener
{
public void valueChanged(ListSelectionEvent le)
{
boolean adjust = souvenirList.getValueIsAdjusting();
if (!adjust)
{
//not sure if/how I should use this
souvIndex = souvenirList.getSelectedIndices();
//I know this is depreciated, I dont know another way
souvItems = souvenirList.getSelectedValues();
for (int i = 0; i < souvItems.length; i++)
{
System.out.println(souvItems[i] + "\n");
//my attempt to save the souvenirs to an accumlator, doesnt work right
souvString += souvItems[i];
}
}
}
}//end List handler
Now, i'm attempting to take what is stored in souvString and print it to the textArea. I have an add to cart JButton which compiles all the data from the GUI to give the user their overall price. I'll focus on the JList since that is what is giving me trouble. Here is the actionEvent() for the add to cart JButton:
else if (ae.getSource() == cartBtn)
{
textArea = new JTextArea(10, 20);
textArea.setFont(f2);
textArea.setLineWrap(true);
textArea.setOpaque(false);
textArea.setWrapStyleWord(true);
textArea.setEditable(false);
//appending all the data from the GUI. souvString holds my JList selections
textArea.setText("Team: Tigers" + "\nMeal: " + restaurant
+ "\n\nSeats Ordered: " + seatingType
+ "\nItems Ordered:" + "\n " + souvString);
JOptionPane.showMessageDialog(null, textArea, "OrderReview",
JOptionPane.INFORMATION_MESSAGE,
new ImageIcon(Project7.class.getResource("/tigers.jpg")));
While it prints the souvenirs, weird things happen. I get a combination of null and duplicate souvenirs. I also can't figure out how to use the parallel array of prices that go along with the souvenirs that do print. The parallel array looks like:
private double[] prices = {2.0, 10.0, 15.0, 25.0, 3.0, 5.0, 9.0, 8.0, 12.0, 6.0};
Each price matches w/ it's corresponding souvenir from this array:
private String[] itemNames = {"mug","cap","tee shirt","sweat shirt","pennant","mini stick",
"bobblehead","paper bag","foam paw","thunderstix"};
I've been messing around with this for about 6 hours and can't get it to work, partially bc I don't understand JLists all that well, and partially bc my logic is flawed I feel. I've tried a few different approaches and those didn't work, either. If someone has some suggestions on how I could approach things differently, or even some advice/clarification on how to properly manipulate a JList, i'd be soo appreciative. I really want to understand this! Thanks again stack users :)
Instead of using two arrays i would create a new Class Souvenir in which you save your souvenirs with a subject and a price.
class Souvenir{
String subject;
double price;
}
About the JList i also dont know really much but i thought there is a method you can get a normal List from the JList Object and with this list you could work threw with the indices and put into an ArrayList of Souvenir or something like that.
This is just an idea i can't really give you an example for it so if someone else could verify this i would also be interested :)

Refreshing display of a text panel in a GUI

I'm having more "I'm hopeless at programming" problems.
I have a piece of code which uses StringBuilder to display elements of an array in a text panel of a GUI when the program starts. Here's the StringBuilder code:
// memory tab
StringBuilder mList = new StringBuilder();
memLocList = new Memory[MEM_LOCATIONS];
mem = new Memory();
for (int i = 0; i < memLocList.length; i++) {
memLocList[i] = mem;
memLocList[i].setOpCode(00);
mList.append(String.format("%10s %04x %10s %6s", "Address: ", i,
"Value: ", memLocList[i].getOpCode()));
mList.append("\n");
}
JComponent memTab = makeTextPanel(mList.toString());
tabs.addTab("Memory", new JScrollPane(memTab));
}
protected JComponent makeTextPanel(String t) {
text = t;
JPanel panel = new JPanel(false);
JTextPane filler = new JTextPane();
filler.setFont(new Font("Courier", Font.PLAIN, 14));
filler.setText(text);
filler.setAlignmentX(LEFT_ALIGNMENT);
panel.setLayout(new GridLayout(1, 1));
panel.add(filler);
return panel;
}
The GUI also has a text entry panel where a String of hex values can be entered.
On clicking a button, the user is prompted for another value, which corresponds to the position in the array where the first hex value should be inserted.
Once these values have been entered, I'd like the display to be updated / refreshed to reflect this but am unsure of how to go about it.
I found this question here, which is similar but I'm not sure if implementing Observer/Observable pattern is the right way to proceed, and even if it is, how I'd go about it:
Best Way to Constantly Update GUI Elements
My initial approach was to add an "updateDisplay()" method, which I could call after processing the button click and re-call the makeTextPanel method:
public void updateDisplay() {
makeTextPanel(text);
}
I thought this might refresh it but it has no effect of the display.
Any help appreciated.
You hold your array in a model class, and you allow other classes to "listen" to this by giving this class a SwingPropertyChangeSupport object as well as an addPropertyChangeListener(...) method. Then give the array a setXXX(...) method, and in that method fire the SwingPropertyChangeSupport object after updating the array. There are examples of just this sort of thing on this site, some written by me.
For example: here, here, here, ...
By the way, I'm not surprised that your call to makeTextPanel(text) doesn't work. It creates a JPanel, but you don't appear to do anything with the JPanel that is returned from the method. But nor should you. I don't think that creating new JPanels is the solution you want, but rather updating the Strings displayed by a component of some sort such as a JList or JTextArea using the listener framework that I've described above.
If any of this is confusing, please ask for clarification.

How do I use requestFocus in a Java JFrame GUI?

I am given an assignment but I am totally new to Java (I have been programming in C++ and Python for two years).
So we are doing GUI and basically we extended JFrame and added a couple fields.
Say we have a field named "Text 1" and "Text 2". When user presses enter with the cursor in Text 1, move the focus to Text 2. I tried to add
private JTextField textfield1() {
textfield1 = new JTextField();
textfield1.setPreferredSize(new Dimension(200, 20));
textfield1.addActionListener(
new ActionListener() {
public void actionPerformed(ActionEvent e) {
textfield1text = textfield1.getText().trim();
textfield1.setText(textfield1text);
System.out.println(textfield1text);
textfield1.requestFocus();
}
});
return textfield1;
}
But that doesn't work at all.
I noticed that requestFocus is not recommended, and instead one should use requestFocusWindows. But I tried that too. Upon some readings it seems like I have to do keyboard action and listener? But my teacher said it only requires 1 line...
Well, you have textfield1.requestFocus(), but your description would imply you need textfield2.requestFocus(). (that's 2).
Another option might be to use:
textField1.transferFocus();
This way you don't need to know the name of the next component on the form.

Categories