cannot find symbol for method in a class of array objects - object

I have a class Card to represent a deck of cards as an array of objects Card[], with methods to shuffle and print the deck. I have a test class TestCard to generate the deck (in TestCard) then shuffle and print the deck (as methods in Card.) I get the message
TestCard.java:17: error: cannot find symbol
mydeck.writeDeck();
^
symbol: method writeDeck()
location: variable mydeck of type Card[]
Here is the Card.java code.
public class Card {
public static final int NUMCARDS=52;
String suit;
int value;
String name;
public Card() {
suit = " ";
value = 0;
name = " ";
}
public Card(String suit, int value, String name) {
this.suit=suit;
this.value=value;
this.name=name;
}
public void setData(String su,int va, String na) {
suit = su; value = va; name = na;
}
public void writeDeck(Card[] cards) {
int count=0;
for (Card mycard : cards ) {
System.out.print(mycard.name+mycard.suit);
count++;
if (count==13) {
System.out.println();
count= 0;
}
}
System.out.println();
}
private void swap(Card[] arr,int i, int j) {
Card temp=arr[i];
arr[i]=arr[j];
arr[j]=temp;
}
public void shuffle(Card[] carr) {
int index;
for (int i=NUMCARDS-1; i>0; i--) {
index = (int) (Math.random() * (i+1));
swap(carr, i, index);
}
}
}
and here is TestCode.java code
public class TestCard {
public static final int NUMCARDS=52;
public static void main(String args[]) {
Card[] mydeck = new Card[NUMCARDS];
for (int i=0; i<NUMCARDS; i++) {
int j=i%13+1;
String v;
v = Integer.toString(j);
String s;
if (i<13) s="C";
else if (i<26) s="D";
else if (i<39) s="H";
else s="S";
mydeck[i] = new Card(s,j,v);
}
System.out.print(mydeck[5].suit+mydeck[5].value);
mydeck.writeDeck();
mydeck.shuffle();
mydeck.writeDeck();
}
}
I have spent 8 hours trying various fixes, using tutorials from various we sites, but have not succeeded.

mydeck.writeDeck(); is trying to call the writeDeck() method of the instance mydeck. But if you look at the code:
Card[] mydeck = new Card[NUMCARDS];
my deck is not a Card object, it's an array of Card objects. According to your code, you must pass in a Card[] as a parameter.
Turn .writeDeck(Card[] cards) into a static method:
public static void writeDeck(Card[] cards)
and then invoke the method like so:
Card.writeDeck(mydeck)

Marvin's answer worked like a charm. According to the Oracle documentation, for a method to work on an array of objects, the method must be defined for the object. But you can't just simply say arrayvar.method(). You have to say Objectclass.method(arrayvar). Good news is you can pass two array variables if you are working with both.

Related

OOPs: Count is not updated when trying to use countObject( ) function?

public class Practice {
public static void main(String[] args) {
Test t1 = new Test();
//System.out.println( Test.countObject() );
Test t2 = new Test(9);
//System.out.println( Test.countObject() );
Test t3 = new Test("Soham");
System.out.println( Test.countObject() );
}
}
class Test{
static int count = 0;
static int countObject(){
count++;
//System.out.println(count);
return count;
}
public Test(){
}
public Test(int n){
}
public Test (String s){
}
}
In this code , I'm trying print the count of objects by calling countObject() (don't want to call by a constructor) bt my count is not updated even after creating 3 objects. my count is only updated if I call Test.countObject() thrice . Why this is happening ? and how can I solve the problem (count object in a single call by countObject Function) ?

read write object in codenameone storage

