I am making exactly the same Java program that is in this link:
Run-time Polymorphism in Java without "abstract"?
But I am having problems in the Main Application.
In my problem I have to ask the user to enter which types does he want(Bicycle,MountainBike,RoadBike).
And then I add what type he chose to an array of 5 indexes.
How can I do that?
Please give me some help.
Thanks in advance.
I don't know how you look for answers from your users, but if it's buttons you do it with, you can just add the requested type of object, when a user press specific buttons.
But what you have to do, is make an ArrayList<Bicycle> and then just add the objects that extends Bicycle.
You should create a factory method that returns an instance of a Bicycle:
For example:
public Bicycle createBicycle(String type) {
if (type.equals("Bicycle")) {
return new Bicycle(20, 10, 1);
} else if (type.equals("MountainBike")) {
return new MountainBike(20, 10, 5, "Dual");
}
//and so on..
}
And use it like this for example:
Bicycle[] bicycles = new Bicycle[5];
bicycle[0] = createBicycle("Bicycle");
Related
So this is my very first mini-javaproject and I have been stuck for days now on the basic structure and the (non existing) relation between anything within my code. I linked the code in my comment below, could not paste it in here for some reason - (Main is empty, so did not copy it.)
So I spent some time getting my head around the basics of Java (as my first programming adventure) and to be honest I felt pretty confident. (On Codewars I completed like 100+ Katas, but of course those are "single-class", so I was not prepared for the "real world.)
It is hard to exactly pinpoint my question, but I will try to give some examples.
1, (Main is empty right now, but anyway) Basically "nothing can be used" in main. Like methods of objects, like room1, or player1, etc.
2, In my Room.java line 21-22 why is the object room1 not visible? Why does Intellij say "Unknown class: RoomArray if I just created that very thing before??
3, I understand that I am supposed to have my variables set to private, which I plan to do later on. Also, I should use setter and getter methods, which I tried to do so with basically everything. But for example in Player.java I have this
Player player1 = new Player(300, 50, "Conan", 75, false);
public Player getPlayer1() {
return player1;
}
and if I try to use the getPlayer1() method in any other class it just simply can not see/access it?
3, And to make me even more confused Room1 class has access to getMyDungeon () method created in the Dungeon class. Why is that so?
(Maybe it has to do with inheritance? The fact that Room1 extends Room which extends Room? But if so, it seems strange because not all classes can have a HAS-A or IS-A relationship with something. An example - if I create all 10 Rooms later on as Room1, Room2, etc. in separate classes, how could I ever create a Room [] array containing them? No matter where I started to do that it will always give me the error "Cannot resolve smybol" for all the Room objects...)
I have spent the past few days reading up on the topic and understand it all, but still when I try to build this project it all falls apart. I realize that an experienced programmer might not even my question because how basic it is, but if anyone can help me to get this whole thing clear in my head, I would appreciate it. (Really not looking for the complete code, but just some direction I should go, or the missing step, etc.)
It seems you to be trying to create an object within the class of that object The correct use is:
public static void main(String[] args){
Player player1 = new Player(300, 50, "Conan", 75, false);
}
or if you want your Room class to have a lot of players
public class Room {
//this object will be create when you do Room room = new Room();
List<Player> players = new ArrayList<>();
public void createPlayer(){
players.add(new Player());
}
//this is a getter
public List<Player> getPlayers() {
return players;
}
}
your Player:
public class Player {
//Fields and Methods
}
and your main:
public static void main(String[] args)
{
Room room =new Room();
room.createPlayer();
for (Player p:room.getPlayers()) {
//p.doSomething
}
}
if you want an object to be created without the need to create an instance from the outside you need to use the static keyword (don't do that unless you know what you are doing)
static Player player1 = new Player(300, 50, "Conan", 75, false);
public static Player getPlayer1() {
return player1;
}
I'm POSITIVE that my title for this topic is not appropriate. Let me explain. The purpose of this is to duplicate a "Profile" application, where I have a profile and so would you. We both have our own followers and in this example, we both follow each other. What this method is needed to return is a cross reference based on whom you follow that I do not. I need this method to return to me a recommended Profile object that I do not already have in my array. Right now I'm having a difficult time with one line of code within a particular method.
One of my classes is a Set class that implements a SetInterface (provided by my professor) and also my Profile class that implements a ProfileInterface which was also provided. In my code for the Profile class, I have the following object: private Set<ProfileInterface> followBag = new Set<ProfileInterface>(); which utilizes the Array bag methods from my Set class with the ProfileInterface methods I've made.
Here is the method (not complete but can't move further without my problem being explained):
public ProfileInterface recommend(){
Set<ProfileInterface> recommended;
ProfileInterface thisProfile = new Profile();
for(int index = 0; index < followBag.getCurrentSize(); index++){
Set<ProfileInterface> follows = followBag[index].toArray();
for(int followedFollowers = 0; followedFollowers < follows.getCurrentSize(); followedFollowers++) {
if()
//if Profile's do not match, set recommended == the Profile
}
}
return recommended;
}
The purpose of this method is to parse through an array (Profile as this example) and then take each of those sub-Profiles and do a similar action. The reason for this much like "Twitter", "Facebook", or "LinkedIn"; where each Profile has followers. This method is meant to look through the highest Profiles follows and see if those subProfiles have any followers that aren't being followed by the highest one. This method is then meant to return that Profile as a recommended one to be followed. This is my first dealing with Array Bag data structures, as well as with generics. Through "IntelliJ", I'm receiving errors with the line Set<ProfileInterface> follows = followBag[index].toArray();. Let me explain the reason for this line. What I'm trying to do is take "my" profile (in this example), and see who I'm following. For each followed profile (or followBag[index]) I wish to see if followBag[index][index] == followBag[index] and continue to parse the array to see if it matches. But, due to my confusion with generics and array bag data structures, I'm having major difficulties figuring this out.
I'd like to do the following:
//for all of my followers
//look at a particular followed profile
//look at all of that profile's followers
//if they match one of my followers, do nothing
//else
//if they don't match, recommend that profile
//return that profile or null
My problem is that I do not know how to appropriately create an object of a Profile type that will allow me to return this object
(in my method above, the line Set<ProfileInterface> follows = followBag[index].toArray();)
I'm trying to make an index of my Profile set to an object that can later be compared where my difficulties are. I'd really appreciate any insight into how this should be done.
Much appreciated for all help and Cheers!
When you do:
Set<ProfileInterface> follows = followBag[index].toArray();
you're trying to use Set as Array. But you can't.
Java will not allow, because Set and Array are different classes, and Set does not support [] syntax.
That is why you get error. For usefollowBag as Array you have to convert it:
ProfileInterface[] profileArray = followBag.toArray(new ProfileInterface[followBag.size()]);
for(int i=0; i<profileArray.length; i++){
ProfileInterface profile = profileArray[i];
//do what you would like to do with array item
}
I believe, in your case, you don't need assign Set object to generic Array at all. Because you can enumerate Set as is.
public class Profile {
private Set<ProfileInterface> followBag = new HashSet<Profile>();
...
public Set<ProfileInterface> recommended(){
Set<ProfileInterface> recommendSet = new HashSet<ProfileInterface>();
for(Profile follower : followBag){
for(Profile subfollower : follower.followBag){
if(!this.followBag.contains(subfollower)){
recommendSet.add(subfollower);
}
}
}
return recommendSet;
}
}
I also added possibility of returning list of recommended profiles, because there is may be several.
I have a question regarding a situation I am experiencing. I wrote a really basic program to help show you an example of what my issue is. I wondering how (if even possible) to do something a certain way. It involves a variable from one class, a method from another class. And using them together to get a result in the Main.
Main:
// The main, which creates an object of Testing and Yupp, then Tries to run the method to add +3 and display it, repeatidly.
import javax.swing.JOptionPane;
public class Runit
{
public static void main(String[] args)
{
Testing testing = new Testing();
Yupp yupp = new Yupp();
JOptionPane.showMessageDialog(null, testing.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, testing.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, testing.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, testing.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, testing.number);
}
}
Yupp Class:
//Just extending all the information from Testing class( which holds the "number" variable so I have access to it ) Then making the simple personal method to add 3 to it.
public class Yupp extends Testing
{
public void doMath()
{
number = number + 3;
}
}
Testing Class:
// Just holding the number variable in this class.
public class Testing
{
int number = 3;
}
So essentially what I want to happen, regardless of if its proper coding, which I'm sure it isn't. What should(I want to) happen is the "number" variable, should just increase by 3 on each separate JOptionPane window. Like I said, its just a basic code example I wrote to explain my problem. I think it makes a lot of sense this way. Thank you if you can help me figure out what to do to make this possible.
Currently the number always comes back as 3. Instead of 3 + 3, 6 + 3, 9 + 3, etc.
problem:
testing.number
You are getting the same number from that instance of Testing which is not incremented thus giving you 3 all the time
solution:
use your Yupp object to get the incremented value from the method call doMath
sample:
JOptionPane.showMessageDialog(null, yupp.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, yupp.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, yupp.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, yupp.number);
yupp.doMath();
JOptionPane.showMessageDialog(null, yupp.number);
In short:
You are creating two different objects:
Testing testing = new Testing();
Yupp yupp = new Yupp();
then, you are calling the operation (doMath) in one (yupp), but printing the attribute number of the other (testing). The last one, doesn't change in the whole program.
I've been looking all over, and i cant find anyone who can solve this problem. I'm making a game, and in that game, i have editable controls. the controls window is a seperate JFrame, and when i click the confirm button, it is supposed to write the items in the JTextFields (holding the controls) to a file. but that wasnt working, so instead i have it print the arraylist that holds the values. here is the code:
public void writeControls() {
ArrayList<String> al = new ArrayList<String>();
al.add(up.getText());
al.add(down.getText());
al.add(left.getText());
al.add(right.getText());
al.add(jump.getText());
al.add(duck.getText());
al.add(attack.getText());
for (int i = 0; i < al.size(); i++) {
System.out.println(al.get(i));
}
System.exit(0);
}
the problem is this: if i change the final JTextField attack or any other one for that matter, and click submit, the system prints out the default controls. for example, if the JTextFields have the values w,a,s,d,r,t,q and i change the value q to i, it prints out q. what am i doing wrong? thanks in advance!
EDIT 1:
code for the textfields, and the FILES.... is simply a string stored in a different class. the class setText() is below the textfields.
up = new JTextField(setText(FILES.controlsFileFinalDir, 1));
down = new JTextField(setText(FILES.controlsFileFinalDir, 2));
left = new JTextField(setText(FILES.controlsFileFinalDir, 3));
right = new JTextField(setText(FILES.controlsFileFinalDir, 4));
jump = new JTextField(setText(FILES.controlsFileFinalDir, 5));
duck = new JTextField(setText(FILES.controlsFileFinalDir, 6));
attack = new JTextField(setText(FILES.controlsFileFinalDir, 7));
public String setText(String fileDir, int lineNum) {
String txt = "";
txt = io.readSpecificLine(fileDir, lineNum);
txt = switchCase(txt);
return txt;
}
switchcase() is only taking what you have written in the text file that these are getting the values from, and translating them. so if the value is 0, it is turned into Space, etc. io.readSpecificLine(); is only to get the line of text from the file. does this help?
EDIT 2:
i just was dinking around and found out that if i set the JTextField text by using setText(""); then use getText(); it works. so the problem is that when i change it manually, and use getText(); it wont work. Why?
To update the text to a currently existing JTextField, I would establish the JTextField as a class variable, and create a setter/getter method to adjust it (which I'm assuming you're doing).
According to your methods, you would use something like:
up.setText(setText(FILES.controlsFileFinalDir, 7));
Edit: **The first setText is the JTextField.setText, the second setText is your public method you posted. I'm assuming your second getText() isn't working because you're probably not setting the text correctly.
Without seeing more code, I can't really give a better guess.
The main possibilities:
(1) The text fields have their editable property set to false.
(2) You are creating multiple copies of the JTextFields, then editing a new one on the screen, but referring to the old one when you get the value.
(3) You have a ValueChanged or LostFocus event handler that is resetting the text fields to their defaults
(4) It is actually JFormattedTextField not a JTextField
If I was you, I would try to debug the programm. You will probably do some Mistake in your code, you won't be able to see, by just checking the code.
For example in which order do you call the functions and so on, maybe you have a fault here, or maybe you have several threads, so you try to read the Textfields without even set them and so on ... It's hard to say without reviewing the whole Code.
So if you use eclipse you can follow this link for an explanation on how to debug: http://www.vogella.com/articles/EclipseDebugging/article.html
Netbeans or any other IDE should support debugging as well.
This may seem like a strange thing to suggest, but I think this is an issue with pointers. If you create a new string before passing it in, JTextField will be able to change it internally and return what you expect when asked for the modified value.
down = new JTextField("" + setText(FILES.controlsFileFinalDir, 2));
// or
down = new JTextField(new String(setText(FILES.controlsFileFinalDir, 2)));
You might want to try the following:
create a class Test.java
import java.util.ArrayList;
import javax.swing.JTextField;
public class Test implements Runnable {
private ArrayList<JTextField> textFields = null;
private ArrayList<String> stringList = null;
public Test(ArrayList<JTextField> textFields, ArrayList<String> stringList) {
this.textFields = textFields;
this.stringList = stringList;
}
#Override
public void run() {
for ( JTextField textField : this.textFields )
this.stringList.add( textField.getText() );
}
}
and then, at the place where you use the "getText() method .. "
do the following...
ArrayList<JTextField> textFields = new ArrayList<JTextField>();
// add all the JTextField to textFields
ArrayList<String> stringList = new ArrayList<String>();
Test test = new Test( textFields, stringList );
SwingUtilities.invokeLater( test );
// check if the stringList is populated.
If this work, then what I believe is that, for some reason, the JTextField hasn't finished
"setting" the text, and before it finishes your getText() was called. I've had similar problems before, and this solved my problem that time, but still, this might not be the perfect solution.
First, you should change your "setText()" method name to something like "getTextFromFile()" it would be more readable
Then, if you are setting and reading the new text in different threads, my bet is that the setText() is taking long to return, because it is accessing the file system, while the method that read the values run instantly
I would try to do run a little test:
public void test(){ // must be run after the JTextFields be initialized
up.setText("TEST")
System.out.println(up.getText());
up.setText(setText(FILES.controlsFileFinalDir, 1));
System.out.println(up.getText());
}
If the test() prints the correct values, then we can assume that if you set and read the new value in the same thread it works fine
The other test I would do is:
public void testThread(){
new Thread(){
public void run(){
while(true){
if(up!=null){
System.out.println(up.getText());
}
try{
Thread.sleep(1000);
}catch(Exception e){
e.printStackTrace();
}
}
}
}.start();
}
It will print the value of up each 1 second, so that you can see if after some time you get the new value. If it does, then the answer is: Your setText() is taking long to run and you are reading the value before the new value is set
SOLUTION
none of the above answers were working for me, so i finally decided to just start over with that class. the few things i changed were the way i made the JTextFields. I made them as an array instead of individual objects. Second is the way i put what they say. When i initialized them, i was unable to get them to create WITH the text in the parameters. so i had to do that seperately. i changed some of the method names so as to reduce future confusion, and it worked! so im not sure what was up with that, maybe it was the way i did it, maybe just a fluke. it happens sometimes, so im sorry for the delay and waste of your time! thanks for all the answers anyway!
Try this:
textbox.setText(setFile(args)); // your function for set file
I was going over the tutorials for GWT and was confused by this piece of code.
The code is at GWT tutorials
private void addStock() {
final String symbol = newSymbolTextBox.getText().toUpperCase().trim();
newSymbolTextBox.setFocus(true);
// Stock code must be between 1 and 10 chars that are numbers, letters,
// or dots.
if (!symbol.matches("^[0-9A-Z\\.]{1,10}$")) {
Window.alert("'" + symbol + "' is not a valid symbol.");
newSymbolTextBox.selectAll();
return;
}
newSymbolTextBox.setText("");
// Don't add the stock if it's already in the table.
if (stocks.contains(symbol))
return;
// Add the stock to the table.
int row = stocksFlexTable.getRowCount();
stocks.add(symbol);
stocksFlexTable.setText(row, 0, symbol);
stocksFlexTable.setWidget(row, 2, new Label());
stocksFlexTable.getCellFormatter().addStyleName(row, 1,
"watchListNumericColumn");
stocksFlexTable.getCellFormatter().addStyleName(row, 2,
"watchListNumericColumn");
stocksFlexTable.getCellFormatter().addStyleName(row, 3,
"watchListRemoveColumn");
// Add a button to remove this stock from the table.
Button removeStockButton = new Button("x");
removeStockButton.addStyleDependentName("remove");
removeStockButton.addClickHandler(new ClickHandler() {
public void onClick(ClickEvent event) {
int removedIndex = stocks.indexOf(symbol);
stocks.remove(removedIndex);
stocksFlexTable.removeRow(removedIndex + 1);
}
});
stocksFlexTable.setWidget(row, 3, removeStockButton);
// Get the stock price.
refreshWatchList();
}
The problem part is the anonymous inner class to add event handling to the removeStockButton. The class' onClick method accepts an event and then retrieves the index of row-to-be-deleted from the ArrayList stocks using the variable symbol.
How will symbol still be in scope when the user actually calls onClick(), i.e. clicks the remove button? If you doubt the correctness of the code, it's from Google engineers and so is correct (plus, it works, I've used it).
Is this some JavaScript trick or do I need Java referesher courses?
This is because and only because symbol was declared as final in the enclosing method.
Here's a link to a brief explanation of anonymous classes in Java : see here.
The language basically takes care of this in the background with a feature called a Closure. The closure binds "symbol" to the class. In order for this to work in Java, the variable must be final (which it is here).
Note the keyword "final" in the declaration of symbol.
(No & Yes, respectively to your final questions.)
Yes, you need to get a refresher on your Java skills. This type of programming is very common in Java. As said by the others: since symbol is final, you can access it from inner classes.