Im try to insert data into Database using ArrayList.there is a Erro msg.
That is my Custmer.class method. this is what i got from when i going to pass ArrayList into another class.
incompatible types: ArrayList<String> cannot be converted to ArrayList<Inquiries>
I want to know how to do this using correct Using OOP concept
public void passingMsg(ArrayList<Inquiries> arrlist){
try {
System.out.println("Method "+arrlist);
String sq = "INSERT INTO Inquiries (name,mail,tp,msg)VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for(int i=0;i<arrlist.size();i++){
pr.setString(1,arrlist.get(i).getName());
pr.setString(2,arrlist.get(i).getMail());
pr.setString(3,arrlist.get(i).getTp());
pr.setString(4,arrlist.get(i).getMsg());
}
pr.executeQuery();//executeBatch();
} catch (SQLException ex) {
}
}
and this is how i get values from user
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
Custmer c =new Custmer();
if( c.passingMsg(arrInq)){
try {
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
}
and this is my Inquiries.class :
public class Inquiries {
private String name;
private String mail;
private String tp;
private String msg;
public Inquiries(String name,String mail,String tp,String msg){
this.name = name;
this.mail = mail;
this.tp = tp;
this.msg = msg;
}
//
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getMail() {
return mail;
}
public void setMail(String mail) {
this.mail = mail;
}
public String getTp() {
return tp;
}
public void setTp(String tp) {
this.tp = tp;
}
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
}
Can Some one please explain whats wrong with this. please ?
Reason For Error
This was simply telling you that your types were incompatible for the operation you were trying to perform. In your passingMsg() method, you have its header as: public void passingMsg(ArrayList<Inquiries> arrlist). However, inside your "how i get values from user" area, which I will now refer to as "2nd Snippet", you have your method call declared as: if( c.passingMsg(arrInq)). This means that you are implying that your parameter being passed, arrInq in this case, is of the type ArrayList<Inquiries>, but it's not. It's being initialized in your 2nd Snippet as: ArrayList<String> arrInq = new ArrayList<String>();
Simple Fix
I take no responsibility for this code; use at your own risk. To fix this, you would want to change that entire 2nd Snippet to something similar to the following:
String name = txtName.getText();
String mail = txtEmail.getText();
String tp = txtTp.getText();
String msg = txtMsg.getText();
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));
Custmer c = new Custmer();
try {
c.passingMsg(arrInq);
JOptionPane.showMessageDialog(this, "Successs!!");
} catch (Exception e) {
JOptionPane.showMessageDialog(this, "Unsuccesss!!");
e.printStackTrace();
}
You would also want to change the method header to either return a boolean, or fix it up a little bit to actually throw the exception. Such as:
public void passingMsg(ArrayList<Inquiries> arrlist) {
System.out.println("Method " + arrlist);
String sq = "INSERT INTO Inquiries(name,mail,tp,msg) VALUES(?,?,?)";
PreparedStatement pr = con.prepareStatement(sq);
for (Inquiries inquiries : arrlist) {
pr.setString(1, inquiries.getName());
pr.setString(2, inquiries.getMail());
pr.setString(3, inquiries.getTp());
pr.setString(4, inquiries.getMsg());
}
pr.executeQuery();//executeBatch();
}
Let's talk in O-O-P way.
Here Inquiries is your model, model is nothing but simple class that has instance members and public methods to get and set value of model's instance variable.
Generally we put all database related operations code in their respective models.
e.g. I have model "Model" which typically maps to database table say it as "TableModel" ,I would do something like this:
public class Model{
private int id;
private String attr;
//other properties of the model
public int getId(){
return id;
}
public void setId(int id){
this.id=id;
}
//other getters and setters
//here we write methods to performs database operations
public void save(){
//use "this" to get properties of object
//logic to save to this object in database table TableModel as record
}
public void delete(int id){
//logic to delete this object i.e. from database table TableModel
}
public Model get(int id){
//retrieve record from table TableModel with this id
}
//other methods to get data from database.
}
Now question is how I can use this in some another class. Let's say I have list of Model objects and I wish to insert them in to database.I will do it something like this:
public class AnotherClass{
public void someMethod(){
//create list of models objects e.g. get them from user interface
ArrayList<Model> models=new ArrayList<>();
for(int i=0;i<3;i++){
Model model=new Model();
model.setId(i);
model.setAttr("attr"+i);
models.add(model);
}
SomeOtherClass obj=new SomeOtherClass();
obj.insert(models);
}
}
public class SomeOtherClass{
//other code above.....
//my method that inserts each Model object in database
//Note: this is sample method , you should do it in optimized way
// e.g. batch insert
public void insert(ArrayList<Model> models){
for(Model myModel:models){
myModel.save();
}
}
//other code below.....
}
You are using the wrong type parameter for the ArrayList. Instead of ArrayList<String> you need ArrayList<Inquiries>. To fix the problem, you should remove this code ...
ArrayList<String> arrInq = new ArrayList<String>();
arrInq.add(name);
arrInq.add(mail);
arrInq.add(tp);
arrInq.add(msg);
... and replace it with this code:
ArrayList<Inquiries> arrInq = new ArrayList<Inquiries>();
arrInq.add(new Inquiries(name, mail, tp, msg));
Related
I have an class IntegrationWithDB in which i have to method getConnection()and selectFromDB().
In the selectFromDb() i have a result set , i want to get the result
set vales in another class method
Actually it did but it only shows the last value of dataBase table.
Note i have made getter and setter method in IntegrationWithDB class and use in selectFromDB() method.
public void selectFromDB() {
try {
if (this.conn == null) {
this.getConnection();
}
if (this.stmt == null) {
this.stmt = this.conn.createStatement();
}
int success = 0;
this.query = "select * from contacts order by node_id";
this.rs = this.stmt.executeQuery(query);
// something is wrong in the while loop
while (rs.next()) {
setId(rs.getInt("node_id")); // i made getter and setter for id, name, parent and for level
setNam(rs.getString("node_name"));
setParnt(rs.getString("node_parent"));
setLvl(rs.getInt("node_parent"));
}
if (success == 0) {
this.conn.rollback();
} else {
this.conn.commit();
}
} catch (Exception ex) {
ex.printStackTrace();
}
and in another class test i have method displayList() in this method i write the following code
public class test {
IntegrationWithDbClass qaz = new IntegrationWithDbClass();
public void displayList ( ) {
qaz.getConnection();
qaz.selectFromDB();
for(int i = 0; i< 5; i++){
System.out.println(" "+qaz.getId());
System.out.println(" "+qaz.getNam());
}
}
when i initilize the displayList() method in the main method , it shows the following result
5
red
how can i get all the five values?
First of all you have to create what is commonly referred to as an Entity class. This is the class that represents a single row in your database. This should ideally be separate from the code that interacts with the database connection.
So first step, create a class named Contact, and in it put the 4 fields you have, id, name, parent and level, with the respective getter methods. If you do not expect these to change by your program make them immutable, it is the good practice to ensure consistency. So something like:
public class Contact {
private final int id;
private final String name;
private final String parent;
private final String level;
public Contact(String id, String name, String parent, String level) {
this.id = id;
this.name = name;
this.parent = parent;
this.level = level;
}
public int getId() {
return id;
}
//... put the rest of the getter methods
}
Then in your IntegrationWithDB class (I would rename this to something more meaningful like ContactRepository) you can change that method you have to:
public List<Contact> getContacts() {
// ... your database connection and query code here
this.rs = this.stmt.executeQuery(query);
List<Contact> contacts = new LinkedList<Contact>();
while (rs.next()) {
int id = rs.getInt("node_id");
String name = rs.getString("node_name");
String parent = rs.getString("node_parent");
String level = setLvl(rs.getInt("level"));
contacts.add(new Contact(id, name, parent, level));
}
//... the rest of your database handling code, don't forget to close the connection
return contacts;
}
Then from displayList() you just have to call getContacts() which gives you a list of Contact objects to iterate through.
I assume that currently you're storing those properties in int/string variables. In every iteration of the loop you're overwriting the values. What you need to do is to store them in some collection like ArrayList and in each iteration add() to this collection.
I have used One-to-Many Mapping in my project. I have stored a list of clicks for every user.
But when I retrieve the list by calling getClicks() methodm Hibernate returns list in different format.
Something like this.
"[com.zednx.tech.persistence.Click#29df9a77]"
So I tried Reading Every value from the list and assign to a new List.
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
clicks.add(temp);
}
But when i print the items of new List it stills prints the same way.
I need to build a JSON from the resulting String of this list.
So if the list is returned in format, it wont help me.
I couldn't find anything regarding this except How to pretty print Hibernate query results?
I tried Arrays.ToString(Object o). But it doesn't work.
GSON builder part-
Gson gson = new GsonBuilder()
.registerTypeAdapter(Click.class, new MyTypeAdapter<Click>())
.create();
List<Click> clicks=new ArrayList<Click>();
for(Click c: e.getClicks()){
Click temp = new Click();
temp.setAff_source(c.getAff_source());
temp.setCb_to_award(c.getCb_to_award());
temp.setCb_type(c.getCb_type());
temp.setCom_to_recieve(c.getCom_to_recieve());
temp.setStore_name(c.getStore_name());
temp.setT_date(c.getT_date());
temp.setT_status(c.getT_status());
temp.setT_ticket(c.getT_ticket());
temp.setUid(c.getUid());
System.out.println(c.toString());
clicks.add(temp);
}
String json = gson.toJson(clicks, Click.class);
Click.java
#Entity
#Table(name="click")
public class Click {
#Id
#Column(name="t_ticket")
private String t_ticket;
#Column(name="uid",nullable=false)
private long uid;
public long getUid() {
return uid;
}
public void setUid(long uid) {
this.uid = uid;
}
#ManyToOne
#JoinColumn(name="uid",
insertable=false, updatable=false,
nullable=false)
private Earning earning;
#Column(name="store_name")
private String store_name;
#Column(name="t_status")
private String t_status;
#Column(name="aff_source")
private String aff_source;
#Column(name="com_to_recieve")
private float com_to_recieve;
#Column(name="t_date")
private Date t_date;
#Column(name="cb_to_award")
private float cb_to_award;
#Column(name="cb_type")
private String cb_type;
public String getT_ticket() {
return t_ticket;
}
public void setT_ticket(String t_ticket) {
this.t_ticket = t_ticket;
}
public Earning getEarning() {
return earning;
}
public void setEarning(Earning earning) {
this.earning = earning;
}
public String getStore_name() {
return store_name;
}
public void setStore_name(String store_name) {
this.store_name = store_name;
}
public String getT_status() {
return t_status;
}
public void setT_status(String t_status) {
this.t_status = t_status;
}
public String getAff_source() {
return aff_source;
}
public void setAff_source(String aff_source) {
this.aff_source = aff_source;
}
public float getCom_to_recieve() {
return com_to_recieve;
}
public void setCom_to_recieve(float com_to_recieve) {
this.com_to_recieve = com_to_recieve;
}
public Date getT_date() {
return t_date;
}
public void setT_date(Date t_date) {
this.t_date = t_date;
}
public float getCb_to_award() {
return cb_to_award;
}
public void setCb_to_award(float cb_to_award) {
this.cb_to_award = cb_to_award;
}
public String getCb_type() {
return cb_type;
}
public void setCb_type(String cb_type) {
this.cb_type = cb_type;
}
Any Help is appreciated.
You need to implement a toString method, as your current Click class likely doesn't have one, so it just prints as the name of the class and instance identifier.
Okay, I could solve my problem finally.
I made another POJO without any annotations and Mapped the List items to that POJO class.
I think the problem was with Annotation of mapping on another class which I had in original POJO.
Also getString() method only helps in changing format of identifier. So basically it has nothing to do with JSON building unless you format getString() in form of JSON.
Hope it helps. If anyone wants new temp POJO I made I can post it if requested.
Thanks.
I am working on a project ( I had a problem yesterday and so many people helped me!) so I decided to ask for help again.
My code has 3 classes. ProjectMain,Students,Classroom. I created an array of Classroom objects. Right now I have 3 Classroom objects. But I have to assign student objects to these Classroom objects. For example : classarray[0] is an object from Classroom class and studentobject.get(0) , studentobject.get(1) ... will be students objects inside classarray[0] object. But I have failed on this while coding. Here are my classes :
public class Classroom
{
private String classname;
private String word[] = null;
protected ArrayList<Students> studentobject = new ArrayList<Students>(10);
public String[] getWord()
{
return word;
}
public void setWord(String[] word)
{
this.word = word;
}
public ArrayList<Students> getStudentobject()
{
return studentobject;
}
public void setStudentobject(ArrayList<Students> studentobject)
{
this.studentobject = studentobject;
}
public String getClassname()
{
return classname;
}
public void setClassname(String classname)
{
this.classname = classname;
}
public void classroomreader(String filename)
{
// This method gets the name of Classroom
File text = new File("C:/Users/Lab/Desktop/classlists/" + filename
+ ".txt");
Scanner scan;
try
{
scan = new Scanner(text);
String line = scan.nextLine();
word = line.split("\t");
line = scan.nextLine();
word = line.split("\t");
} catch (FileNotFoundException e1)
{
e1.printStackTrace();
}
}
}
This is my student class :
public class Students extends Classroom
{
private String name,id;
private int age;
public String getName()
{
return name;
}
public void setName(String name)
{
this.name = name;
}
public String getId()
{
return id;
}
public void setId(String id)
{
this.id = id;
}
public int getAge()
{
return age;
}
public void setAge(int age)
{
this.age = age;
}
And my main class :
public class ProjectMain
{
public static void main(String[] args)
{
Classroom[] classarray = new Classroom[3];
//I got 3 Classroom objects here
classarray[0]=new Classroom();
classarray[1]=new Classroom();
classarray[2]=new Classroom();
classarray[0].classroomreader("class1");
classarray[0].studentobject.get(0).setName(classarray[0].getWord()[1]);
//The problem is in here. When my code comes to the line above,
// at java.util.ArrayList.rangeCheck(Unknown Source) error comes out.
// I tried to get first object in studentobject Arraylist, and tried to set it's name
// to the variable which my text reader reads.
How can I write what I have in my mind?
Your classroomreader method reads the file but don't do much of it... maybe you want to create some instance of Students within it.
scan = new Scanner(text);
String line = scan.nextLine();
word = line.split("\t"); // won't be used
line = scan.nextLine();
word = line.split("\t"); // erased here
There you only have the last line (split) of the file in word attribute.
When creating Classroom instance studentobject list is created empty and it stays that way so you can't access first (or any) object in it.
To populate your list you may add to Classroom method like this:
public void addStudent(Student s)
{
studentobject.add(s);
}
classroom contains the following field declaration
String word[] = null;
the main class, incl the classroomreader does not set a value to this field. Yet you are going to invoke
classarray[0].getWord()[1]
which then must fail.
tip: don't use expressions like this, which can be found in your main class (at least not in early stages of development, or learning)
classarray[0].studentobject.get(0).setName(classarray[0].getWord()[1]);
resolve into variables and several steps. Compilers are smart enough to produce the same code if the context is not disturbed, ie the long expression is resolved into a single block.
Never forget that the purpose of programming languages is to make programs readable for humans. :) Code with abbreviations or "tricks" simply shows some philodoxical attitude (imho)
Hi I'm having some trouble getting started with a problem in a Java course learning Swing and starting on JTables and getting data into them. It's going to be hard to explain so I'm just going to post the code I was given, along with the question.
The question is:
The getData() method needs to return an Object[][] containing the data represented by the class.
The first class is MusicAlbum
class MusicAlbum {
private String id;
private String name;
private String genre;
private boolean isCompilation;
private int track_count;
public MusicAlbum(String id, String name, String genre, boolean isCompilation, int track_count) {
this.id = id;
this.name = name;
this.genre = genre;
this.isCompilation = isCompilation;
this.track_count = track_count;
}
public String getId() {
return id;
}
public String getName() {
return name;
}
public String getGenre() {
return genre;
}
public boolean isCompilation() {
return isCompilation;
}
public int getTrackCount() {
return track_count;
}
public boolean equals(Object obj) {
if (obj instanceof MusicAlbum)
return this.id.equalsIgnoreCase(((MusicAlbum)obj).id);
return super.equals(obj);
}
}
The class I have to implement the methods in is MusicDataObject (at the bottom)
import java.util.Random;
import java.util.Scanner;
public class MusicDataObject {
private List<MusicAlbum> albums = new ArrayList<>();
private Random random = new Random(); // for generating IDs
public void addAlbum(MusicAlbum album) throws IllegalArgumentException {
if (searchAlbum(album.getId()) != null)
throw new IllegalArgumentException("Album ID is not new!");
albums.add(album);
}
public MusicAlbum searchAlbum(String id) {
for (MusicAlbum album : albums) {
if (album.getId().equalsIgnoreCase(id)) {
return album;
}
}
return null;
}
public MusicAlbum removeAlbum(String id) {
MusicAlbum album = searchAlbum(id);
albums.remove(album);
return album;
}
public void updateAlbum(MusicAlbum album)
throws IllegalArgumentException {
if (removeAlbum(album.getId()) == null)
throw new IllegalArgumentException("Album ID does not exist!");
addAlbum(album);
}
public String generateID() {
String formatter = "A%0" + (int)Math.ceil(Math.log10(albums.size() * 2) + 1) + "d";
String ID;
do {
ID = String.format(formatter, random.nextInt(albums.size() * 2 + 1));
} while (searchAlbum(ID) != null);
return ID;
}
public void saveData(String fileName) throws IOException {
// make sure that the file exists or try to create it
File fout = new File(fileName);
if (!fout.exists() && !fout.createNewFile())
return;
PrintWriter out = new PrintWriter(fout);
for (MusicAlbum album: albums) {
out.println(serializeAlbum(album));
}
out.close();
}
public String serializeAlbum(MusicAlbum album) {
return String.format(
"%s;%s;%s;%b;%d",
album.getId(),
album.getName(),
album.getGenre(),
album.isCompilation(),
album.getTrackCount());
}
public void loadFile(String fileName) throws FileNotFoundException {
albums = new ArrayList<>();
Scanner in = new Scanner(new File(fileName));
while (in.hasNext()) {
// --- split the next line with the character ";"
String line = in.nextLine();
String[] tokens = line.split(";");
// --- construct a new MusicAlbum using the resulting tokens. NOTE: This isn't very robust.
// If a line doesn't contain enough data or the data is invalid, this will crash
albums.add(new MusicAlbum(
tokens[0],
tokens[1],
tokens[2],
Boolean.parseBoolean(tokens[3]),
Integer.parseInt(tokens[4])
));
}
}
// ----- these methods need to be implemented
public Object[][] getData() {
// TODO
}
public String[] getColumnNames() {
// TODO
}
}
The sample data being used is in a txt file, formatted as so:
A01;Defiance;Soundtrack;true;24
A02;Insomniac;Punk Rock;false;14
A03;A Great Day For The Race;Gypsy Jazz;false;10
A04;Viva La Internet;Ska;false;31
A05;New Surrender;Rock;false;17
So basically it's this getData() method they want me to implement that is giving me grief. I don't fully understand what they want me to do, nor do I fully understand what the Object[][] does.
I hope I have been clear enough, and I will appreciate all help given. Also please try to explain things as best you can and dumb them down as much as possible, I'm new to a lot of this :)
Thanks for your time.
Object[][] is a 2-dimensional array. Each of its element is an Object[], a one-dimensional array.
Your task is to create a 2 dimensional array, having one element (Object[]) for each of your MusicAlbum. An Object[] should hold the properties of a MusicAlbum like id, name, genre, isCompilation and track_count.
You can create an object array like this:
Object[] arr = new Object[] { "some", "values", 23, true };
You can create a 2 dimensional array like this:
Object[][] arr2d = new Object[size][];
And you can iterate over all your MusicAlbums, create an Object[] for each of them containing the properties of that music album, and set it in the arr2d.
You can set/get elements of a 2-dimensional array just like any other arrays:
// Set first element:
arr2d[0] = arr;
// Get first element:
Object[] firstElement = arr2d[0];
The getColumnNames() method should just return a String[] (a String array) containing the column names, the names of the properties.
And it might be obvious but note that the order you return the column names and the order of the property values (in the elements of the Object[]) should be the same.
I have created a database and every entry from the JList will be added to a table in the database. This work perfectly, but my next task is to get whatever is in the database to load to the JList. I have a function created within the button but it brings up errors. I'm struggling with how to fix this so I hope somebody can resolve it.
Thanks
Here is my code:
JButton btnDb1 = new JButton("J");
btnDb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
try {
ResultSet rs = st.executeQuery("SELECT * FROM patient");
while (rs.next()) {
Patient patient = new Patient(patientname, patientaddress, patientphone, patientid);
patient.setName(rs.getString("patientname"));
patient.setAddress(rs.getString("patientaddress"));
patient.setPhoneNum(rs.getString("patientphone"));
patient.setID(rs.getInt("patientid"));
MainDentist.model.addElement(patient);
}
} catch (Exception e) {
System.out.println(" Error ");
}
}
});
btnDb1.setBounds(200, 393, 120, 23);
contentPane.add(btnDb1);
Here is my patient class:
public class Patient {
public String patientName;
public String patientAddress;
public String patientPhone;
public int patientID;
public Patient(String patientname, String patientaddress, String patientphone,int patientid){
patientName = patientname;
patientAddress = patientaddress;
patientPhone = patientphone;
patientID = patientid;
}
public String setName(String patientname){
return patientName = patientname;
}
public String getName(){
return patientName;
}
public String setAddress(String patientaddress){
return patientAddress = patientaddress;
}
public String getAddress(){
return patientAddress;
}
public String setPhoneNum(String patientphone){
return patientPhone = patientphone;
}
public String getPhoneNum(){
return patientPhone;
}
public int setID(int patientid){
return patientID = patientid;
}
public int getID(){
return patientID;
}
public String toString() { // Printing the patient's details to the scroll pane
return "Patient Name: " + patientName + ", PatientAddress: "
+ patientAddress + ", PatientPhone: " + patientPhone
+ ", patientID: " + patientID +"" ;
}
}
Let me rephrase the actionlistener – posting code in comments isn't really helpfull :)
First I would put the code from your actionPerformed method somewhere else, best would be even to create some class that handles the whole reading and maybe writing of the database. That way you don't mix reading the database with pushing buttons (maybe you want to create another button that reads the database, too. Then you don't have to write all the code again). Anyway, this is an example:
JButton btnDb1 = new JButton("J");
btnDb1.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent arg0) {
readDatabase();
}
});
public void onActionPerformed(){
try {
// I don't know where you have that part of code, but you didn't create any statement variable. So here an example DB-connection:
String url = "jdbc:mysql://localhost/myDatabase";
Connection connection = DriverManager.getConnection(url, "username", "password");
Statement statement = connection.createStatement();
ResultSet rs = statement.executeQuery("SELECT * FROM patient");
while (rs.next()) {
// read the columns one by one, that way it may be easier to detect errors if one column is wrong
String name = rs.getString("patientname");
String address = rs.getString("patientaddress");
String phone = rs.getString("patientphone");
int id = rs.getInt("patientid");
// now that you have all values, create the patient and add it to the model
// if you have all parameters for the constructor, you don't need to use the setters to set the name and address …
MainDentist.model.addElement(new Patient(name, address, phone, id));
}
} catch (Exception e) {
// as JB Nizet suggested, it is easier to detect errors, when you print the whole stack trace (it will tell you in which line the exception gets thrown
e.printStackTrace();
}
}
This still may not work right away, if you get errors, edit your post and tell us what goes wrong. BTW: I noticed that you have your variables name, address and all this in the patient set to public. This isn't wrong but it is recommended to use getter and setters (as you do) and make the variables private. That way you can control how the variables get accessed from outside.