I'm developing a j2me application based on codenameone. I implements some codes and Now I wanna add database to my application. After search a lot I found Storage class of codenameone that simplify database concept in mobile application.
In this appliaction I create a class for each entity (like person, city, ...) and add "read" and "write" method to read and write data.
Some entity classes have 2 or more fields. So I must save and read them with Storage class.
How can I do this?
Here is my sample code:
package com.x.database;
import com.codename1.io.Storage;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.Iterator;
public class Person {
public Person(){
}
public Person(int pID, String pPersonNumber){
ID = pID;
PersonNumber = pPersonNumber;
}
public static String PERSON = "Person";
private Storage store;
private int ID;
public int getID(){
return ID;
}
public void setID(int pID){
ID = pID;
}
private String PersonNumber;
public String getPersonNumber(){
return PersonNumber;
}
public void setPersonNumber(String pPersonNumber){
PersonNumber = pPersonNumber;
}
public int getLastKeyNumber(){
if(store == null) {
store = Storage.getInstance();
}
Hashtable depHash = (Hashtable)store.readObject(PERSON);
ArrayList<String> keyArray = (ArrayList<String>)depHash.keys();
int i = 0;
for (Iterator<String> it = keyArray.iterator(); it.hasNext();) {
int tmp = Integer.parseInt(it.next());
i = i < tmp ? tmp : i;
}
return i;
}
public void write(Person pPerson){
if(store == null) {
store = Storage.getInstance();
}
if(!store.exists(PERSON)) {
Hashtable depHash = new Hashtable();
try {
depHash.put("0", pPerson);
} catch (IOException ex) {
System.out.println(ex.getMessage());
}
store.writeObject(PERSON, depHash);
}
else {
Hashtable depHash = (Hashtable)store.readObject(PERSON);
ArrayList<Person> depArray = (ArrayList<Person>)depHash.keys();
for (Iterator<Person> it = depArray.iterator(); it.hasNext();) {
Person tmp = it.next();
if(!tmp.getPersonNumber().equals(pPerson)) {
depHash.put(String.valueOf(getLastKeyNumber()), pPerson.getPersonNumber());
store.writeObject(Person depHash);
}
}
}
}
public ArrayList<Person> readAll(){
Storage store = Storage.getInstance();
if(!store.exists(PERSON)) {
Hashtable depHash = (Hashtable)store.readObject(PERSON);
return (ArrayList<Person>)depHash.elements();
}
return new ArrayList<Person>();
}
}
In this code I have an error on write and read object on Storage.
How can I write one object in Storage and read it again?
Thanks in advance.
You can store a Vector or a Hashtable in storage and nest them as deeply as you like e.g.:
Vector v = new Vector();
Hashtable content = new Hashtable();
content.put("A", ...);
content.put("B", ...);
v.addElement(content);
Etc... You can add more hashes and they can contain Strings, numbers or byte arrays.
Alternatively you can implement the Codename One Externalizable interface which allows you to write an arbitrary class to storage. This poses one requirement though, you need to call Util.register in order to register the externalizable class name. There is a sample of this in the tipster demo.

ManagementObjectCollection count property leaks?

