Customer ArrayList Class amending Specific Element in Java - java

How do i change a specific variable at a specific point in a custom ArrayList? I have created an ArrayList class and need to adjust a certain variable within the list, but i cannot seem to figure how i would achieve it. I have searched for the answer as well but nothing seems specific to my problem.
The code for my Super Class is:
public class Parcel extends JPanel
{
protected int idNum;
protected double charge;
protected char zone;
protected ImageIcon i;
protected static ArrayList<Parcel> parcelList;
protected static ParcelList newParcel = new ParcelList();
public Parcel(int id, char z)
{
this.idNum = id;
this.zone = z;
}
And the code for my list is...
public class ParcelList extends Parcel
{
ParcelList()
{
parcelList = new ArrayList<Parcel>();
}
public void addBox(int id, char z, int w, int l, int h)
{
parcelList.add(new Box(id,z,w,l,h));
}
What i am looking to do is change the ImageIcon for example, change the ImageIcon of the 5th element in the List of list that contains many different instances of Box with differing images. And also Removing an element.
Is it possible to do this with the current way i have set my code up?

Never minding what seems to be some redundancy in the code, one way to do this is to use newParcel.get(index), modify the Box that you get from it using setter methods, then newParcel.set(index, newBox)

Related

Java: link object to a variable in another object

This is a bit difficult to explain so I wrote up and example to illustrate the concept. In the following example I have a stock class which models the figures that affect a stock simulation program. I also have a MarketModifier class which represents events which would affect the stocks in different ways.
public class ExampleArea
{
public static void main(String cvhfg[])
{
Stock test = new Stock(1f,1f,1f,1f);
MarketModifier worldEvent =
new MarketModifier("Bad publicity",-2.5f,"publicOpinion");
}
}
class MarketModifier
{
public MarketModifier(String name, float modifier, String variable) {
super();
this.name = name;
Modifier = modifier;
this.variable = variable;
}
String name;
float Modifier;
String variable;
}
class Stock
{
public Stock(float value, float integrity, float publicPresence, float publicOpinion) {
super();
this.value = value;
this.integrity = integrity;
this.publicPresence = publicPresence;
this.publicOpinion = publicOpinion;
}
float value;
float integrity;
float publicPresence;
float publicOpinion;
//...other variables...
}
My question is how would I link the marketModifer to the variable in the Stock model (in the example above it is "publicOpinion" set in the "variable" String) without using a string. Strings have the problem of possibly mistyping them, and I would need a switch to identify which variable the modifier was affecting.
I thought of using an enum but I would still need a switch table to check them and I would also have to update the enum values every time a stock has a different variable which could be affected (there could be additional variables in the subclasses of Stock). The other option I thought of was reflection but this solution, though I think it would work, seems overly complicated, and adds more difficulty in reading than it solves.
So again, is there a better way to link the an object to the variable(s) that it affects in another object (maybe some kind of observer/watcher pattern?).
Since you want to avoid reflective approaches, what I can suggest is to use an event listener approach.
So what you basically want to do is to listen for the event when market action is performed and then modify the values in your Stock object.
So you would need an interface like this that your MarketModifier would invoke when it is processed.
Modifier.java
public interface Modifier {
public void modify(Stock taget, float modifier);
}
And this interface's implementations would be able to modify any value(s) in the stock object.
An implementation would look like this:
PublicOpinionModifier.java
public class PublicOpinionModifier implements Modifier {
public void modify(Stock target, float modifier) {
target.setPublicOpinion(target.getPublicOpinion() + modifier);
}
}
After that, you can create your MarketManager class like this:
MarketManager.java
public class MarketManager {
// The name of the event.
private String name = "unkown";
// Modifier value of the event.
private float modifier = 0f;
// The listener to listen for the modifications.
private Modifier modificationListener;
// The target stock object towards which the action is directed.
private Stock target;
/**
* Executes the market event.
*/
public void executeAction() {
modificationListener.modify(target, modifier);
}
}
The MarketManager would have the target object (the Stock object to update) and an implementation of Modifer which would be acting as a listener which would be invoked when the market stuff is going on...
TestMarket.java
public class TestMarket {
public static void main(String[] args) {
Stock stock = new Stock(1f, 3f, 1f, 3f);
MarketManager manager = new MarketManager();
manager.setTarget(stock);
manager.setName("Bad Publicity");
manager.setModifier(-2f);
manager.setModificationListener(new PublicOpinionModifier());
manager.executeAction();
}
}
Neat!
I have uploaded a more clean and elaborated version in my public repo.

Other ways to add a parameter to initComponents [java-netbeans]

I have a huge problem with my GUI java project in netbeans.
It is well-known that the code compiled by netbeans is read-only and I need an other way to add a parameter to the initComponents method, besides calling a myInitComponents method, identical to initComponents, and calling it in the constructor.
Now I have this:
public class MainFrame {
public MainFrame() {
DefaultStyledDocument doc = new DefaultStyledDocument();
myInitComponents(doc);
}
myInitComponents (DefaultStyledDocument doc) {
//components
textModel = new javax.swing.JTextPane(doc);
//components
}
initComponents () {
//components
}
In this way it works, but every time I change something within the frame, I have to copy and pase all the new code of initComponents inside myInitComponent.
Moreover, this is a very awful way to do that.
Is there any other way to add that parameter?
Any help is appreciated!
You can add a parameter to the MainFrame constructor, place it in a field, use custom creation code in the properties table of the GUI builder.
There a couple of free code places to insert in the code of initComponents. Create custom code is such a place;
private final DefaultStyledDocument doc = new DefaultStyledDocument();
And in "custom creation code:"
new JTextPane(doc)
Which can also be used for custom panels etcetera.
I have a huge problem with my GUI java project in netbeans. It is well-known that the code compiled by netbeans is read-only and I need an other way to add a parameter to the initComponents method, besides calling a myInitComponents method, identical to initComponents, and calling it in the constructor
I think you are probably confused between using constructors for initializations and setters for accessing values.
This is as good as asking: if you have a class with attributes like a, b & c, how to create a setter which set all attributes. This is something you should avoid. You could just create an individual setter and getter for each property instead of trying to use an init to set all attributes.
You should be doing this:
class MyClass
{
private int a;
private int b;
private int c;
public MyClass(){
init();
}
private void init(){
a = 100;
b = 200;
c = 300;
}
public int getA(){return a;}
public int getB(){return b;}
public int getC(){return c;}
public void setA(int a){this.a = a;}
public void setB(int b){this.a = b;}
public void setC(int c){this.a = c;}
}
instead of this:
class MyClass
{
private int a;
private int b;
private int c;
public MyClass(){
init();
}
private void init(){
a = 100;
b = 200;
c = 300;
}
public void myInit(int a, int b, int c){
this.a = a;
this.b = b;
this.c = c;
}
}
this is a very awful way to do that. Is there any other way to add that parameter?
So you asked, if you have one more attribute, say int d. How should I add it to the parameter list of myInit(). So you already start to see the problem with this approach for your class design.
If possible, we try to achieve low coupling and high cohesion in our design. When you dump various unrelated attributes within a single method, you are steering towards low cohesion (a method which is not performing a very specific task).
If you try to use a single method like myInit() and use it as a setter to set multiple fields, it can cause a number of problems.
What if the user only wants to set a specific attribute, and not the rest?
So to answer your question, use individual setters for each attribute, unless the attributes are closely related for example:
setLocation(int x, int y);
setBounds(int x, int y, int width, int height);
At last I fixed this in a very simple way. I inserted all the code needed for the DefaultStyleDocument in the initComponents() method by clicking on customize code and adding it as pre-creation code.
public class MainFrame {
public MainFrame() {
myInitComponents();
}
//delete the myInitComponents() method
initComponents () {
//code useful for the DefaultStyledDocument..
DefaultStyledDocument doc = new DefaultStyledDocument();
//components
textModel = new javax.swing.JTextPane(doc);
}
Hope this could be useful to somebody.

Adding an item to an indexed property - PropertyChangeSupport

I am currently working with PropertyChangeListeners and I want to know if it would be advisable to fire a property change whenever an object is added (or removed, for that matter) to an indexed property such as an ArrayList.
public class SimpleBean implements Serializable
{
private ArrayList<Matrix> mats;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public SimpleBean()
{...}
public void addMat(Matrix m)
{
pcs.firePropertyChange("mats", null, m); // I'm having trouble with the parameters
mats.add(m);
}
}
I was reading the PropertyChangeListener tutorials and it seemed like it was appropriate to fire a property change whenever the value of a bound property changed. Well, I wasn't quite sure if this meant that I should fire a property change whenever a property was modified by any means or only when the property (or an element of that property) was strictly set/reassigned to a different value.
In my program, it would be very convenient if several classes could change every time an element is removed from or added to the mats ArrayList, and I figured that a PropertyChangeListener could help me in that regard.
Please let me know if this method is not recommended and if there is another way that other classes can listen and respond to deletion/addition to indexed properties.
See the following example:
public class SimpleBean implements Serializable {
private ArrayList<Matrix> mats;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
public void setMats(ArrayList<Matrix> mats) {
if(mats.equals(this.mats))
return;
ArrayList<Matrix> oldMats = this.mats ;
this.mats = mats ;
pcs.firePropertyChange("mats", oldMats, mats);
}
public ArrayList<Matrix> getMats() {
return mats;
}
public void setMat(int index, Matrix mat) {
Matrix existing = index == mats.size() ? null : mats.get(index);
if(existing.equals(mat))
return;
mats.remove(index);
mats.add(index, mat);
pcs.fireIndexedPropertyChange("mats", index, existing, mat);
}
public Matrix getMat(int index) {
return mats.get(index);
}
public void addMat(Matrix m) {
setMat(mats.size(), m);
}
}
Which implements both propertyChange as well as indexedPropertyChange for mats.

Access methods on different types

I have something like this:
Figures fig = new Line();
on which Line extends Figure. Figure is an abstract class that only has a method getType() that tells me which figure it is by returning a String;
I have 3 types, Rectangle, Circle and Figure. All of them extend Figures.
Now the real question. I store every single one inside of a List<Figures> and I want to get access to some methods on each object like getStartX(); and getStartY(); and I can't, I only can access the methods that are on Figures also.
Your abstract class should define the getStartX and getStartY method. Either abstract if you want Rectangle, Circle and Figure to have a different behaviour and force them to Override those methods. Else just put the method in Figures it'll be available for use (with the appropriate keyword : public/protected depending your needs).
If you want to use methods that are specific to a class you'll need to check of which instance it is. Something like
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof Circle) {
System.out.println("Oh no a Circle!");
int radius = ((Circle)figure).getRadius();
...
}
}
For your Rectangle/Line you can define an interface with your 2 methods:
public interface HasEndpoints {
int getEndX();
int getEndY();
}
public class Rectangle implements HasEndpoints {
...
public int getEndX() {return endx;}
...
}
for (Figures figure: myList) {
int x = figure.getStartX(); // Method common and declared in Figures
if (figure instanceof HasEndpoints) { // Rectangle and Line will go there
System.out.println("HasEndpoints implementor");
int endX = ((HasEndpoints)figure).getEndX();
...
}
}
You can use instanceof with if...else and cast dynamically your object
Figure fig = new //Circle()/Triangle()/Rectangle();
if( fig instanceof Circle) {
((Circle) fig).getRadius(); //This method is only available in Circle class
}
You can always cast the Figure to Line, but not the best choice. Depending on the problem, you can apply Visitor Pattern or add those methods to Figure, even when the Circle doesn't have a starting and ending point.
For example
public abstract class Figure{
public abstract void visit(FigureVisitor visitor);
}
public class Line extends Figure{
public void visit(FigureVisitor visitor){
visitor.visitLine(this);
}
}
public interface FigureVisitor{
public void visitLine(Line figure);
public void visitCircle(Circle figure);
}
public class StartingPointsVisitor implements FigureVisitor{
private Double startX;
private Double startY;
private Double endX;
private Double endY;
public void visitLine(Line figure){
this.startX = figure.getStartX(); //No cast needed
...
}
public void visitCircle(Circle figure){
//Stub-method
}
//Getters to read the results
}
Is a more complex solution, but as i said, it depends on the problem, and most of the complex remains in the Visitor
Either getStartX() and getStartY() should be declared in Figure class or you need to cast the object to Line class:
Figure figure = figures.get(0);
if ("line".equals(figure.getType())) {
Line line = (Line)figure;
}
Another option is to use reflection. But you still need to be sure, that the requested method can be called.

adding multiple inherited objects to a container class

I have a program that is well under way, but I can't seem to wrap my ahead around how to add certain classes to a container.
I'm creating a java program for just a 2D person. I have an abstract class, BodyPart (which all body parts share in common), DrawablePart and ContainerPart class implements the abstract class, where Drawable parts include implemented classes such as head, legs, feet, etc; And ContainerParts include implemented classes such as person > upperbody & lowerbody.
The only part I have left to do is create the upperbody and lowerbody classes derived from the container class, which has an array of BodyParts.
Let's say I'm working on LowerBody container, derived from ContainerPart. How is it possible to have a LowerBody constructor that can contain arrays of Legs and Feet (which are derived from DrawablePart)? I would like to have LowerBody and UpperBody derive from Avatar container, which derives from ContainerPart.
I know it's hard getting an answer without showing my code, but I think someone can explain it to me with this UML diagram I created below from my classes.
Here is the UML diagram:
Here is a ContainerPart constructor with an array of BodyParts (super is from BodyPart), which is what I want, but I need certain parts like Leg and Feet in the constructor of LowerBody:
public ContainerPart(String name, String color, int xCoord, int yCoord, BodyPart[] yourParts) {
super(name, color, xCoord, yCoord);
parts = yourParts;
}
In my container class I have an instance field for an array of BodyParts, as seen in the constructor above. But when I try to use more than one derived BodyPart, I get this:
But, if I just have one, say "yourFoot" in super(), it'll work.
I couldn't add this as a comment hence putting here.
If I understand correctly, you have something like below (your real constructor has more arguments):
public abstract class BodyPart {
private String name;
private String color;
......
......
}
public class DrawablePart extends BodyPart {
public DrawablePart(){
super();
}
}
public class ContainerPart extends BodyPart {
public ContainerPart(String name, String color, int xCoord, int yCoord, BodyPart[] yourParts){
super(......);
...........
}
}
public class Legs extends DrawablePart {
public Legs(){
super();
}
}
Now you want to create LowerBody as:
public class LowerBody extends ContainerPart {
public LowerBody(Legs[] legs, Feet[] feet, String name, String color, int xCoord, int yCoord){
super(name, color,xCoord, yCoord, legs);
........
.......
}
public LowerBody(Legs leg, Feet feet, String name, String color, int xCoord, int yCoord){
super(name, color,xCoord, yCoord, new BodyPart[]{leg, feet});
}
}
If yes, what is the problem? It should work fine. If I am missing anything, please let me know.
Maybe a silly question. Why not just have LowerBody extend Avatar? You'd still get the benefits of ContainerPart.
Or you can add a new constructor:
public LowerBody(List<DrawableParts> parts) {
}

Categories

Resources