I'm working on a TextTwist java implementation and I'm currently working on the GUI. I was wondering if some of you Swing geniuses could help me out. I'm trying to do a GUI where whenever a button is clicked, the text of that button is written into the first empty textField below it. I'm having trouble thinking through how to do it. What I've tried so far makes the first button click fill all the TextFields.
Any help or pointers in the right direction would be great.
private void makeButtonLayout() {
this.charArray = new char[6];
ArrayList<Character> charArrayList = new ArrayList<Character>();
this.charArray = this.randomString.toCharArray();
for(char tempCharacter : this.charArray){
charArrayList.add(tempCharacter);
}
for (int i = 0; i< 6; i++){
JButton letterButton = new JButton();
Character buttonCharacter = charArrayList.get(i);
charArrayList.remove(i);
String letterString = buttonCharacter.toString();
letterButton.setText(letterString);
this.letterButtonsArray.add(letterButton);
}
for (final JButton currentButton : this.letterButtonsArray){
this.buttonPanel.add(currentButton);
currentButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
int i = 0;
currentButton.setVisible(false);
JTextField temporaryTextField = new JTextField();
String temporaryString = currentButton.getText();
temporaryTextField.setText(temporaryString);
if(textFieldArray.get(i).getText().isEmpty()){
textFieldArray.get(i).setText(temporaryString);
return;
}else{
i++;
return;
}
}
});
}
}
I think you method is really strange. You mixed initialization code and execution code. Do it like this:
for (final JButton currentButton : this.letterButtonsArray){
this.buttonPanel.add(currentButton);
currentButton.addActionListener(new ActionListener(){
#Override
public void actionPerformed(ActionEvent arg0) {
currentButton.setVisible(false);
String temporaryString = currentButton.getText();
for(int i = 0; i < textFieldArray.size(); i++)
JTextField elem = textFieldArray.get(i);
if(elem.getText().equals("")){ // or if you don't want spaces do: elem.getText().trim().equals("");
elem.setText(temporaryString);
break;
}
}
}
});
}
Related
According to my previous question here:
Remove a Button with same text when clicked
I need that the only buttons that appearing more then one will disappearing while clicking on them
Problem is when clicking on the "Unique" ones ( see picture ), they will disappear also.
My code:
private String namesArr[] = {"Yakir","Yarden","Igor","Maoz","Moshe","Israel","Tal","Haim","Nati","Mor","Daniel","Idan"};
private Button buttonArr[] = new Button[namesArr.length];
private Font font;
public StudentsGUI(String caption) {
super(caption);
addWindowListener(new WindowAdapter(){
public void windowClosing(WindowEvent e){
dispose();
System.exit(0);
}
});
this.setLayout(new GridLayout(3,3));
font = new Font("Ariel",Font.BOLD,35);
for(int i=0;i<namesArr.length;i++) {
buttonArr[i] = new Button(" "+namesArr[(int)(Math.random()*namesArr.length)]);
buttonArr[i].setFont(font);
buttonArr[i].addActionListener(this);
this.add(buttonArr[i]);
}
setLocation(800,500);
setVisible(true);
pack();
}
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Button) {
String btnText = ((Button)e.getSource()).getLabel();
for(int i=0; i<buttonArr.length; i++) {
if (buttonArr[i].getLabel().equals(btnText)) {
this.remove(buttonArr[i]);
pack();
}
}
}
}
The picture to help you understand:
So if clicking on "Idan", witch is a unique name nothing will happen as it only have one instance, but if clicking on "Maoz" all the buttons with "Maoz" title will disappear ( this already happening )
using collections as per #Freddy's answer should be better. However if you're to stick with arrays, something like below should do it (haven't tested it though)
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Button) {
String btnText = ((Button)e.getSource()).getLabel();
int counter = 0;
for(int i=0; i<buttonArr.length; i++) {
if (buttonArr[i].getLabel().equals(btnText)) counter++;
if (count > 1) {
for(int j=0; j<buttonArr.length; j++) {
if (buttonArr[j].getLabel().equals(btnText))
this.remove(buttonArr[j]);
}
}
}
pack();
}
}
You mean something like this (code may have syntax errors)?
public void actionPerformed(ActionEvent e) {
if (e.getSource() instanceof Button) {
String btnText = ((Button)e.getSource()).getLabel();
List<Button> btnList = new ArrayList<Button>();
for(int i=0; i<buttonArr.length; i++) {
if (buttonArr[i].getLabel().equals(btnText)) {
btnList.add(buttonArr[i]);
//this.remove(buttonArr[i]);
//pack();
}
}
if (btnList.size() > 1) {
for (Iterator<Button> it = btnList.iterator(); it.hasNext()) {
this.remove(it.next());
}
pack();
}
}
}
I have 20 loop-generated JToggleButtons and I need to count how many of them are active.
private void generarBotones(){
JToggleButton b;
this.panelCuerpo.setLayout(new GridLayout(4,5));
for(int i = 1; i<=20; i++){
b = new JToggleButton();
b.setText(String.valueOf(i));
this.panelCuerpo.add(b);
b.addActionListener(new ActionListener() {
int clicks = 0;
#Override
public void actionPerformed(ActionEvent ae2){
clicks = clicks + 1;
System.out.println(clicks);
}
public void setCantidadBoletas(int clicks){
cantidadBoletas = clicks;
}
});
}
}
The problem here is that it counts how many times is EACH ONE of them clicked instead of count how many of them are selected.
PS. I tried to use (b.isSelected()) but b needs to be final to access it so it wasn't the solution.
If you declare the JToggleButton inside the loop, you can make it final:
for (int i = 1; i<=20; i++) {
JToggleButton b = new JToggleButton();
Then you can use b.isSelected:
b.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
if (b.isSelected())
clicks++;
else
clicks--;
}
});
}
clicks would have to be a class variable.
Suggestions:
Create a field, JToggleButton[] toggleButtons = new JToggleButton[20]
Or use an ArrayList if you so choose
In your for loop create your JToggleButton and assign it to the proper array item.
In the ActionListener simply iterate through the array, counting how many of its JToggleButton items are selected.
You're done.
Create a class attribute that will count the selected toggles:
private int selectedCount;
Initialize the counter to 0 in your constructor:
this.selectedCount = 0;
Increment or decrement the counter every time the state of a toggle changes:
b.addItemListener(new ItemListener() {
public void itemStateChanged(ItemEvent ev) {
if (ev.getStateChange() == ItemEvent.SELECTED){
YourClass.this.selectedCount++;
} else if (ev.getStateChange() == ItemEvent.DESELECTED){
YourClass.this.selectedCount--;
}
System.out.println(YourClass.this.selectedCount);
}
});
There are many ways to get this done and the best way depends on the rest of your code. I tried to keep it as close to yours.
You can just declare the buttons as final inside the loop and keep a global count of the number of buttons selected, which will be modified in the ActionListener:
public class ButtonsCount extends JFrame {
int clicks = 0;
ButtonsCount() {
JLabel label = new JLabel("0");
JPanel buttonsPanel = new JPanel(new GridLayout(4,5));
for(int i = 1; i <= 20; i++) {
final JToggleButton b = new JToggleButton();
b.setText(String.valueOf(i));
buttonsPanel.add(b);
b.addActionListener(new ActionListener() {
#Override
public void actionPerformed(ActionEvent ae2){
if (b.isSelected())
label.setText(String.valueOf(++clicks));
else
label.setText(String.valueOf(--clicks));
}
});
}
add(buttonsPanel);
add(label, BorderLayout.PAGE_END);
setDefaultCloseOperation(EXIT_ON_CLOSE);
pack();
setLocationRelativeTo(null);
setVisible(true);
}
public static void main(String[] args) {
new ButtonsCount();
}
}
package javaisnotbannana;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.*;
import javax.swing.*;
public class Javaisnotbannana{
public static void main(String[] args) {
window();
}
////////////////////////////////////////////////////
public static void window()
{
JFrame window= new JFrame();
JPanel jp = new JPanel();
JLabel jl = new JLabel();
JTextField jt = new JTextField(30);
JButton jb = new JButton("Enter");
window.setTitle("ThisisTitleofWindow");
window.setVisible(true);
window.setSize(500, 500);
window.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//textfield
jp.add(jt);
jt.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String inoutt = jt.getText();
jl.setText(inoutt);
}
});
Why dose this lower section have the problem "Exception in thread "AWT-EventQueue-0" java.lang.StringIndexOutOfBoundsException: String index out of range:(how ever many characters i entered)".str is receiving what is typed in the Jtextfield and im trying to filter the input to give a different output. With out a filter it works fine like above just press enter,but when i try to press the button i and filter i get an error.
//button
jp.add(jb);
jb.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent e)
{
String str = jt.getText();
String text="";
int A=0;
int B=1;
int C=2;
for(int num=0;num<=str.length()/3;num++)
{
if (str.charAt(A) == 'T'&&str.charAt(B) == 'A'&&str.charAt(C)=='S')
{
text+="smell tasty";
}
else if(str.charAt(A) == 'B'&&str.charAt(B) == 'A'&&str.charAt(C)=='N')
{
text+="bannanas";
}
A+=3;
B+=3;
C+=3;
}
jl.setText(text);
}
});
jp.add(jl);
window.add(jp);
}
}
your index is overshooting use this instead
for(int num=0;num<str.length()/3;num++)
just < not <=
The problem seems to the fact that you are overthinking the it. Remember, Java Strings are zero indexed so num<=str.length()/3 should be something more like num < str.length()/3
But, having said that, the whole thing seems woefully inefficient (not to mention confusing)
You could use something like...
for (int num = 0; num + 3 < str.length(); num++) {
String test = str.substring(num, 3);
if ("tas".equalsIgnoreCase(test)) {
text = "smell tasty";
break;
} else if ("ban".equalsIgnoreCase(test)) {
text = "bannanas";
break;
}
}
But even that's a long way around an otherwise simple problem.
Instead, you could simply use something like...
String str = "tas";
String text = "";
if (str.toLowerCase().contains("tas")) {
text = "smell tasty";
} else if (str.toLowerCase().contains("ban")) {
text = "bannanas";
}
I am trying to create and simple program that has the user input 4 fields using the JFrame and textfields. Save those into a class. Put that class into an ArrayList (So they have the option to delete / or add more "classes" to it later). Then display all the contents of the ArrayList on one Frame.
I got the four fields to work I believe , but the part where the ArrayList contents are supposed to be displayed is not working ( I get a blank frame ).
this is my add into the arrayList ..
public void newEntryFrame()
{
JFrame entryFrame = new JFrame("Passafe");
entryFrame.setVisible(true);
entryFrame.setSize(500, 500);
entryFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
entryFrame.setLocationRelativeTo(null);
entryFrame.setLayout(new FlowLayout());
header.setFont(new Font("Serif", Font.BOLD, 16));
entryFrame.add(header);
entryFrame.add(nameLabel);
entryFrame.add(nametf);
entryFrame.add(usernameLabel);
entryFrame.add(usernametf);
entryFrame.add(passwordLabel);
entryFrame.add(passwordtf);
entryFrame.add(descriptionLabel);
entryFrame.add(descriptiontf);
entryFrame.add(enterButton);
enterButton.addActionListener(this);
}
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();
if(source == enterButton)
{
name = nametf.getText();
description = descriptiontf.getText();
username = usernametf.getText();
password = passwordtf.getText();
totalEntries++;
JOptionPane.showMessageDialog(null, "SAVED");
}
else if(source == okButton)
{
JOptionPane.showMessageDialog(null, "Ok Button Works");
}
}
this is what I have to display the arrayList.
public void viewEntryFrame()
{
JFrame viewFrame = new JFrame("Passafe");
viewFrame.setSize(500, 500);
viewFrame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
viewFrame.setLocationRelativeTo(null);
viewFrame.setLayout(new FlowLayout());
viewFrame.add(listHeader);
newEntry tempView = new newEntry();
for(int i = 0; i < totalEntries; ++i)
{
tempView = entries.get(i);
viewFrame.add(tempView.display);
}
viewFrame.add(okButton);
okButton.addActionListener(this);
viewFrame.setVisible(true);
}
I might be doing this completely wrong if so could you point me in the right direction.
I don't think you ever called setContentPane() A JFrame has only one component in the main part of it. You have to create a JPanel to which you can add all of the components you want, then add that to your JFrame.
JFrame frame = new JFrame();
JPanel panel = new JPanel();
panel.add(/**whatever you want in your JFrame**/);
//...
panel.add(/**whatever you want in your JFrame**/);
frame.setContentPane(panel);
You never seem to be adding anything to your entries list...
public void actionPerformed(ActionEvent event)
{
Object source = event.getSource();
if(source == enterButton)
{
name = nametf.getText();
description = descriptiontf.getText();
username = usernametf.getText();
password = passwordtf.getText();
totalEntries++;
// Nope, nothing here...
JOptionPane.showMessageDialog(null, "SAVED");
}
//...
}
Also, this is very dangrouos...
newEntry tempView = new newEntry();
for(int i = 0; i < totalEntries; ++i)
{
tempView = entries.get(i);
viewFrame.add(tempView.display);
}
Rather the relying on the actual side of the ArrayList, you relying on some other variable, which may or may not equal the actual size, instead you should be using ArrayList#size, for example
for(int i = 0; i < entries.size(); ++i)
{
newEntry tempView = entries.get(i);
viewFrame.add(tempView.display);
}
Or if you're using Java 5+...
for(newEntry tempView : enties)
{
viewFrame.add(tempView.display);
}
Hey I'm a little new here so my apologies if I messed something up in my post. Anyways the problem I'm having has to deal with arrays, what I'm trying to do basically is use the String[] arrays to populate my form and display it on screen and then have the getForm() function return a String[] with the title of the form and the info in text[i]. This all works fine until I use use the button I added to call the getForm() function and I change to a different form (createForm() attached to ListListener) and all the labels appear as whatever was returned in the getForm() function. I'm pretty sure it has something to do with the way I'm using my arrays but I thought they would be set back to normal after I chose another list item which goes through the createForm() function again resetting the arrays, so I'm not sure whats going on.
Thanks
I've included a screenshot of what I'm referring too bellow as well.
http://www.majhost.com/gallery/adc90/afsd/error.png
class Form extends JPanel
{
//Arrays for the forms
private String[] com = {"Communication","ICAO","Type","Frequency"};
private String[] fuel = {"Fuel","ICAO","Type"};
private String[] runway = {"Runway","ICAO","Number","Type","Length"};
private String[] airplane = {"Airplane","Make","Model","Type","Fuel Capacity", "Fuel Burn Rate", "Air Speed"};
private String[] airport = {"Airplane","ICAO","Name","Longitude","Latitude","crFreq","crType", "Fuel Type"};
//Declare variables
private JTextField[] text;
private String[] formReturn;
private String[] formArray;
private JButton submit,clear;
public Form()
{
createForm("Airplane");
}
public void createForm(String choice)
{
removeAll();
if(choice.equals("Communication"))
{
formArray = com;
}
else if(choice.equals("Fuel"))
{
formArray = fuel;
}
else if(choice.equals("Airplane"))
{
formArray = airplane;
}
else if(choice.equals("Airport"))
{
formArray = airport;
}
else if(choice.equals("Runway"))
{
formArray = runway;
}
int l = formArray.length + 1;
text = new JTextField[l];
//Layout info
GridLayout grid = new GridLayout(l,2);
grid.setHgap(0);
setLayout(grid);
//Set label
add(new JLabel(formArray[0]));
add(new JLabel(""));
for(int i = 1; i < formArray.length; ++i)
{
add(new JLabel(formArray[i]));
add(text[i] = new JTextField(20));
}
//Add in the buttons and the actionlisteners
submit = new JButton("Create");
clear = new JButton("Delete");
add(clear);
clear.addActionListener(new Button());
add(submit);
submit.addActionListener(new Button());
updateUI();
}
//Get form info
//This works so far
public String[] getForm()
{
formReturn = formArray;
formReturn[0] = formArray[0];
for(int i = 1; i < formReturn.length; i++)
formReturn[i] = text[i].getText();
return formReturn;
}
//Clear form
public void clearForm()
{
for(int i = 1; i < formArray.length; i++)
text[i].setText("");
}
}
public String[] getForm()
{
formReturn = formArray; /* (0) */
formReturn[0] = formArray[0];
for(int i = 1; i < formReturn.length; i++)
formReturn[i] = text[i].getText(); /* (1) */
return formReturn;
}
Look at line (1): you modify formReturn array which points to labels text. formReturn -> formArray -> com.
To fix it just create new String array at (0):
formReturn = new String[formArray.length];