I have a Combo Bx (Dropdown box) with an index range of 0-20. If there anyways I can use that index to specify which object I want data from? All of the objects use the same naming convention obj0, obj1, obj2, etc. Basically something like this...
public abstract class Person {
private String name;
private String title;
private String email;
private String job;
public Person(String name, String title, String email, String job){
this.name = name;
this.title = title;
this.email = email;
this.job = job;
}
//Getters and Setters
}
public class main extends javax.swing.JFrame {
...misc code...
private void btn_startActionPerformed(java.awt.event.ActionEvent evt) {
Person obj0 = new Person("Jon Doe",
"Program Coordinator",
"jon.doe#test.com",
"Faculty");
Person obj1 = ...
...
Person obj20 = ...
/*
Onclick it uses the index of the current index in the combobox (dropdown)
to specify which object to get the data from.
*/
private void btn_GetActionPerformed(java.awt.event.ActionEvent evt) {
//Uses the obj naming convention plus the index
string foo = "obj" + toString(combobox_Name.getSelectedIndex());
//Fills the textbox using the above string and the getName method
txtbox_username.setText(ToObject(foo).getName);
}
I have created a basic design of what I think you want:
This code creates 20 objects, adds them to a combobox and uses their predefined name when selected to change a textfield.
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.BoxLayout;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTextField;
class ObjExample {
String name;
public ObjExample(String name) {
this.name = name;
}
#Override
public String toString() {
return name;
}
}
public class Main extends JFrame implements ActionListener {
JComboBox jcb = new JComboBox();
JTextField jtf = new JTextField("Text Field");
public Main() {
setSize(200, 200);
setDefaultCloseOperation(EXIT_ON_CLOSE);
for (int i = 0; i <= 20; i++) {
jcb.addItem(new ObjExample(Integer.toString(i)));
}
jcb.addActionListener(this);
add(jcb);
add(jtf);
setVisible(true);
}
public static void main(String[] args) {
new Main();
}
#Override
public void actionPerformed(ActionEvent e) {
if (e.getSource() == jcb) {
ObjExample obj = (ObjExample) jcb.getSelectedItem();
jtf.setText(obj.toString());
}
}
}
Related
long story short, I have one settlementItemeBase class as my father and two children. I want to make the father class parcelable so as extension happens, my two child classes be parcelable as well. I don't exactly know what I'm doing right or wrong. I searched little bit but nothing helped me.
here are my classes:
SettlementItemBase:
public class SettlementItemBase implements Parcelable{
public SettlementItemBase(){}
protected SettlementItemBase(Parcel in) {
}
public static final Creator<SettlementItemBase> CREATOR = new Creator<SettlementItemBase>() {
#Override
public SettlementItemBase createFromParcel(Parcel in) {
return new SettlementItemBase(in);
}
#Override
public SettlementItemBase[] newArray(int size) {
return new SettlementItemBase[size];
}
};
#Override
public int describeContents() {
return 0;
}
#Override
public void writeToParcel(Parcel dest, int flags) {
}
}
first child class:
public class FirstClass extends SettlementItemBase {
private int id;
private int cardId;
private String cardNumber;
private String expDate;
private String currency;
private String url;
public FirstClass(){
id = 0;
cardId = 0;
cardNumber = "";
expDate = "";
currency = "";
url = "";
}
protected FirstClass(Parcel in) {
super(in);
id = in.readInt();
cardId = in.readInt();
cardNumber = in.readString();
expDate = in.readString();
currency = in.readString();
url = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeInt(cardId);
dest.writeString(cardNumber);
dest.writeString(expDate);
dest.writeString(currency);
dest.writeString(url);
}
public int getId() {
return id;
}
public int getCardId() {
return cardId;
}
public String getCardNumber() {
return cardNumber;
}
public String getExpDate() {
return expDate;
}
public String getCurrency() {
return currency;
}
public String getUrl() {
return url;
}
}
second child class:
public class SecondClass extends SettlementItemBase{
private int id;
private String currency;
private String accountNumber;
private String ibanNumber;
public SecondClass(int id, String currency,
String accountNumber, String ibanNumber){
this.id = id;
this.currency = currency;
this.accountNumber = accountNumber;
this.ibanNumber = ibanNumber;
}
protected SecondClass(Parcel in){
super(in);
id = in.readInt();
currency = in.readString();
accountNumber = in.readString();
ibanNumber = in.readString();
}
#Override
public void writeToParcel(Parcel dest, int flags) {
dest.writeInt(id);
dest.writeString(currency);
dest.writeString(accountNumber);
dest.writeString(ibanNumber);
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getCurrency() {
return currency;
}
public String getAccountNumber() {
return accountNumber;
}
public String getIbanNumber() {
return ibanNumber;
}
}
I'm passing and getting an ArrayList of both child class' items with intent putParcelableArrayListExtra and getParcelableArrayListExtra methods and get the following error:
Parcel android.os.Parcel#2d0fde33: Unmarshalling unknown type code 3276849 at offset 172
any help would be appreciated 3>
well I'm posting this for those who may run into the same problem as me.
the problem was solved after adding the Creator statement to the child classes.
for one of the child classes it would be like:
public static final Creator<FirstClass> CREATOR = new Creator<FirstClass>() {
#Override
public FirstClass createFromParcel(Parcel in) {
return new FirstClass(in);
}
#Override
public FirstClass[] newArray(int size) {
return new FirstClass[size];
}
};
hope this helps. 3>
It took me way too long to set up a listener on one property of the objects in my Observablelist and add a listener to it.
ObservableList<Track> observableResult = FXCollections.observableArrayList((Track tr)-> new Observable[]{tr.selectedProperty()});
observableResult.addListener(new ListChangeListener<Track>() {
#Override
public void onChanged(Change<? extends Track> c) {
c.next();
for(Track k : c.getAddedSubList()){
System.out.println(k.getTrackName());
}
}
});
But I can't seem to be able to locate the actual object the change has been made to. The Change class only appears to support added and removed members, which don't get triggered by the actual changes inside them.
I have a workaround for this, just calling another method that would loop trough the entire ObservableArrayList and get for example, only the selected items, but that gets pretty expensive after I have a couple of thousand objects. Finding the source members that got changed would allow me to just push them to another array and save a bunch of overhead.
You can call getFrom() on the change to get the index of the changed item. I don't think there's a way to actually figure out which property changed (if you have more than one property listed in the extractor) or get the old value, but maybe this is enough.
If you need more, you could consider registering your own listeners with the list to track, which would be tricky but not impossible.
Here's an SSCCE demonstrating the getFrom() call:
import java.util.Random;
import java.util.stream.IntStream;
import javafx.beans.Observable;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
public class ListChangeListenerTest {
public static void main(String[] args) {
ObservableList<Item> itemList = FXCollections.observableArrayList(item -> new Observable[]{item.valueProperty()});
itemList.addListener((Change<? extends Item> c) -> {
while (c.next()) {
if (c.wasUpdated()) {
int index = c.getFrom();
System.out.println("Updated item at "+index+" new value is "+itemList.get(index).getValue());
}
}
});
IntStream.rangeClosed(1, 1000).mapToObj(Item::new).forEach(itemList::add);
Random rng = new Random();
itemList.get(rng.nextInt(itemList.size())).setValue(rng.nextInt(10000));
}
public static class Item {
private final IntegerProperty value = new SimpleIntegerProperty();
public Item(int value) {
setValue(value);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
}
}
Here's a version that manages the listeners on the property manually. Note that
This doesn't use an extractor on the list
The property in the Item bean is constructed passing a reference to the bean that owns the property. This allows the listener on the property to get a reference to the Item (via a bit of ugly downcasting)
This gives a bit more flexibility; e.g. if you wanted to check modifications on multiple properties and perform different actions, this would allow this. As you can see, the listener can also access the old value.
import java.util.Random;
import java.util.stream.IntStream;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.Property;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.beans.value.ChangeListener;
import javafx.collections.FXCollections;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ObservableList;
public class ListChangeListenerTest {
public static void main(String[] args) {
ChangeListener<Number> valueListener = (obs, oldValue, newValue) -> {
Item item = (Item) ((Property<?>) obs).getBean();
System.out.println("Value for "+item+" changed from " + oldValue + " to "+newValue);
};
ObservableList<Item> itemList = FXCollections.observableArrayList();
itemList.addListener((Change<? extends Item> change) -> {
while (change.next()) {
if (change.wasAdded()) {
for (Item item : change.getAddedSubList()) {
item.valueProperty().addListener(valueListener);
}
}
if (change.wasRemoved()) {
for (Item item : change.getRemoved()) {
item.valueProperty().removeListener(valueListener);
}
}
}
});
IntStream.rangeClosed(1, 1000).mapToObj(Item::new).forEach(itemList::add);
Random rng = new Random();
itemList.get(rng.nextInt(itemList.size())).setValue(rng.nextInt(10000));
}
public static class Item {
private final IntegerProperty value = new SimpleIntegerProperty(this, "value");
private final String id ;
public Item(int value) {
id = "Item "+value ;
setValue(value);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
#Override
public String toString() {
return id ;
}
}
}
Finally, if you want to account for "bulk" updates, you need to implement ObservableList yourself. You can do this by subclassing ModifiableObservableListBase, and the basic idea is pretty straightforward. The implementation is made a bit tedious by having to create the Change object representing the update, but it's not too bad. Here's an example that allows updating a contiguous range:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.function.Consumer;
import javafx.collections.ListChangeListener.Change;
import javafx.collections.ModifiableObservableListBase;
public class UpdatingObservableList<T> extends ModifiableObservableListBase<T> {
private final List<T> list ;
public UpdatingObservableList(List<T> list) {
this.list = list ;
}
public UpdatingObservableList() {
this(new ArrayList<>());
}
public void updateSublist(int start, int end, Consumer<T> updater) {
if (start < 0) throw new ArrayIndexOutOfBoundsException("Start ("+start+") cannot be < 0");
if (end < start) throw new IllegalArgumentException("End ("+end+") cannot be less than start ("+start+")");
if (end > size()) throw new ArrayIndexOutOfBoundsException("End ("+end+") cannot be greater than list size ("+size()+")");
for (T element : list.subList(start, end)) {
updater.accept(element);
}
fireChange(createUpdate(start, end));
}
#Override
public T get(int index) {
return list.get(index);
}
#Override
public int size() {
return list.size();
}
#Override
protected void doAdd(int index, T element) {
list.add(index, element);
}
#Override
protected T doSet(int index, T element) {
return list.set(index, element);
}
#Override
protected T doRemove(int index) {
return list.remove(index);
}
private Change<T> createUpdate(int start, int end) {
return new Change<T>(this) {
private boolean initialState = true ;
#Override
public boolean next() {
if (initialState) {
initialState = false ;
return true ;
}
return false ;
}
#Override
public void reset() {
initialState = true ;
}
#Override
public int getFrom() {
checkState();
return start ;
}
#Override
public int getTo() {
checkState();
return end ;
}
#Override
public List<T> getAddedSubList() {
checkState();
return Collections.emptyList();
}
#Override
public List<T> getRemoved() {
checkState();
return Collections.emptyList();
}
#Override
protected int[] getPermutation() {
checkState();
return new int[0];
}
#Override
public boolean wasAdded() {
checkState();
return false ;
}
#Override
public boolean wasRemoved() {
checkState();
return false ;
}
#Override
public boolean wasUpdated() {
return true ;
}
#Override
public boolean wasPermutated() {
checkState();
return false ;
}
#Override
public int getRemovedSize() {
checkState();
return 0 ;
}
#Override
public int getAddedSize() {
checkState();
return 0 ;
}
private void checkState() {
if (initialState) {
throw new IllegalStateException("Must call Change.next()");
}
}
};
}
}
and here's a version of the test class that uses this. Note that the update is performed via the list:
import java.util.Random;
import java.util.stream.IntStream;
import javafx.beans.property.IntegerProperty;
import javafx.beans.property.SimpleIntegerProperty;
import javafx.collections.ListChangeListener.Change;
public class ListChangeListenerTest {
public static void main(String[] args) {
UpdatingObservableList<Item> itemList = new UpdatingObservableList<Item>();
itemList.addListener((Change<? extends Item> change) -> {
while (change.next()) {
if (change.wasUpdated()) {
for (int i = change.getFrom() ; i < change.getTo() ; i++) {
System.out.println(itemList.get(i) + " updated - new value: "+itemList.get(i).getValue());
}
}
}
});
IntStream.rangeClosed(1, 1000).mapToObj(Item::new).forEach(itemList::add);
Random rng = new Random();
int start = rng.nextInt(itemList.size());
int end = Math.min(itemList.size(), start + 1 + rng.nextInt(15));
itemList.updateSublist(start, end, item -> item.setValue(rng.nextInt(10000)));
}
public static class Item {
private final IntegerProperty value = new SimpleIntegerProperty(this, "value");
private final String id ;
public Item(int value) {
id = "Item "+value ;
setValue(value);
}
public final IntegerProperty valueProperty() {
return this.value;
}
public final int getValue() {
return this.valueProperty().get();
}
public final void setValue(final int value) {
this.valueProperty().set(value);
}
#Override
public String toString() {
return id ;
}
}
}
import java.util.Scanner;
import java.util.ArrayList;
public class fester
{
public static void main(String args[] )
{
ArrayList<BankAccount> ba = new ArrayList<BankAccount>();
ba.add(new BankAccount("hi", 4));
}
class BankAccount
{
private String name;
private double amount;
public BankAccount(String name, Double amount)
{
this.name = name;
this.amount = amount;
}
public String getName()
{
return this.name;
}
public double getAmount()
{
return this.amount;
}
}
}
I dont get problem. I tried to almost copy this
http://www.java2s.com/Code/Java/Collections-Data-Structure/Storeuserdefinedobjectsinarraylist.htm
and it works. I'm very lost, and I cant see the fundamental differences.
You constructed class BankAccount as nested inner class (which means that you need an object of the outer class in order to instantiate it).
Move it outside of fester and replace 4 with 4.0 it'll work:
class fester {
public static void main(String args[]) {
ArrayList<BankAccount> ba = new ArrayList<BankAccount>();
ba.add(new BankAccount("hi", 4.0));
}
}
class BankAccount {
private String name;
private double amount;
public BankAccount(String name, Double amount) {
this.name = name;
this.amount = amount;
}
public String getName() {
return this.name;
}
public double getAmount() {
return this.amount;
}
}
Comment: You should follow Java naming convention and rename fester to Fester (with a capital letter).
I'm creating a TableView to show information regarding a list of custom objects (EntityEvents).
The table view must have 2 columns.
First column to show the corresponding EntityEvent's name.
The second column would display a button. The button text deppends on a property of the EntityEvent. If the property is ZERO, it would be "Create", otherwise "Edit".
I managed to do it all just fine, except that I can't find a way to update the TableView line when the corresponding EntityEvent object is changed.
Very Important: I can't change the EntityEvent class to use JavaFX properties, since they are not under my control. This class uses PropertyChangeSupport to notify listeners when the monitored property is changed.
Note:
I realize that adding new elements to the List would PROBABLY cause the TableView to repaint itself, but that is not what I need. I say PROBABLY because I've read about some bugs that affect this behavior.
I tried using this approach to force the repaint, by I couldn't make it work.
Does anyone knows how to do it?
Thanks very much.
Here is a reduced code example that illustrates the scenario:
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.beans.PropertyChangeSupport;
import javafx.application.Application;
import javafx.beans.property.ReadOnlyStringWrapper;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.event.ActionEvent;
import javafx.event.EventHandler;
import javafx.geometry.Insets;
import javafx.scene.Scene;
import javafx.scene.control.Button;
import javafx.scene.control.ContentDisplay;
import javafx.scene.control.TableCell;
import javafx.scene.control.TableColumn;
import javafx.scene.control.TableColumn.CellDataFeatures;
import javafx.scene.control.TableView;
import javafx.scene.layout.StackPane;
import javafx.scene.layout.VBox;
import javafx.scene.paint.Color;
import javafx.stage.Stage;
import javafx.util.Callback;
public class Main extends Application {
//=============================================================================================
public class EntityEvent {
private String m_Name;
private PropertyChangeSupport m_NamePCS = new PropertyChangeSupport(this);
private int m_ActionCounter;
private PropertyChangeSupport m_ActionCounterPCS = new PropertyChangeSupport(this);
public EntityEvent(String name, int actionCounter) {
m_Name = name;
m_ActionCounter = actionCounter;
}
public String getName() {
return m_Name;
}
public void setName(String name) {
String lastName = m_Name;
m_Name = name;
System.out.println("Name changed: " + lastName + " -> " + m_Name);
m_NamePCS.firePropertyChange("Name", lastName, m_Name);
}
public void addNameChangeListener(PropertyChangeListener listener) {
m_NamePCS.addPropertyChangeListener(listener);
}
public int getActionCounter() {
return m_ActionCounter;
}
public void setActionCounter(int actionCounter) {
int lastActionCounter = m_ActionCounter;
m_ActionCounter = actionCounter;
System.out.println(m_Name + ": ActionCounter changed: " + lastActionCounter + " -> " + m_ActionCounter);
m_ActionCounterPCS.firePropertyChange("ActionCounter", lastActionCounter, m_ActionCounter);
}
public void addActionCounterChangeListener(PropertyChangeListener listener) {
m_ActionCounterPCS.addPropertyChangeListener(listener);
}
}
//=============================================================================================
private class AddPersonCell extends TableCell<EntityEvent, String> {
Button m_Button = new Button("Undefined");
StackPane m_Padded = new StackPane();
AddPersonCell(final TableView<EntityEvent> table) {
m_Padded.setPadding(new Insets(3));
m_Padded.getChildren().add(m_Button);
m_Button.setOnAction(new EventHandler<ActionEvent>() {
#Override public void handle(ActionEvent actionEvent) {
// Do something
}
});
}
#Override protected void updateItem(String item, boolean empty) {
super.updateItem(item, empty);
if (!empty) {
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
setGraphic(m_Padded);
m_Button.setText(item);
}
}
}
//=============================================================================================
private ObservableList<EntityEvent> m_EventList;
//=============================================================================================
#SuppressWarnings("unchecked")
#Override
public void start(Stage primaryStage) {
primaryStage.setTitle("Table View test.");
VBox container = new VBox();
m_EventList = FXCollections.observableArrayList(
new EntityEvent("Event 1", -1),
new EntityEvent("Event 2", 0),
new EntityEvent("Event 3", 1)
);
final TableView<EntityEvent> table = new TableView<EntityEvent>();
table.setItems(m_EventList);
TableColumn<EntityEvent, String> eventsColumn = new TableColumn<>("Events");
TableColumn<EntityEvent, String> actionCol = new TableColumn<>("Actions");
actionCol.setSortable(false);
eventsColumn.setCellValueFactory(new Callback<CellDataFeatures<EntityEvent, String>, ObservableValue<String>>() {
public ObservableValue<String> call(CellDataFeatures<EntityEvent, String> p) {
EntityEvent event = p.getValue();
event.addActionCounterChangeListener(new PropertyChangeListener() {
#Override
public void propertyChange(PropertyChangeEvent event) {
// TODO: I'd like to update the table cell information.
}
});
return new ReadOnlyStringWrapper(event.getName());
}
});
actionCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<EntityEvent, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(TableColumn.CellDataFeatures<EntityEvent, String> ev) {
String text = "NONE";
if(ev.getValue() != null) {
text = (ev.getValue().getActionCounter() != 0) ? "Edit" : "Create";
}
return new ReadOnlyStringWrapper(text);
}
});
// create a cell value factory with an add button for each row in the table.
actionCol.setCellFactory(new Callback<TableColumn<EntityEvent, String>, TableCell<EntityEvent, String>>() {
#Override
public TableCell<EntityEvent, String> call(TableColumn<EntityEvent, String> personBooleanTableColumn) {
return new AddPersonCell(table);
}
});
table.getColumns().setAll(eventsColumn, actionCol);
table.setColumnResizePolicy(TableView.CONSTRAINED_RESIZE_POLICY);
// Add Resources Button
Button btnInc = new Button("+");
btnInc.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent ev) {
System.out.println("+ clicked.");
EntityEvent entityEvent = table.getSelectionModel().getSelectedItem();
if (entityEvent == null) {
System.out.println("No Event selected.");
return;
}
entityEvent.setActionCounter(entityEvent.getActionCounter() + 1);
// TODO: I expected the TableView to be updated since I modified the object.
}
});
// Add Resources Button
Button btnDec = new Button("-");
btnDec.setOnAction(new EventHandler<ActionEvent>() {
#Override
public void handle(ActionEvent ev) {
System.out.println("- clicked.");
EntityEvent entityEvent = table.getSelectionModel().getSelectedItem();
if (entityEvent == null) {
System.out.println("No Event selected.");
return;
}
entityEvent.setActionCounter(entityEvent.getActionCounter() - 1);
// TODO: I expected the TableView to be updated since I modified the object.
}
});
container.getChildren().add(table);
container.getChildren().add(btnInc);
container.getChildren().add(btnDec);
Scene scene = new Scene(container, 300, 600, Color.WHITE);
primaryStage.setScene(scene);
primaryStage.show();
}
//=============================================================================================
public Main() {
}
//=============================================================================================
public static void main(String[] args) {
launch(Main.class, args);
}
}
Try the javafx.beans.property.adapter classes, particularly JavaBeanStringProperty and JavaBeanIntegerProperty. I haven't used these, but I think you can do something like
TableColumn<EntityEvent, Integer> actionCol = new TableColumn<>("Actions");
actionCol.setCellValueFactory(new Callback<TableColumn.CellDataFeatures<EntityEvent, Integer> ev) {
return new JavaBeanIntegerPropertyBuilder().bean(ev.getValue()).name("actionCounter").build();
});
// ...
public class AddPersonCell extends TableCell<EntityEvent, Integer>() {
final Button button = new Button();
public AddPersonCell() {
setPadding(new Insets(3));
setContentDisplay(ContentDisplay.GRAPHIC_ONLY);
button.setOnAction(...);
}
#Override
public void updateItem(Integer actionCounter, boolean empty) {
if (empty) {
setGraphic(null);
} else {
if (actionCounter.intValue()==0) {
button.setText("Create");
} else {
button.setText("Add");
}
setGraphic(button);
}
}
}
As I said, I haven't used the Java bean property adapter classes, but the idea is that they "translate" property change events to JavaFX change events. I just typed this in here without testing, but it should at least give you something to start with.
UPDATE: After a little experimenting, I don't think this approach will work if your EntityEvent is really set up the way you showed it in your code example. The standard Java beans bound properties pattern (which the JavaFX property adapters rely on) has a single property change listener and an addPropertyChangeListener(...) method. (The listeners can query the event to see which property changed.)
I think if you do
public class EntityEvent {
private String m_Name;
private PropertyChangeSupport pcs = new PropertyChangeSupport(this);
private int m_ActionCounter;
public EntityEvent(String name, int actionCounter) {
m_Name = name;
m_ActionCounter = actionCounter;
}
public String getName() {
return m_Name;
}
public void setName(String name) {
String lastName = m_Name;
m_Name = name;
System.out.println("Name changed: " + lastName + " -> " + m_Name);
pcs.firePropertyChange("name", lastName, m_Name);
}
public void addPropertyChangeListener(PropertyChangeListener listener) {
pcs.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
pcs.removePropertyChangeListener(listener);
}
public int getActionCounter() {
return m_ActionCounter;
}
public void setActionCounter(int actionCounter) {
int lastActionCounter = m_ActionCounter;
m_ActionCounter = actionCounter;
System.out.println(m_Name + ": ActionCounter changed: " + lastActionCounter + " -> " + m_ActionCounter);
pcs.firePropertyChange("ActionCounter", lastActionCounter, m_ActionCounter);
}
}
it will work with the adapter classes above. Obviously, if you have existing code calling the addActionChangeListener and addNameChangeListener methods you would want to keep those existing methods and the existing property change listeners, but I see no reason you can't have both.
I am working with two helper classes (Student, Helper), as well as a main class.
In the Student class, I have the following constructor:
Student(String iName, String iMajor, int iNumber) {
name = iName;
major = iMajor;
number = iNumber;
}
In the Helper class, I declare a HashMap as follows:
HashMap<String, Student> students = new HashMap<String, Student>();
Now, I have written a few method for adding (put) new students into the HashMap construction, as well as a method for retrieving information about a student based on the name.
//Adding new students
Student s1 = new Student("Alex", "Biology", 19);
Student s2 = new Student("Brian", "Chemistry", 20);
Student s3 = new Student("Tom", "Biology", 20);
//etc...
//Get student from name (key)
public Student getFromKey(String key) {
return students.get(key);
}
I am now looking to write a method that finds all students based on either major or number. For instance, the call:
helper.getStudents("Biology");
Should return all the students studying Biology. I imagine the method looking something like:
public Student getStudents(String searchItem) {
for(Students st : students.values()) {
if(searchItem.equals(??)) {
return st;
//Something like this.
However, I can't seem to figure out how to access these values. All the classes have appropriate getter and setter methods, and the program works fine. Any help is highly appreciated!
Assuming this Map exists:
HashMap<String, Student> students = new HashMap<String, Student>();
The following would work:
public Student getStudents(String searchItem) {
for(Map.Entry<String,Student> entry : students.entrySet()) {
Student student = entry.getValue();
//perform conditional logic here
}
Here is a more complete example in case you need it:
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
public class Student {
private String name;
private String major;
private int number;
public Student(String name, String major, int number) {
super();
this.name = name;
this.major = major;
this.number = number;
}
public static void main(String[] args) {
List<String> names = Arrays.asList("Joe", "Jack", "John","James");
List<String> majors = Arrays.asList("English","Math","Geography");
Map<String,Student> students = new HashMap<String,Student>();
for(int i = 0; i < 100; i++){
Collections.shuffle(names);
Collections.shuffle(majors);
students.put(names.get(0) + String.valueOf(i), new Student(names.get(0), majors.get(0), i));
}
List<Student> mathMajors = getStudents(students, "Math");
for(Student student:mathMajors){
System.out.println(student.name);
System.out.println(student.major);
}
}
public static List<Student> getStudents(Map<String,Student> students, String searchToken){
List<Student> results = new ArrayList<Student>();
for(Entry<String,Student> entry:students.entrySet()){
if(entry.getValue().getMajor().equalsIgnoreCase(searchToken)){
results.add(entry.getValue());
}
}
return results;
}
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
public String getMajor() {
return this.major;
}
public void setMajor(String major) {
this.major = major;
}
public int getNumber() {
return this.number;
}
public void setNumber(int number) {
this.number = number;
}
}
On Github