How to define protected, public and private in Generic JavaBean? - java

I am wondering how can I define protected, public and private properties in my class GenericBean, which will result in a JavaBean. So far I've declared a class, that will enable use to access the value of the Bean, however, I have no idea how I can handle different accesses for those properties. Any idea? Here is m y class:
abstract class GenericBean {
protected PropertyChangeSupport chg = new PropertyChangeSupport(this);
protected VetoableChangeSupport veto = new VetoableChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener pcl) {
chg.addPropertyChangeListener(pcl);
}
public void removePropertyChangeListener(PropertyChangeListener pcl) {
chg.addPropertyChangeListener(pcl);
}
class BoundedProperty<T> implements PropertyChangeListener {
private String name;
private T value;
private Object chgHandlerObject;
private Method changeHandler;
public BoundedProperty(String name) {
this.name = name;
}
public T getValue() { return value; }
public void setValue(T newValue) {
T old = value;
value = newValue;
chg.firePropertyChange(name, old, value);
}
public void propertyChange(PropertyChangeEvent e) {
if (!e.getPropertyName().equals(name)) return;
if (changeHandler == null) return;
try {
changeHandler.invoke(chgHandlerObject);
} catch(Exception exc) {
exc.printStackTrace();
}
}
public void setChangeHandler(Object handl, String mname) {
try {
Method m = handl.getClass().getDeclaredMethod(mname);
chgHandlerObject = handl;
changeHandler = m;
chg.addPropertyChangeListener(this);
} catch(Exception exc) {
exc.printStackTrace();
return;
}
}
public void setChangeHandler(Object ohandler) {
try {
Method m = ohandler.getClass().getDeclaredMethod(name+"Change");
chgHandlerObject = ohandler;
changeHandler = m;
} catch(Exception exc) {
exc.printStackTrace();
return;
}
chg.addPropertyChangeListener(this);
}
public void removeChangeHandler() {
changeHandler = null;
chgHandlerObject = null;
chg.removePropertyChangeListener(this);
}
}
}
So that I can decide which methods are available for certain fields?

Related

How print the entire data structure created with Composite?