Just recently a few colleagues of mine helped out with narrowing down a memory leak. One of the problems was found in Microsoft's code. This is from reflector showing that the enumerator will leak.
Here the count property calls getenumerator but never checks for Idisposable:
public int Count
{
get
{
if (this.isDisposed)
{
throw new ObjectDisposedException(name);
}
int num = 0;
IEnumerator enumerator = this.GetEnumerator();
while (enumerator.MoveNext())
{
num++;
}
return num;
}
}
This is the ManagementObjectCollection's GetEnumerator just to show the type returned is a ManagementObjectEnumerator.
public ManagementObjectEnumerator GetEnumerator()
{
if (this.isDisposed)
{
throw new ObjectDisposedException(name);
}
if (!this.options.Rewindable)
{
return new ManagementObjectEnumerator(this, this.enumWbem);
}
IEnumWbemClassObject ppEnum = null;
int errorCode = 0;
try
{
errorCode = this.scope.GetSecuredIEnumWbemClassObjectHandler(this.enumWbem).Clone_(ref ppEnum);
if ((errorCode & 0x80000000L) == 0L)
{
errorCode = this.scope.GetSecuredIEnumWbemClassObjectHandler(ppEnum).Reset_();
}
}
catch (COMException exception)
{
ManagementException.ThrowWithExtendedInfo(exception);
}
if ((errorCode & 0xfffff000L) == 0x80041000L)
{
ManagementException.ThrowWithExtendedInfo((ManagementStatus) errorCode);
}
else if ((errorCode & 0x80000000L) != 0L)
{
Marshal.ThrowExceptionForHR(errorCode);
}
return new ManagementObjectEnumerator(this, ppEnum);
}
This showing that it is disposable:
public class ManagementObjectEnumerator : IEnumerator, IDisposable
{
// Fields
private bool atEndOfCollection;
private uint cachedCount;
private IWbemClassObjectFreeThreaded[] cachedObjects;
private int cacheIndex;
private ManagementObjectCollection collectionObject;
private IEnumWbemClassObject enumWbem;
private bool isDisposed;
private static readonly string name;
// Methods
static ManagementObjectEnumerator();
internal ManagementObjectEnumerator(ManagementObjectCollection collectionObject, IEnumWbemClassObject enumWbem);
public void Dispose();
protected override void Finalize();
public bool MoveNext();
public void Reset();
// Properties
public ManagementBaseObject Current { get; }
object IEnumerator.Current { [TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")] get; }
}
Though enumerators that are disposable are disposed of properly by foreach statements (http://msdn.microsoft.com/en-us/library/aa664754(v=vs.71).aspx), this does not mean that the only case where the enumerator will be used is in a foreach loop.
I know that you can skip the count property and roll your own mechanism for getting the number of objects in the collection by using the enumerator yourself but the question I have is how much unmanaged memory does this leak?

How to apply mask formatting to TextField?

I am creating some forms and I need to create masks and validation for some fields.
Is it implemented in anyway in JavaFX?
My example of the mask.
Using:
<MaskField mask="+7(DDD)DDD-DDDD"/>
<MaskField mask="AA DDD AAA" placeholder="__ ### ___"/>
etc
Restricting input from Richard's fxexperience post:
TextField field = new TextField() {
#Override public void replaceText(int start, int end, String text) {
// If the replaced text would end up being invalid, then simply
// ignore this call!
if (!text.matches("[a-z]")) {
super.replaceText(start, end, text);
}
}
#Override public void replaceSelection(String text) {
if (!text.matches("[a-z]")) {
super.replaceSelection(text);
}
}
};
If you want to create your use a mask and create your own control, take a look at Richard's MoneyField, which also includes a sample project and source. Along the same lines there are controls to restict input to Integers, Doubles or formatted web colors (e.g. #rrggbb) in the fxexperience repository. All of these follow a common theme where they subclass Control, provide some properties to be get and set which define the public interface and then also define a private backing skin which handles rendering of the UI based on the values set through the public interface.
I had the same needs. I created this field, called it SpecialTextField, and pushed into GitHub. Example also there. Hope this help.
NOTE: this only works correctly with JRE 1.8.0_25 or lower. With JRE 1.8.0_48 or 0_51, the caret position is always set to 0 after each character input.
No, this is not implemented in standard JavaFX. You need to use some library or do it yourself.
This is my implementation of static mask for text fields. It works for date, phone and other types of static masks:
/**
* Adds a static mask to the specified text field.
* #param tf the text field.
* #param mask the mask to apply.
* Example of usage: addMask(txtDate, " / / ");
*/
public static void addMask(final TextField tf, final String mask) {
tf.setText(mask);
addTextLimiter(tf, mask.length());
tf.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
String value = stripMask(tf.getText(), mask);
tf.setText(merge(value, mask));
}
});
tf.setOnKeyPressed(new EventHandler<KeyEvent>() {
#Override
public void handle(final KeyEvent e) {
int caretPosition = tf.getCaretPosition();
if (caretPosition < mask.length()-1 && mask.charAt(caretPosition) != ' ' && e.getCode() != KeyCode.BACK_SPACE && e.getCode() != KeyCode.LEFT) {
tf.positionCaret(caretPosition + 1);
}
}
});
}
static String merge(final String value, final String mask) {
final StringBuilder sb = new StringBuilder(mask);
int k = 0;
for (int i = 0; i < mask.length(); i++) {
if (mask.charAt(i) == ' ' && k < value.length()) {
sb.setCharAt(i, value.charAt(k));
k++;
}
}
return sb.toString();
}
static String stripMask(String text, final String mask) {
final Set<String> maskChars = new HashSet<>();
for (int i = 0; i < mask.length(); i++) {
char c = mask.charAt(i);
if (c != ' ') {
maskChars.add(String.valueOf(c));
}
}
for (String c : maskChars) {
text = text.replace(c, "");
}
return text;
}
public static void addTextLimiter(final TextField tf, final int maxLength) {
tf.textProperty().addListener(new ChangeListener<String>() {
#Override
public void changed(final ObservableValue<? extends String> ov, final String oldValue, final String newValue) {
if (tf.getText().length() > maxLength) {
String s = tf.getText().substring(0, maxLength);
tf.setText(s);
}
}
});
}
See also:
JavaFX 2.2 TextField maxlength
Supported by current javafx-2 platform by default - No, but go through this link , it has many insights and sample code for Form validation in javaFX
public class NumberTextField extends TextField {
private int maxLenght;
public NumberTextField(int maxLenght) {
super();
this.maxLenght = maxLenght;
}
#Override
public void replaceText(int start, int end, String text) {
if (validate(text)) {
super.replaceText(start, end, text);
}
}
#Override
public void replaceSelection(String text) {
if (validate(text)) {
super.replaceSelection(text);
}
}
private boolean validate(String text) {
if (this.getText() != null) {
}
boolean status = ("".equals(text) || text.matches("[0-9]"));
if (this.getText() == null) {
return status;
} else {
return (status && this.getText().length() < maxLenght);
}
}
}
In some cases I would validate the text property:
myTextField
.textProperty()
.addListener(
(obs, oldVal, newVal) ->
{
if(!newVal.matches("\\d+"))
textField.setText(oldV);
});
Unlucky: textField.setText(oldV); will enter the same function again, testing unnecessarily if oldVal matches.
If the TextField becomes a value that doesn't matches before this listener is added to the TextField, enter a not matching new value will cause a loop!!!
To avoid this, it will be safer to write:
String acceptableValue = "0";
myTextField
.textProperty()
.addListener(
(obs, oldVal, newVal) ->
{
if(!newVal.matches("\\d+"))
textField.setText(oldVal.matches("\\d+") ? oldV : acceptableValue);
});
I wrote a class that extends the TextField and apply the mask.
package com.model;
import java.text.NumberFormat;
import java.util.Locale;
/**
* ATENTION
* DO NOT FORGUET TO IMPORT IN FXML
* <?import com.view.TextFieldMoney?>
*
* */
import javafx.scene.control.TextField;
public class TextFieldMoney extends TextField {
private int maxlength;
private String valor = "";
public TextFieldMoney() {
this.maxlength = 11;
}
public void setMaxlength(int maxlength) {
this.maxlength = maxlength;
}
#Override
public void replaceText(int start, int end, String text) {
// Delete or backspace user input.
if (getText() == null || getText().equalsIgnoreCase("")) {
valor = "";
}
if (text.equals("")) {
super.replaceText(start, end, text);
} else{
text = text.replaceAll("[^0-9]", "");
valor += text;
super.replaceText(start, end, text);
if (!valor.equalsIgnoreCase(""))
setText(formata(valor));
}
}
#Override
public void replaceSelection(String text) {
// Delete or backspace user input.
if (text.equals("")) {
super.replaceSelection(text);
} else if (getText().length() < maxlength) {
// Add characters, but don't exceed maxlength.
// text = MascaraFinanceira.show(text);
if (text.length() > maxlength - getText().length()) {
// text = MascaraFinanceira.show(text);
text = text.substring(0, maxlength - getText().length());
}
super.replaceSelection(text);
}
}
/*
*Return the number without money mask
**/
public String getCleanValue(){
String cleanString = getText().replaceAll("[^0-9]", "");
Double cleanNumber = new Double(cleanString);
return String.valueOf(cleanNumber/100);
}
private String formata(Double valor) {
Locale locale = new Locale("pt", "BR");
NumberFormat nf = NumberFormat.getInstance(locale);
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
return nf.format(valor);
}
public String formata(String valor) {
double v = new Double(valor);
return formata(v/100);
}
}
And in the FXML where is
<TextField fx:id="valorTextField" GridPane.columnIndex="2" GridPane.rowIndex="2" />
put
<TextFieldMoney fx:id="valorTextField" GridPane.columnIndex="2" GridPane.rowIndex="2" />

