I created a list and a model with custom objects. I want to retreive the objects that are in the list, however, I get an error message, that String can not be converted to Object.
String cannot be converted to ARMAJTermek
Swing automatically creates the JList, to which then I add a new model.
DefaultListModel model = new DefaultListModel<ARMAJTermek>();
TermekList.setModel(model);
I need this, because I'm using a custom object, that has properties and methods, which I need to invoke later. For this, I overrode the .toString method, like this:
#Override
public String toString () {
String toString = "";
toString = this.nev+"\n"+this.cikkszam+"\n"+Integer.toString(this.bruttoKisker)+" Ft";
return toString;
}
This way, when I add an object to the JList, it appears as designed by the cell renderer (which is also unique, in a way that it displays JTextArea as a list element...).
for (int i... and lots of other code) {
model.addElement(termek[i]);
}
TermekList.setModel(model);
TermekList.revalidate();
TermekList.repaint();
After adding objects to the list, it appears correctly, runs correctly, as when I select an object in the lists, it's methods run correctly. However, when I try to make a copy of the selected object for a different JList, I'm unable to retrieve them. I tried getting it from the list itself with
ARMAJTermek termek = (ARMAJTermek)TermekList.getSelectedValue();
ARMAJTermek termek = (ARMAJTermek)TermekList.getModel().getElementAt(TermekList.getSelectedIndex());
(Different functions, that's why some variables have the same name even being different types.)
But I get the message, that these Strings can not be converted to ARMAJTermek. But I don't need the String representation of the objects, I need the objects themselves. I mean, if it's methods can be run by clicking on their String representation in the list, I should be able to make a copy of them, right?
public class ARMAJTermek {
String nev;
String cikkszam;
int bruttoKisker;
public ARMAJTermek(String nev, String cikkszam, int bruttoKisker) {
this.nev = nev;
this.cikkszam = cikkszam;
this.bruttoKisker = bruttoKisker;
}
#Override
public String toString () {
String toString = "";
toString = this.nev+"\n"+this.cikkszam+"\n"+Integer.toString(this.bruttoKisker)+" Ft";
return toString;
}
}
public ui_main() throws {
initComponents();
DefaultListModel model = new DefaultListModel<ARMAJTermek>();
TermekList.setModel(model);
ARMAJTermek termek[2];
termek[0] = new ARMAJTermek("lorem", "ipsum", 1);
termek[1] = new ARMAJTermek("lorem2", "ipsum2", 2);
}
public void addTermek(JList TermekList) {
DefaultListModel model = new DefaultListModel<ARMAJTermek>();
model.clear();
if(TermekList.getSelectedIndex() == 0){
TermekList.setSelectedIndex(1);
}
TermekList.removeAll();
for ( int i = 0; i < termek.length; i++ ) {
model.addElement(termek[i]);
}
TermekList.setModel(model);
TermekList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
TermekList.revalidate();
TermekList.repaint();
}
public void getTermek(JList TermekList) {
ARMAJTermek termek = (ARMAJTermek)TermekList.getSelectedValue();
ARMAJTermek termek = (ARMAJTermek)TermekList.getModel().getElementAt(TermekList.getSelectedIndex());
}
I made it run by creating a new function inside the function, that can take and store the ARMAJTermek object:
ARMAJTermek termek = ARMAStaticFunctions.getTermek(TermekList);
public static ARMAJTermek getTermek(JList TermekList) {
ARMAJTermek termek = (ARMAJTermek)TermekList.getSelectedValue();
return termek;
}
And now it works as intended, not trying to convert objects to String.
Related
I have this code:
<xe:formTable id="formTable1" formTitle="User Roles">
<xe:formRow id="formRow1" label="Category Admin">
<xe:djextNameTextBox id="edtCatAdmin" multipleSeparator="," value="#{exhibitorInfo.categoryAdmin}" />
<xe:namePicker id="namePicker1" for="edtCatAdmin">
<xe:this.dataProvider>
<xe:namePickerAggregator>
<xe:this.dataProviders>
<xe:dominoNABNamePicker addressBookSel="first" groups="false" people="true" />
<xe:dominoViewNamePicker labelColumn="mailinName" viewName="lkp_MailIn" label="Group Mailboxes" />
</xe:this.dataProviders>
</xe:namePickerAggregator>
</xe:this.dataProvider>
</xe:namePicker>
</xe:formRow>
</xe:formTable>
The goal is to just have a multi-value name picker save it's valies in a Java Bean rather then a document field. So the name picker points to a xe:djextNameTextBox to make it easy to remove the names and the xe:djextNameTextBox is bound to my bean.
Using this Java Code -
public void setCategoryAdmin(ArrayList<String> categoryAdmin) {
System.out.println("Set CategoryAdmin - List");
this.categoryAdmin = categoryAdmin;
}
public void setCategoryAdmin(String categoryAdmin) {
System.out.println("Set CategoryAdmin - String");
if (!this.isBlankString(categoryAdmin)) {
ArrayList<String> al = new ArrayList<String>();
al.add(categoryAdmin);
this.setCategoryAdmin(al);
}
}
It appears to work fine for MULTIPLE values. but if only a single valule is used I get an error: java.lang.IllegalArgumentException: argument type mismatch
I THINK this has to do with XPages returning an Array for multiple values and a String for single values. But I'm not sure how to make this work.
Any advice would be appreciated! Thanks!!
--UPDATE--
This code from the blogpost that Camac linked to seems to work.
public Object getCategoryAdmin() {
System.out.println("getCategoryAdmin");
return this.categoryAdmin;
}
#SuppressWarnings("unchecked")
public void setCategoryAdmin( Object inputMulti ) {
this.categoryAdmin = this.translateToVector( inputMulti );
}
#SuppressWarnings("unchecked")
public Vector translateToVector( Object object ){
if( object instanceof String ){
Vector list = new Vector();
list.add( object );
return list;
}
if( object instanceof List ){
return (Vector)object;
}
return null;
}
i remember having the same problem and using tips from this link helped:
http://dontpanic82.blogspot.com.au/2012/06/multi-value-fields-and-beans-in-xpages.html
maybe try having the public getter and setter use java.lang.Object, instead of having 2 different ones?
I'm having trouble understanding what exactly I would put in one of my classes to create the add method for 3 Arrays of the same Type. Here are the generic arrays in the main class
ArrayContainer<Integer> numberContainer = new ArrayContainer<>();
ArrayContainer<String> wordContainer = new ArrayContainer<>();
ArrayContainer<Pokemon> pokedex = new ArrayContainer<>();
My constructor for ArrayContainer is
public ArrayContainer(){
container = (T[]) new Object[defaultSize];
numItems = 0;
}
In my separate class, I'm confused what to put for my
public void add (T item){}
and I'm confused as what to return within my toString. I know you add to an array by putting
arrayName[index] = whatever;
But what would I put in that add method that would add to whatever array I call the method on? Would it be container[index] = item;?
What should I return that would return the element in the array?
Since the number of items in your ArrayContainer is not known beforehand, you should use a dynamic array, also known as List.
The numItems then becomes redundant since you can get it by calling list.size()
Your add function will only need to call list.add. As noted in the comments, it seems you're re-writing/wrapping List
In your toString method, you can return a string that concatenates all results of toString of the items included. StringBuilder can help you create a "format" that suits you. Of course this means that the objects you're putting in the container need to implement toString
Combining all the things will give you something like this:
ArrayContainer
public class ArrayContainer<T> {
private List<T> items;
public ArrayContainer() {
items = new ArrayList<>();
}
public void add(T item) {
items.add(item);
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[ ");
for (T it: items)
sb.append(it.toString()).append(' ');
sb.append(']');
return sb.toString();
}
}
Main
public class Main {
public static void main(String[] args) {
ArrayContainer<String> stringArrayContainer = new ArrayContainer<>();
stringArrayContainer.add("hello");
stringArrayContainer.add("world");
System.out.println(stringArrayContainer);
// Outputs: [hello world]
}
}
I have this class that serves as a container which I will use the instance variable for processing later
class Data{
static int counter= 0;
boolean boolean1;
String string1;
public Data() {
counter++;
}
}
And I have this method that sets the values of Data
public Data setData()
{
Data data = null;
for (int i = 0; i < somecoutnerhere; i++) {
Data = new Data();
Data.boolean1 = some boolean put here;
Data.string1 = "some string to be put here";
}
return ProcessData(Data);
}
I also have this class ProcessData that will make use of Data and will construct the response
private class ProcessData
{
private final Map<String, List<?>> map = new HashMap<String, List<?>>();
int counter;
public ProcessData(Data data)
{
map.put("boolean1", data.boolean1);
map.put("String1", data.string1);
counter = data.counter;
}
public String someMethodToGenerateReturnData(){
// some code here to make use of the Data collected. Will basically use map to construct the return String
}
}
My problem is that I couldn't figure out how can I return all the instance variables created on the for-loop for Data on setData(). Any thoughts?
My problem is that I couldn't figure out how can I return all the instance variables created on the for-loop for Data on setData(). Any thoughts?
According to this your problem is not "returning all instance one variables in one call", as your title states, but rather a question about how returning all Data-Objects created in your for-loop, which is easier.
Your code is erronous though, so I went ahead & corrected it (I hope I didn't mess up). I also renamed a few things.
The changes I made are:
renamed "boolean1" and "string1" to "trueOrFalse" and "string"
added a public, fully parameterized constructor to the Data-class
added a ProcessData-list to the setData()-method, which is filled in the for-loop
(+ a comment)
However, I'd strongly recommend you to check your architecture, and also to learn a bit about naming conventions, or coding conventions in general. Names should point out the purpose or content of the method/variable/class, and "boolean1" isn't really doing that.
Regarding the architecture: The Data-class seems to exist solely for the counter, and you could easily change that, making the Data-class obsolete (unless it's used somewhere else).
Data class:
class Data {
static int counter = 0;
boolean trueOrFalse;
String string;
public Data() {
counter++;
}
public Data(boolean someBoolean, String someString) {
this.trueOrFalse= someBoolean;
this.string = someString;
counter++;
}
}
setData()-Method:
public List<ProcessData> setData() {
List<ProcessData> processedDataList = new ArrayList<ProcessData>();
for (int i = 0; i < someCounterHere; i++) {
processedDataList.add(new ProcessData(new Data(true, "testString"));
// a new Data-object is created (parameters true and "testString")
// a new ProcessData-object is created (parameter is the newly created Data-Object)
// the newly created ProcessData-object is added to the list
}
return processedDataList;
}
ProcessData-class:
private class ProcessData {
private final Map<String, List<?>> map = new HashMap<String, List<?>>();
int counter;
public ProcessData(Data data) {
map.put("trueOrFalse", data.trueOrFalse);
map.put("string", data.string);
counter = data.counter;
}
public String someMethodToGenerateReturnData() {
// some code here to make use of the Data collected. Will basically use map to construct the return String
}
}
I don't know if this is possible in Java but I was wondering if it is possible to use an object in Java to return multiple values without using a class.
Normally when I want to do this in Java I would use the following
public class myScript {
public static void main(String[] args) {
// initialize object class
cl_Object lo_Object = new cl_Object(0, null);
// populate object with data
lo_Object = lo_Object.create(1, "test01");
System.out.println(lo_Object.cl_idno + " - " + lo_Object.cl_desc);
//
// code to utilize data here
//
// populate object with different data
lo_Object = lo_Object.create(2, "test02");
System.out.println(lo_Object.cl_idno + " - " + lo_Object.cl_desc);
//
// code to utilize data here
//
}
}
// the way I would like to use (even though it's terrible)
class cl_Object {
int cl_idno = 0;
String cl_desc = null;
String cl_var01 = null;
String cl_var02 = null;
public cl_Object(int lv_idno, String lv_desc) {
cl_idno = lv_idno;
cl_desc = lv_desc;
cl_var01 = "var 01";
cl_var02 = "var 02";
}
public cl_Object create(int lv_idno, String lv_desc) {
cl_Object lo_Object = new cl_Object(lv_idno, lv_desc);
return lo_Object;
}
}
// the way I don't really like using because they get terribly long
class Example {
int idno = 0;
String desc = null;
String var01 = null;
String var02 = null;
public void set(int idno, String desc) {
this.idno = idno;
this.desc = desc;
var01 = "var 01";
var02 = "var 02";
}
public int idno() {
return idno;
}
public String desc() {
return desc;
}
public String var01() {
return var01;
}
public String var02() {
return var02;
}
}
Which seems like a lot of work considering in Javascript (I know they are different) I can achieve the same effect just doing
var lo_Object = f_Object();
console.log(lo_Object["idno"] + " - " + lo_Object[desc]);
function f_Object() {
var lo_Object = {};
lo_Object = {};
lo_Object["idno"] = 1;
lo_Object["desc"] = "test01";
return lo_Object;
}
NOTE
I know the naming convention is wrong but it is intentional because I have an informix-4gl program that runs with this program so the coding standards are from the company I work for
The best way to do this is to use HashMap<String, Object>
import java.util.HashMap;
public class Main {
public static void main(String[] args) {
HashMap<String, Object> person =
new HashMap<String, Object>();
// add elements dynamically
person.put("name", "Lem");
person.put("age", 46);
person.put("gender", 'M');
// prints the name value
System.out.println(person.get("name"));
// asures that age element is of integer type before
// printing
System.out.println((int)person.get("age"));
// prints the gender value
System.out.println(person.get("gender"));
// prints the person object {gender=M, name=Lem, age=46}
System.out.println(person);
}
}
The advantage of doing this is that you can add elements as you go.
The downside of this is that you will lose type safety like in the case of the age. Making sure that age is always an integer has a cost. So to avoid this cost just use a class.
No, there is no such a feature, you have to type out the full type name(class name).
Or use may use val :
https://projectlombok.org/features/val.html
Also, if you use IntelliJ IDEA
try this plugin :
https://bitbucket.org/balpha/varsity/wiki/Home
I am not sure if it's possible with Java. Class is the primitive structure to generate Object. We need a Class to generate object. So, for the above code, i don't think there is a solution.
Java methods only allow one return value. If you want to return multiple objects/values consider returning one of the collections. Map, List, Queue, etc.
The one you choose will depend on your needs. For example, if you want to store your values as key-value pairs use a Map. If you just want to store values sequentially, use a list.
An example with a list:
list<Object> myList = new ArrayList<Object>();
myList.add("Some value");
return myList;
As a side note, your method create is redundant. You should use getters and setters to populate the object, or populate it through the constructor.
cl_Object lo_Object = new cl_Object(1, "test01");
The way you have it set up right now, you're creating one object to create another of the same type that has the values you want.
Your naming convention is also wrong. Please refer to Java standard naming convention:
http://www.oracle.com/technetwork/java/javase/documentation/codeconventions-135099.html#367
How do you return an array object in Java? I have an object that has an array in it and I want to work with it in my main class:
// code that does not work
class obj()
{
String[] name;
public obj()
{
name = new string[3];
for (int i = 0; i < 3; i++)
{
name[i] = scan.nextLine();
}
}
public String[] getName()
{
return name;
}
}
public class maincl
{
public static void main (String[] args)
{
obj one = new obj();
system.out.println(one.getName());
}
I am sorry if the answer is simple but I am teaching myself to code and I have no idea how you would do this.
You have to use the toString method.
System.out.println(Arrays.toString(one.getName()));
toString is a built-in function in Java (it might need library import; if you are using Netbeans, it will suggest it).
If the problem is to print it use
System.out.println(Arrays.toString(one.getName()));
//note System, not system
When you do getName() you are returning a reference to an array of strings, not the strings themselves. In order to access the individual strings entered, you can use the array index
String enteredName = name[index] format.
From your program, it looks like you want to print each item entered. For that, you could use a method like the following
public void printName() {
// for each item in the list of time
for(String enteredName : name) {
// print that entry
System.out.println(enteredName);
}
}