I have class-Composite:
public class CompositeText implements ComponentText {
private TypeComponent type;
private String value;
private final List<ComponentText> childComponents;
private CompositeText() {
childComponents = new ArrayList<>();
}
public CompositeText(String value, TypeComponent typeComponent) {
this.value = value;
this.type = typeComponent;
childComponents = new ArrayList<>();
}
#Override
public void add(ComponentText componentText) {
childComponents.add(componentText);
}
#Override
public void remove(ComponentText componentText) {
childComponents.remove(componentText);
}
#Override
public TypeComponent getComponentType() {
return this.type;
}
#Override
public ComponentText getChild(int index) {
return childComponents.get(index);
}
#Override
public int getCountChildElements() {
return childComponents.size();
}
#Override
public int getCountAllElements() {
return childComponents.stream()
.mapToInt(ComponentText::getCountAllElements)
.sum();
}
#Override
public String toString() {
return null;
}
}
I created classes that perform the same action - parsing, parsing text into paragraphs, into sentences, into tokens, into symbols.
public class IntoParagraphParser implements ActionParser {
// call IntoSentenceParser
}
public class IntoSentenceParser implements ActionParser {
// call IntoLexemeParser
}
public class IntoLexemeParser implements ActionParser {
// call IntoSymbolParser
}
public class IntoSymbolParser implements ActionParser {
}
All data is stored in List <ComponentText> childComponents in class-Composite - CompositeText.
How to properly create a method so that it prints all the data that is inside the composite?
I think this will be the method toString() in CompositeText.
Class IntoParagraphParser look:
public class IntoParagraphParser implements ActionParser {
private static final String PARAGRAPH_SPLIT_REGEX = "(?m)(?=^\\s{4})";
private static final IntoParagraphParser paragraphParser = new IntoParagraphParser();
private static final IntoSentenceParser sentenceParser = IntoSentenceParser.getInstance();
private IntoParagraphParser() {
}
public static IntoParagraphParser getInstance() {
return paragraphParser;
}
public ComponentText parse(String text) throws TextException {
ComponentText oneParagraph;
ComponentText componentParagraph = new CompositeText(text, TypeComponent.PARAGRAPH);
String[] arrayParagraph = text.split(PARAGRAPH_SPLIT_REGEX);
for(String element: arrayParagraph) {
oneParagraph = new CompositeText(element, TypeComponent.PARAGRAPH);
oneParagraph.add(sentenceParser.parse(element));
componentParagraph.add(oneParagraph);
}
return componentParagraph;
}
}
Need #Override the method toString() in CompositeText like this:
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (ComponentText component : childComponents) {
builder.append(component.toString());
}
return builder.toString();
}
But how to write this code correctly with Stream API?
#Override
public String toString() {
StringBuilder builder = new StringBuilder();
childComponents.stream().map(...????
return builder.toString();
}

How to Dynamically call and setter and getter methods using Reflection class?

Say I have class AccountPojo and GetAccountPojo with its setter and getter methods as below.
public class AccountPojo {
private String dataList;
private String dataSet;
public String getDataList() {
return dataList;
}
public void setDataList(String dataList) {
this.dataList = dataList;
}
public String getDataSet() {
return dataSet;
}
public void setDataSet(String dataSet) {
this.dataSet = dataSet;
}
}
public class GetAccountsPojo {
private String accountId;
private int noOfAccounts;
public String getAccountId() {
return accountId;
}
public void setAccountId(String accountId) {
this.accountId = accountId;
}
public int getNoOfAccounts() {
return noOfAccounts;
}
public void setNoOfAccounts(int noOfAccounts) {
this.noOfAccounts = noOfAccounts;
}
}
Now I have class Test as below
public Class Test {
public static void main(String[] args) {
Class cls = Class.forName("com.org.temp."+ClassName); // ClassName(AccountPojo/GetAccountPojo) here I know already which class is getting called.
Object clsInstance = (Object) cls.newInstance();
System.out.println("The cls is==" + cls+" and classInstance is=="+clsInstance);
// Here I want to access getter and setter methods of AccountPojo and GetAcoountPojo dynamically, no hard coding
}
}
Have you tried getting all the methods of the invoked class and filtering out only the getter methods by name and invoking them?
Method[] methods = cls.getClass().getDeclaredMethods();
for (Method m: methods) {
if(m.getName().startsWith("get")) {
m.invoke(clsInstance);
}
}
This solves our half problem, as getters are invoked without any arguments. But if you need to invoke a setter method you need to specify arguments. Ex, To invoke a setter which accepts string argument method as below:
m.invoke(clsInstance, "some string argument");
One solution to could be make all the setters accept an object type value and typecast them while assigning it to actual class variables.
Now your pojo classes will look as below:
public class AccountPojo {
private String dataList;
private String dataSet;
public String getDataList() {
return dataList;
}
public void setDataList(Object dataList) {
this.dataList = (String) dataList;
}
public String getDataSet() {
return dataSet;
}
public void setDataSet(Object dataSet) {
this.dataSet = (String)dataSet;
}
}
public class GetAccountsPojo {
private String accountId;
private int noOfAccounts;
public String getAccountId() {
return accountId;
}
public void setAccountId(Object accountId) {
this.accountId = (String) accountId;
}
public int getNoOfAccounts() {
return noOfAccounts;
}
public void setNoOfAccounts(Object noOfAccounts) {
this.noOfAccounts = (int) noOfAccounts;
}
}
Add below code to your main method:
for (Method m: methods) {
if(m.getName().startsWith("get")) {
m.invoke(clsInstance);
}
if(m.getName().startsWith("set")) {
m.invoke(clsInstance, "any argument to be passed here");
}
}
Don't use raw class. If you know which class is called already, use typed class.
try {
AccountPojo obj = AccountPojo.class.newInstance();
Method setDataList = AccountPojo.class.getMethod("setDataList");
setDataList.setAccessible(true); // This is important if you want to access protected or private method. For public method you can skip
setDataList.invoke(obj, "123");
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}

DataFlavor custom class usage

I want to create a custom dataFlavor with my class (Item.class)
#Override
public synchronized void drop(DropTargetDropEvent dtde) {
DataFlavor itemFlavor = new DataFlavor(Item.class, Item.class.getSimpleName());
try{
System.out.println(dtde.getTransferable().getTransferData(itemFlavor));
}catch(UnsupportedFlavorException | IOException e){
e.printStackTrace();
}
}
Item.class
public class Item {
private String classFile;
private String imgFile;
private String imgPath;
public Item(String classFile, String imgFile, String imgPath){
this.classFile = classFile;
this.imgFile = imgFile;
this.imgPath = imgPath;
}
public String getImgFile() {
return imgFile;
}
public void setImgFile(String imgFile) {
this.imgFile = imgFile;
}
public String getClassFile() {
return classFile;
}
public void setClassFile(String classFile) {
this.classFile = classFile;
}
public String getImgPath() {
return imgPath;
}
public void setImgPath(String imgPath) {
this.imgPath = imgPath;
}
}
but I'm getting an error: java.awt.datatransfer.UnsupportedFlavorException: Item
Can you say what is wrong ?
I were using this docs https://docs.oracle.com/javase/tutorial/uiswing/dnd/dataflavor.html
Example, that demonstrate the problem DND Test Project
To get an error, try drag from JTable to JLayeredPane

Constructor of a child class

folks.... i have a child class GateNot which extends Gate. I'm not sure how to fill out the constructor of GateNot since Im not given any instance variables inside a child class. What would be the approach?
public class GateNot extends Gate {
public GateNot(Wire input, Wire output)
{
super()
}
}
import java.util.*;
public abstract class Gate implements Logic {
private List<Wire> inputs;
private Wire output;
private String name;
public Gate(String name, List<Wire> ins, Wire out)
{
this.name = name;
this.output = out;
if(ins.size() == 0 || ins.isEmpty())
throw new ExceptionLogicParameters(false, 1, 0);
else
this.inputs = ins;
}
#Override
public void feed(List<Signal> inSigs)
{
if(inSigs.size() != inputs.size())
throw new ExceptionLogicParameters(false, inputs.size(), inSigs.size());
else
{
for(int i = 0; i < inSigs.size(); i++)
{
inputs.get(i).setSignal(inSigs.get(i));
}
}
}
#Override
public void feed(String name)
{
if(!(this.name.equals(name)))
throw new ExceptionLogicMalformedSignal(name.charAt(0), "Invalid logic input");
else
{
Signal signalValue = Signal.fromString(name.charAt(0));
}
}
#Override
public List<Signal> read()
{
List<Signal> signals = new ArrayList<>();
signals.add(output.getSignal());
return signals;
}
#Override
public String toString()
{
return this.name+"( " + inputs.toString() + " | " + output.toString() + " )";
}
#Override
public boolean equals(Object other)
{
if(other instanceof Gate)
{
Gate someGate = (Gate)other;
return (this.inputs == someGate.inputs) && (this.output.equals(someGate.output)
&& (this.name.equals(someGate.name)));
}
else
return false;
}
public List<Wire>getInputs()
{
return this.inputs;
}
public Wire getOutput()
{
return this.output;
}
public String getName()
{
return this.name;
}
public void setInputs(List<Wire> inputs)
{
this.inputs = inputs;
}
public void setOutput(Wire output)
{
this.output = output;
}
public void setName(String name)
{
this.name = name;
}
}
You have to call the super class's constructor.
Based on the argument types and names of the super class's constructor, I'd say this is what you need :
public GateNot(Wire input, Wire output)
{
super("Not", Arrays.asList(new Wire[]{input}), output);
}
You can pass whatever String you wish as name
You should convert the input to a List of inputs
You can pass the output as is

Casting DataRow to Strongly-Typed DataRow

I have a class that extends DataRow:
import org.jdesktop.dataset.DataRow;
public class MainDataRow extends DataRow {
private MainDataTable baseDataTable;
protected MainDataRow(MainDataTable dt) {
super(dt);
this.baseDataTable = dt;
}
public int getId() { return (int) super.getValue(baseDataTable.getColId()); };
public void setId(int id) { super.setValue(baseDataTable.getColId(), id); };
public int getDelta() { return (int) super.getValue(baseDataTable.getColDelta()); };
public void setDelta(int delta) { super.setValue(baseDataTable.getColDelta(), delta); };
public String getNombre() { return (String) super.getValue(baseDataTable.getColNombre()); };
public void setNombre(String nombre) { super.setValue(baseDataTable.getColNombre(), nombre); };
Also MainDataTable extends DataTable, and returns valid columns for getColId(), getColDelta(), getColNombre().
I would like to do:
MainDataTable dt = new MainDataTable(ds);
MainDataRow dr = (MainDataRow) dt.appendRow();
But this is not possible due to a CastClassException (dt.appendRow return DataRow and MainDataRow is extending DataRow, not vice versa, so the only possibility could be something similar to DataRow dr = (DataRow) new MainDataRow(dt);).
In c++ it can be easyly achieved through DataRowBuilder, overriding NewRowFromBuilder() in MainDataTable and overriding the protected creator from DataRowBuilder in MainDataRow (Casting DataRow to Strongly-Typed DataRow: How do they do it?).
How could I do it in Java?
Edit
MainDataTable class:
public class MainDataTable extends TypedDataTable<MainDataRow> {
...
}
And TypedDataTable class:
public abstract class TypedDataTable<TypeOfRow> extends DataTable {
protected boolean locked;
public TypedDataTable(DataSet ds, boolean appendRowSupported) {
super(ds);
InitClass();
super.setAppendRowSupported(appendRowSupported);
locked = false;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
#Override
public abstract DataRow appendRow();
#Override
public abstract DataRow appendRowNoEvent();
public abstract void InitVars();
public abstract void InitClass();
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
}
Override appendRow() and appendRowNoEvent() in MainDataTable to return a MainDataRow
public abstract class TypedDataTable<TypeOfRow extends DataRow> extends DataTable {
protected boolean locked;
public TypedDataTable(DataSet ds, boolean appendRowSupported) {
super(ds);
InitClass();
super.setAppendRowSupported(appendRowSupported);
locked = false;
}
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
return null;
}
}
#Override
public TypeOfRow appendRowNoEvent() {
if (appendRowSupported) {
TypeOfRow row = createDataRow(); //<-- HERE we create a MainDataRow!!!
rows.add(row);
return row;
} else {
return null;
}
}
#Override
public TypeOfRow appendRow() {
return (TypeOfRow)super.appendRow();
}
public abstract TypeOfRow createDataRow();
public abstract void InitVars();
public abstract void InitClass();
public boolean isLocked() {
return locked;
}
public void setLocked(boolean locked) {
this.locked = locked;
}
}

Categories