Array List in C# without a loop

I like to know how to initialise the array without the loops like for, foreach or any LINQ.
From the following code, need to find under 2m length cars within .Netframework using console application.
{
ArrayList = CarType new ArrayList();
CarType.Add(new CarList("Ford"));
((CarList)CarType[0]).Cars.Add(new Car("Focus", 2));
((CarList)CarType[0]).Cars.Add(new Car("Fiesta", 1));
CarType.Add(new CarList("Peugeout"));
((CarList)CarType[1]).Cars.Add(new Car("206", 1));
((CarList)CarType[1]).Cars.Add(new Car("407", 2));
RemoveLargeCars(CarType);
}
public static ArrayList RemoveLargeCars (ArrayList CarType)
{
//Array List should be here
return CarType;
}
It has got two classes as follows.
class Car
{
public string name;
public float length;
public Car(string newName, float newLength)
{
this.name = newName;
this.length = newLength;
}
}
Class CarList
{
public string CarType;
public ArrayList Pipes;
public CarList(string newCarType)
{
carType = newCarType;
Cars = new ArrayList();
}
}
Can you please let me know how to solve this.
Thanks in advance.
Use the static Adapter method on ArrayList
CarType = ArrayList.Adapter(CarList);
But that probably uses a loop internally, you can't get away from them, but at least this hides them.
Well, first of all you should use the generic list type List<T> instead of ArrayList, that will make the code simpler. (And best practive recommends properties rather than public fields):
class Car {
public string Name { get; set; }
public float Length { get; set; }
public Car(string newName, float newLength) {
Name = newName;
Length = newLength;
}
}
class CarList {
public string CarType { get; set; }
public List<Car> Cars { get; set; }
public CarList(string newCarType, List<Car> newCars) {
CarType = newCarType;
Cars = newCars;
}
public CarList(string newCarType) : this(newCarType, new List<Car>()) {}
}
Now use a List<CarList>:
List<CarList> CarType = new List<CarList>();
CarList ford = new CarList("Ford");
CarType.Add(ford);
ford.Cars.Add(new Car("Focus", 2));
ford.Cars.Add(new Car("Fiesta", 1));
CarList peugeot = new CarList("Peugeout");
CarType.Add(peugeot);
peugeot.Cars.Add(new Car("206", 1));
peugeot.Cars.Add(new Car("407", 2));
List<CarList> smallCars = RemoveLargeCars(CarType);
You can use extension methods to easily filter out cars based on a condition:
public static List<CarList> RemoveLargeCars(List<CarList> CarType) {
return CarType.Select(
t => new CarList(t.CarType, t.Cars.Where(c => c.Length < 2f).ToList()
) .ToList();
}
Note that the method doesn't change the original list, but creates a new list.

Resources