I am trying to change elements in an array to the word "empty" with a Jbutton and also add names through a Jtextfield if the in the selected position in the array says empty. For some reason I cant get it to work. here is the code don't know if I am missing something or I am just completely wrong
move = new JButton("Add Tennant");
window.add(move);
moveIn.addActionListener(this);
Tennant = new JTextField(FIELD_WIDTH);
nTennant.setText("Enter new name") ;
window.add(Tennant);
Tennant.addActionListener(this);
evict = new JButton("Evict");
window.add(evict);
moveIn.addActionListener(this);
different method:
if(e.getSource() == move)
{
if (occupant[selectedApartment].equals("empty"))
{
occupant[selectedApartment] = Tennant.getText();
}
}
if(e.getSource() == evict)
{
if(!occupant[selectedApartment].equals("Empty"))
{
occupant[selectedApartment] = "Empty";
}
}
The first thing that jumps out at me is you use occupant[selectedApartment] = "Empty"; to set an apartment empty, but use if (occupant[selectedApartment].equals("empty")) to test if an apartment is empty
"Empty" != "empty"
You could change
if (occupant[selectedApartment].equals("empty"))
to
if (occupant[selectedApartment].equals("Empty"))
or use
if (occupant[selectedApartment].equalsIgnoreCase("empty"))
or change
occupant[selectedApartment] = "Empty";
to
occupant[selectedApartment] = "empty";
Related
I periodically check if a string which I get from a web service changed. This works just fine but if an old string is deleted from my method triggers, too.
For Example:
//I get this at the beginning
"One,Two,Three"
//And at the next check I get this
"Two,Three"
So the String changed and my method returned true like it is supposed to do.
But I only want to return true if e.g. "Four" is added to the string.
Can anyone give me a solution for this problem?
Thank you a lot,
Freezed
if (!oldstring.contains(newstring)))
return true;
Perhaps you could use split like so
public class MyClass {
public static void main(String args[]) {
String oldString = "This,Is,A,Test";
String[] oldItems = oldString.split(",");
String newString = "This,Is,A,New";
String[] newItems = newString.split(",");
// For each new item, check all old items
for (String newItem: newItems)
{
Boolean foundItem = false;
for (String oldItem: oldItems)
{
// Item was already in the old items
if (newItem.equals(oldItem))
{
foundItem = true;
break;
}
}
// New item is not in the old list of items
if (!foundItem)
{
System.out.println("New item added: " + newItem);
}
}
}
}
Something like
newString.contains(oldString) && !newString.equals(oldString)
Why not just trigger when the length of the string increases? The question doesn't state that what is being added matters--only whether something is being added at all.
boolean result = false;
if(newString.length() > oldString.length()) {
result = true;
break;
}
return result;
EDIT: Based on further clarification, I understand that the length of the string is not the best indicator, since something can be removed and added at the same time, in which case OP wants true returned--even if length is shorter. Here's a solution that splits the strings into tokens, and then checks whether the last token of the old string occurs before the last token of the new string, because that means something was added after it:
boolean result = false;
String delim = ",";
String oldStringTokens[] = oldString.split(delim);
String newStringTokens[] = newString.split(delim);
for(int i = 0; i < newStringTokens.length; i++) {
if(oldStringTokens[oldStringTokens.length-1].equals(newStringTokens[i])) {
if(i < newStringTokens.length - 1) {
result = true;
}
}
}
return result;
I have a final variable, save, that is a serializble class for some information. What I've attempted to do is to set a final variable as that serializable class, however I get some conflicting warnings. I'm attempting to make it so that if the file isn't loadable / doesn't exist, it will simply create a new instance, otherwise it will use the old one.
My issue as it stands is commented in the code at the constructor opening, closing, and on reading the object from the ObjectInputStream
private final CannonSet save;
public CannonManager(ManCannon plugin) { // Warning that save is not initialized
if (/* some conditional statement */) {
//lot of code removed, unnecessary to problem
//essentially, save was set conditionally here (loaded from file)
this.save = new CannonSet();
}
if (this.save == null) {
this.save = new CannonSet(); // Warning that save may have already been set
}
}
It looks like you just need to declare your temp object at full method scope, test if it's null at the bottom where you are checking this.save instead, and then do the assignment. Basically, just have one line ONLY where you assign the instance field. Abbreviated from your code:
public CannonManager(ManCannon plugin) {
CannonSet temp = null;
try{
// stuff happens
temp = (CannonSet) in.readObject();
}catch( ... ){
// exception handling
}
if(temp == null){
this.save = new CannonSet();
}else{
this.save = temp;
}
}
You can't do this to a final variable:
if (this.save == null) {
this.save = new CannonSet(); // Warning that save may have already been set
}
If save was initialized - and only in this case comparison to null is possible, then you can't reassign it.
Conditional logic is possible with final variables and in many cases it looks similar to:
final CannonSet save;
if(condition1){
save = new CannotSet(1);
} else
if(condition2){
save = new CannotSet(2);
} else {
save = new CannotSet(3);
}
I found that using a temp variable throughout the constructor made this a lot simpler:
private final CannonSet save;
public CannonManager(ManCannon plugin) {
CannonSet temp = null;
/* code .... */
if (temp == null) {
this.save = new CannonSet();
} else {
this.save = temp;
}
}
Here I have a GUI window and it basically ask the user to select a JRadioButton and type something in a JTextField, then choose confirm/cancel.
It is a project which we have to make a UML-to-Java text file. User would enter class information and choose a UML relationship, and this programme have to print out the Java clsas text on a JTextField. Just like when you create a new class in eclipse.
what I want to do is make a boolean[] to store an array of booleans, when user selects JRadioButton_A it'll store true and when user select JRadioButton_B it'll store false.And also I want the things typed in JTextField to be checked by a checkName(), if the method returns false, the string will be stored in an ArrayList.
Below is my code - there's some problems in getName() method and the boolean[] for storing true and false. When user needs to input name again, it would save the discarded sting/boolean into the array. (Sorry for my bad english!) Is there any better way to make this programme? I feel like I am complicating things and there should be a simpler way to make it.
Here's the UI stuffs asking user to enter class information. User have to select public/private and then type in class name and JTextField
private class Handler implements ActionListener{
public void actionPerformed(ActionEvent event){
String name = inputClassName.getText();
classObject.addName(name);
while (classObject.checkName(name) == true){
JOptionPane.showMessageDialog(null, "Class name invalid. " +
"\nEntered name should not contain java keywords or equal to other existing names. " +
"\nPlease try again."); // doesn't work
name = inputClassName.getText();
classObject.addName(name);
}// end if
JOptionPane.showMessageDialog(null, "Class saved."); // doesn't work
name = inputClassName.getText();
classObject.addName(name);
}// end actionPerformed()
}// end Handler class
private class Handler2 implements ActionListener{
public void actionPerformed(ActionEvent event){
boolean b = true;
b = classObject.setPP();
}
}
private class Handler3 implements ActionListener{
public void actionPerformed(ActionEvent event){
boolean b = false;
b = classObject.setPP();
}
}
Here's the methods for storing the inputs to the ArrayList and boolean[]
Scanner input = new Scanner(System.in);
JavaKeywords keyObject = new JavaKeywords();
private ArrayList<String> className = new ArrayList<String>();
private String name = new String();
private int size = className.size();
private Boolean[] bArray = new Boolean[size];
public boolean checkName(String name){
boolean check = true;
for (int i=0; i<=size; i++){
if (keyObject.containsKeyword(className.get(i)) || name.equals(className.get(i))){
boolean o = false;
check = o;
}// end if
}// end for
return check;
}// end checkName
public boolean setPP(){
boolean b = true;
return b;
}
public void addPP(Boolean[] bArray){
this.bArray = bArray;
for (int i=0; i>=size; i++){
bArray[i] = setPP();
}
}// add a Array of boolean. for className[i], its class type = item[i] in bArray.
// public = true, private = false
public String getPublicPrivate(){
String p = "";
for (int i =0; i<=size; i++){
if(bArray[i]=true)
p = "public";
else
p = "private";
}
return p;
}
Solved
Solution: store the string className and boolean isPrivate in a class and make the class into an ArrayList can save me from all the trouble. But then i faced anther problem, that is the checkName() doesn't work after I changed my code.
here is the ActionListener
private class Handler implements ActionListener{
public void actionPerformed(ActionEvent event){
VirtualClass virtualObject = new VirtualClass();
classObject.addClass(virtualObject);
String name = inputClassName.getText();
virtualObject.className = name;
if (classObject.checkName(name) == false){
JOptionPane.showMessageDialog(null, "Class name invalid. " +
"\nEntered name should not contain java keywords or equal to other existing names. " +
"\nPlease try again."); // Always return "invalid" message
} else {
JOptionPane.showMessageDialog(null, "Class saved.");
name = inputClassName.getText();
virtualObject.className = name;
}
if (event.getSource() == publicButton) {
virtualObject.isPrivate = false;
} else if (event.getSource() == privateButton) {
virtualObject.isPrivate = true;
}
}// end actionPerformed()
and here is the checkName() method
public boolean checkName(String name){
boolean check = true;
for (int i=0; i<=size; i++){
if (keyObject.containsKeyword(classes.get(i).className) || name.equals(classes.get(i).className)){
boolean o = false;
check = o;
}// end if
}// end for
return check;
}// end checkName
For containsKeyword() in checkName() I've used a JavaKeywords class from How to check if the class name is valid? by #MrLore.
Probably what I would do is create a simple class to represent your fields so you don't have to use multiple lists at all.
public class VirtualClass {
public boolean isPrivate;
public String className = "Object";
}
ArrayList<VirtualClass> classes = new ArrayList<VirtualClass>(0);
public void addClass(VirtualClass clazz) {
classes.add(clazz);
}
Otherwise you will have to create a second list of some kind to hold the public/private. You will just have to change them in parallel.
// in actionPerformed
ClassObject.VirtualClass clazz = new ClassObject.VirtualClass();
clazz.isPrivate = rbPrivate.isSelected();
clazz.className = tfClassName.getText();
classObject.addClass(clazz);
And just ignore the listening on the radio buttons since you technically do not need their states until you go to add the class to the list.
To access the fields later you just need to
for (VirtualClass clazz : classes) {
System.out.println((clazz.isPrivate ? "private" : "public") + " " + clazz.className);
}
// or something like
for (int i = 0; i < classes.size(); i++) {
System.out.println(classes.get(i).className + ":");
if (classes.get(i).isPrivate) {
System.out.println(" private");
} else {
System.out.println(" public");
}
}
I'm not entirely convinced by your over all approach. What I think "should"/"could" happen is, the user enters all the information you ask, they hit "accept", you valid the information that the user has entered and if it is correct, you create a new object representing the results of this input as you need.
I would, personally, avoid using an array of booleans, or at least, expose them differently. The main problem I have with it is keeping it all straight in my head, what does the element at 0 actually mean?
Instead, I would provide getter/setters on the ClassName class that allowed me to set/get particular properties. You could, of course, keep the values in an array internally, but anyone using the class wouldn't need to know how you store these values.
The problem with your check name Handler is the fact you are blocking the Event Dispatching Thread with your while-loop
This will stop you program from responding to user input (and painting itself)
while (classObject.checkName(name) == true){
JOptionPane.showMessageDialog(null, "Class name invalid. " +
"\nEntered name should not contain java keywords or equal to other existing names. " +
"\nPlease try again."); // doesn't work
name = inputClassName.getText();
classObject.addName(name);
}// end if
Swing is a single threaded framework, meaning that all interactions and changes to the UI are expected to be executed within the context of the EDT. Equally, anything that blocks or stops this thread from processing the Event Queue, will stop it from responding to new events, including repaint requests, making your program hang
Instead, you should simply check the name within a if-else statement. If it's valid, create the new ClassName object, if it's not, display a message and let the method exit.
Check out Concurrency in Swing for more details
I have a program that allows the user to choose between a binary search tree a splay tree and a red black tree. I wrote the class for the binary search tree and now im working on the splay tree but ive realized that my method that interacts with the user only works with the binary search tree. I set it up so that it will create an instance of whichever tree the user selects but down in my code I use only the variable that would be created if the user selected a binary search tree. My question is how can i make it so that I will only create an instance of the tree that the user selected and how can i use only one variable so that when i insert items or work on the tree i dont have to add more conditional statements for different trees?
this is what i have now
import java.util.Scanner;
import java.lang.Math.*;
public class Driver1
{
public static void main(String[] args)
{
//local variables
String treeChoice = null;
String choice = null;
String choice2 = null;
String command = null;
int insertAmount = -1;
String pattern;
int height = -1;
int i = -1;
//BST<Integer> myTree = null;
//ST<Integer> mySTTree = null;
int num = 0;
//Scanners to take user input
Scanner input = new Scanner(System.in);
Scanner inputt = new Scanner(System.in);
System.out.println("Which tree would you like to test (BST, ST, RBT)? ");
treeChoice = input.nextLine();
//Based on user input either a BST, Splay Tree, or RBT will be initialized.
if("BST".equalsIgnoreCase(treeChoice))
{
BST<Integer> myTree = new BST<Integer>();
}
else if("ST".equalsIgnoreCase(treeChoice))
{
//System.out.println("Splay Tree not ready yet");
ST<Integer> mySTTree = new ST<Integer>();
}
else if("RBT".equalsIgnoreCase(treeChoice))
{
System.out.println("RBT not ready yet");
//RBT<Integer> myTree = new RBT<Integer>();
}
else
{
System.out.println("Invalid Entry");
}
//Ask user how many items to input
System.out.println("How many items would you like to insert? ");
insertAmount = input.nextInt();
//ask user if the items will be random or sorted
System.out.println("Pattern (random or sorted): ");
choice2 = inputt.nextLine();
//If random, create random numbers
if("random".equalsIgnoreCase(choice2))
{
for(i = 1; i <= insertAmount; i++)
{
myTree.insert((int)(Math.random()*1000000)+i);
}
}
//else fill the tree with numbers in order from 1 to the user limit
else if("sorted".equalsIgnoreCase(choice2))
{
for(i = 1; i <= insertAmount; i++)
{
myTree.insert(i);
}
}
//Keep asking users input on what to do to the tree until user says quit
while(command != "quit")
{
System.out.println(
"Next command (insert X, delete X, find X, height, quit)?");
command = inputt.nextLine();
if (command.startsWith("insert"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.insert(num);
if(result == false)
{
System.out.println("Item already present.");
}
}
else if(command.startsWith("delete"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.delete(num);
}
else if(command.startsWith("find"))
{
num = Integer.parseInt(command.replaceAll("\\D", ""));
boolean result = myTree.find(num);
if(result == true)
{
System.out.println("Item present.");
}
else
{
System.out.println("Item not present.");
}
}
else if(command.startsWith("height"))
{
System.out.println("Current height of tree " + myTree.height());
}
else if(command.startsWith("quit"))
{
break;
}
System.out.println();
}
}//Close main method
as you can see I fill only myTree which would be the tree created if the user selected bst. and in the while loop i only work on myTree.
How can i make this more generic or my other idea was to take the users input and then create the instance of that tree and then pass the instance into a seperate method so that i could still use only myTree since it would refer to the instance that was passed into that method but im not sure how to pass an instance into another method. This way seems like the best but im not sure
any help is appreciated
Your trees should extend a common base class, or better, a implement common interface, say Tree, that specifies the methods to be used on all trees (find, insert, delete). Then you should have only one variable Tree myTree to which you assign an actual instance of the type the user selects.
Are you sure your above code works, however? If you do this
if("BST".equalsIgnoreCase(treeChoice))
{
BST<Integer> myTree = new BST<Integer>();
}
then the variable myTree will be unavailable after the } because the code block in which it is declared ends there. You can declare a variable at one point and assign a value to it later, like so:
Tree<Integer> myTree;
if("BST".equalsIgnoreCase(treeChoice)) {
myTree = new BinarySearchTree<Integer>();
} else if("ST".equalsIgnoreCase(treeChoice)) {
myTree = new SplayTree<Integer>();
} else if("RBT".equalsIgnoreCase(treeChoice)) {
myTree = new RedBlackTree<Integer>();
} else {
throw new IllegalArgumentException(treeChoice + " is not a valid input");
}
I very much recommend that you give your classes real names that make obvious what they represent, not just two or three letter combinations. Note that if you do not throw an exception in the last else branch, the compiler will later complain that "the variable myTree may not have been initialized".
Alternatively, you could put all your code after the tree creation if-else-statements into a method, say <T> void testTree(Tree<T> myTree) and call this method directly where you evaluate the user input, e.g. if("BST".equalsIgnoreCase(treeChoice)) testTree(new BinarySearchTree<Integer>());, but at some you will want to assign it to a variable anyway.
I am not sure how to ask this. The program I am working on is done, but it seems like it has excessive code. Here is part of the code:
chkDef1 = new JCheckBox
if (chkDef1.isSelected()) {
actual = chkDef1.getText();
}
else if (chkDef2.isSelected()) {
actual = chkDef2.getText();
}
else if (chkDef3.isSelected()) {
actual = chkDef3.getText();
}
else {
actual = chkDef4.getText();
}
There are other areas where there is a lot of duplicate code with the chkDef1 - 4 checkboxes. What I would like to do is use a loop in the areas where the code is duplicated and then just use 1 assignment statement.
I've tried :
if(('chkDef' + counter).isSelected())
I've also tried assigning "'chkDef' + counter" to a String variable and then adding isSelected. Unfortunately I keep getting error messages.
I am a novice programmer so I do not know if what I want to do is possible or what it is called. If it is possible an explanation of how would be appreciated.
Simply create a list of checkboxes and iterate through it.
ArrayList<JCheckBox> checkboxes = new ArrayList<JCheckBox>();
//Init your checkboxes array.
for(JCheckbox chkbox :checkboxes)
{
if(chkbox.isSelected())
{
actual = chkbox.getText() ; break;
}
}
Although, there could be a JCheckbox group that does what you want.
Looks like you can use ButtonGroup and get the elements to iterate through it.
You could create an array that contains all the check boxes and then loop through the array...
JCheckBox[] boxes = new JCheckBox[] {chkDef1,chkDef2,chkDef3,chkDef4}
for (JCheckBox box : boxes) {
if (box.isSelected()) {
actual = box.getText();
break; // We don't want to loop unnecessarily
}
}
Equally, you could create a simple method that takes a variable number of arguments...
public String getCheckedItem(JCheckBox... boxes) {
String actual = null;
for (JCheckBox box : boxes) {
if (box.isSelected()) {
actual = box.getText();
break; // We don't want to loop unnecessarily
}
}
return actual;
}
And call it like...
String actual = getCheckItem(chkDef1, chkDef2, chkDef3, chkDef4);
Personally, I'd return the check box, but that's up to you
If you're only interested in maintaining a single selected check box (ie not allowing multiple check boxes to be selected) then you should seriously consider using JRadioButtons and ButtonGroup instead.
Otherwise you could collect ALL the selected checked boxes...
public JCheckBox[] getCheckedItem(JCheckBox... boxes) {
List<JCheckBox> selected = new ArrayList<JCheckBox>(boxes.length);
for (JCheckBox box : boxes) {
if (box.isSelected()) {
selected.add(box);
}
}
return selected.toArray(new JCheckBox[selected.size]);
}