Java logic in my code - java

Okay, so I have this code below and I keep getting run-time errors and I'm thinking its a flaw in the codes logic. I'm trying to use the setOneOtherPicture method to pick a picture and set it into an array to be later called on to be displayed in the showArtCollection method. I've been given two parameters, which and pRef. Can someone help me with this? Thanks.
public class House
{
String owner;
Picture pRef;
Picture favPic;
Picture [] picArray = new Picture [3];
public void showArtCollection ()
{
ArtWall aWall = new ArtWall(600,600);
aWall.copyPictureIntoWhere(favPic,250,100);
aWall.copyPictureIntoWhere(pRef,51,330);
aWall.copyPictureIntoWhere(pRef,151,330);
aWall.copyPictureIntoWhere(pRef,351,280);
aWall.show();
}
public void setOneOtherPicture (int which, Picture pRef)
{
this.picArray [which] = new Picture (FileChooser.pickAFile ());
}
public static void main (String [] args)
{
House PhDsHouse = new House ("Mad PH.D.");
Picture favPic = new Picture ();
Picture pRef = new Picture ();
PhDsHouse.setOneOtherPicture (0, pRef);
PhDsHouse.setOneOtherPicture (1, pRef);
PhDsHouse.setOneOtherPicture (2,pRef);
PhDsHouse.showArtCollection ();
}

Your House class has several fields, and your main method has local variables with the same names. Perhaps these should be sent into the constructor? Otherwise, these fields are null, which causes the crash in the showArtHouse method.

this method:
public void setOneOtherPicture (int which, Picture pRef)
{
this.picArray [which] = new Picture (FileChooser.pickAFile ());
}
shouldn't be calling FileChooser, and it shouldn't even be creating a new Picture object, but instead should just be putting pRef Picture object that you already have passed into the method into the array. Otherwise you're just throwing the pRef parameter away -- makes no sense.

Related

How do I make multiple JButtons that work individually through instantiating the class?

I am just a beginner in java programming, and I got confused in class. Our assignment was to make 3 jButtons, and when you click on them, a gif appears. Our teacher said that we have to show the instantiation of 3 objects, each one controlling one button. Please help me; I am so confused!
This is part of my code (the image Icon part)
public void addButtonsToContentPanel() {
ImageIcon frog = new ImageIcon("frog.gif");
ImageIcon buffalo = new ImageIcon("buffalo.gif");
fancyButton1 = new JButton("Fancy Button", frog);
fancyButton1.setRolloverIcon(buffalo);
p.add(fancyButton1);
fancyButton1.addActionListener(this);
}
^^ how do I make the code above so that fancyButton1 is linked with the instantiation of a class? Sorry If what I'm saying doesn't make sense; I wasn't sure how to word it.
fancyButton1 = new ImageButton()
By calling new ImageButton(), you are instantiating a new object of the class ImageButton.
I am unsure quite what you are being asked to do. The following is code which instantiates three buttons:
ImageButton fancyButton1 = new ImageButton()
ImageButton fancyButton2 = new ImageButton()
ImageButton fancyButton3 = new ImageButton()
The other thing that you may be being asked to do, is to define the Cyberpet class so that it can create its own JButton, something along the following lines:
class CyberPet {
private String name;
private ImageIcon imgIcon;
private ImageIcon rolloverImgIcon;
// Initialiser
Cyberpet(String name, String pathToImgIcon, String pathToRolloverImgIcon) {
this.name = name;
this.imgIcon = new ImageIcon(pathToImgIcon);
this.rolloverImgIcon = new ImageIcon(pathToRolloverImgIcon);
}
public JButton createButton() {
JButton btn = new JButton(this.name, this.imgIcon);
btn.setRolloverIcon(this.rolloverImgIcon);
}
}
public void addButtonsToContentPanel() {
Cyberpet frog = new Cyberpet("frog.gif", "buffalo.gif");
fancyButton1 = frog.createButton();
fancyButton1.addActionListener(this);
}
Hope this helps. If I have misinterpreted the question then please let me know and I will try to provide a better answer.

INRIA SPOON INNER METHODS CALLING CONSTRUCTORS

I am trying to extract the calls from the method run() to the constructors. Here is the code I am trying to parse
SwingUtilities.invokeLater(new Runnable() {
public void run() {
// Create the two text areas
TextAreaFigure ta = new TextAreaFigure();
ta.setBounds(new Point2D.Double(10,10),new Point2D.Double(100,100));
TextAreaFigure tb = new TextAreaFigure();
tb.setBounds(new Point2D.Double(210,110),new Point2D.Double(300,200));
// Create an elbow connection
ConnectionFigure cf = new LineConnectionFigure();
cf.setLiner(new ElbowLiner());
// Connect the figures
cf.setStartConnector(ta.findConnector(Geom.center(ta.getBounds()), cf));
cf.setEndConnector(tb.findConnector(Geom.center(tb.getBounds()), cf));
// Add all figures to a drawing
Drawing drawing = new DefaultDrawing();
drawing.add(ta);
drawing.add(tb);
drawing.add(cf);
// Show the drawing
JFrame f = new JFrame("My Drawing");
f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f.setSize(400,300);
DrawingView view = new DefaultDrawingView();
view.setDrawing(drawing);
f.getContentPane().add(view.getComponent());
f.setVisible(true);
}
});
}
Here is the code I am using to extract the calls from method run() to the constructors. The problem that I have is that the last line: String constructorClassName= cons.getExecutable().getDeclaringType().toString(); is returning the wrong class name, instead of getting "jhot.draw.TextAreaFigure()" as the name I am getting "jhot.mini.samples.TextAreaFigure()". The file that I am parsing is located under "jhot.mini.samples" while the constructor is declared within "jhot.draw.TextAreaFigure()". I am not sure if this is a bug in spoon or if I am using the wrong API to retrieve the constructor calls.
for(CtMethod<?> method :clazz.getMethods()) {
List<CtConstructorCall> ctNewClasses = method.getElements(new TypeFilter<CtConstructorCall>(CtConstructorCall.class));
for( CtConstructorCall myclass: ctNewClasses) {
//CONSTRUCTOR
if(myclass instanceof CtConstructorCall<?>) {
System.out.println("yes");
List<CtMethod> methoddeclared = myclass.getElements(new TypeFilter<CtMethod>(CtMethod.class));
for(CtMethod<?> meth: methoddeclared) {
methodinside=meth.getSignature();
methodinsideclass=clazz.getQualifiedName();
String mymethod=methodinsideclass+"."+methodinside;
ResultSet methodsinside = st.executeQuery("SELECT methods.* from methods where methods.fullmethod='"+mymethod+"'");
//while(callingmethodsrefined.next()){
if(methodsinside.next()) {
MethodIDINSIDE = methodsinside.getString("id");
CLASSNAMEINSIDE = methodsinside.getString("classname");
CLASSIDINSIDE = methodsinside.getString("classid");
//System.out.println("CALLEE METHOD ID: "+ CALLEEID);
}
List<CtConstructorCall> constructors = meth.getElements(new TypeFilter<CtConstructorCall>(CtConstructorCall.class));
for(CtConstructorCall<?> cons: constructors) {
String constructorClassName= cons.getExecutable().getDeclaringType().toString();
}
}
}
}
I am not sure if this is a bug in spoon or if I am using the wrong API to retrieve the constructor calls.
I'm one of the contributor of Spoon. It looks to me that you're using the right API, but I'm not sure because your example looks a bit messy here.
I think it would be easier if you open an issue on Spoon Github repository and specify:
the project you're working on if it's open-source
how you launch Spoon (the version of Spoon, arguments, etc)
what do you expect exactly
Then we could investigate to check exactly what happens there. Thanks!

How to transport information from one class to another in order to show it without using static?

I am programming an application that deals with orders from a database. It has several pages, a navigation, a header that always should show information about the actual order you are working with and a content area, in which the details of said order get shown:
My MainProgram extends a JFrame and contains a CardLayout, in which the other pages are hosted, so when the user clicks on the page in the navigation, only the view of the content-area changes. Logo, header and the navigation stay the same. The header keeps displaying the order number.
As there are several different pages that contain details about the same order, I need to "send / transfer" information about the order from one page to the other so I can show some information in the header and in the content area from the order object.
But I am not getting this to work as intended, mostly to my misunderstand of static and when to use it, where objects get created exactly and also the complexity of my program: I am using a class that is intended for the navigation and therefore should also handle
the information transfer from one page to the other.
Since I am using a database, creating a MVCE will be hard, so instead I will show the important parts of my program.
MainProgram.java
Here the navigation and the content panel (centerPanel) get created, also the CardLayout. centerPanel and the CardLayout are static, so I can call this from other classes and switch the page that is shown (probably not a good idea?):
NavigationPanel navigationPanel = new NavigationPanel();
public static JPanel centerPanel = new JPanel();
public static CardLayout contentCardsLayout = new CardLayout();
I create the pages and put them into my CardLayout:
OverviewPage overviewPage = new OverviewPage();
BasicDataPage basicDataPage = new BasicDataPage();
centerPanel.setLayout(contentCardsLayout);
overviewPage.setName("overviewPage");
basicDataPage.setName("basicDataPage");
centerPanel.add(overviewPage, "overviewPage");
centerPanel.add(basicDataPage, "basicDataPage");
The main method, where I create a MainProgram object:
public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {
public void run() {
try {
UIManager.setLookAndFeel("com.sun.java.swing.plaf.nimbus.NimbusLookAndFeel");
MainProgram window = new MainProgram();
window.setVisible(true);
window.initialize();
} catch (Exception e) {
e.printStackTrace();
}
}
});
}
OverviewPage.java
The overview page contains a JTable which gets populated from a database. If the user double-clicks an entry, he gets transfered to the BasicDataPage where he can see the details of the order.
But in order to show the details, I need to somehow transfer the information of the order object into the target class and thats the point I am struggling with!
// I tried several things like object into constructor, static object, creating a method etc...
if (mouseEvent.getClickCount() == 2 && row != -1) {
String workNumberOfOrderObject = (String) table.getValueAt(row, 0);
OrderObject orderObject = GetOrderObject.getOrderObjectFromDatabase(workNumberOfOrderObject);
BasicDataPage basicDataPage = new BasicDataPage();
basicDataPage.recieveOrderObject(orderObject);
workNumberPanel.recieveOrderObject(orderObject);
workNumberPanel.setTxtWorkNumber(workNumberOfOrderObject);
MainProgram.contentCardsLayout.show(MainProgram.centerPanel, "basicDataPage");
}
I tried "sending" the order object to the BasicDataPage via the constructor and set the text in the JTextFields in the BasicDataPage accordingly. This did not work, the textfields simply stayed empty altough I can System.out.println(orderObject.toString()) the recieved object.
BasicDataPage.java
I also tried creating a method receiveOrderObject that I use in the OverviewPage, which should set the textfields of the basicDataPage AND the workNumberPanel, but the fields stay empty:
WorkNumberPanel workNumberPanel = new WorkNumberPanel();
JTextField txtCarWidth = new JTextField(TEXTFIELD_LENGTH);
JTextField txtCarDepth = new JTextField(TEXTFIELD_LENGTH);
JTextField txtCarHeight = new JTextField(TEXTFIELD_LENGTH);
public void recieveOrderObject(OrderObject orderObject){
txtCarDepth.setText(orderObject.getCar_depth());
}
Before posting my question I've read several Q/As here on SO like this:
Accessing UUID from another class in Java ... suggesting to use static for global variables.
I know that static variables are class variables, that all instances can use and only one version exists of. So I tried to send a static object from one class to the other.
But since I am using JTextFields, I had to mix static and non-static content, which either did not work at all or the textfields disappeared.
I have the feeling that I am getting a very basic concept in java wrong, so any help, no matter in which direction, is appreciated!
EDIT:
Based on Reşit Dönüks answer, I was able to fill the textfields by making BasicDataPage and loadBasicData(orderObject) in MainProgram static. Now I can do MainProgram.loadBasicData(orderObject); ... and the textfields in the BasicDataPage get filled as intended.
Is this a valid approach or do I get problems for using static for GUI-Elements? ..... Don't!
I realized that, your are creating BasicDataPage in each double click.
if (mouseEvent.getClickCount() == 2 && row != -1) {
String workNumberOfOrderObject = (String) table.getValueAt(row, 0);
OrderObject orderObject = GetOrderObject.getOrderObjectFromDatabase(workNumberOfOrderObject);
BasicDataPage basicDataPage = new BasicDataPage();
This is the main problem. Do not create BasicDataPage there, just reach the created instance and set the order object to that. My solution is below.
public class MainProgram implements OrderView{
//remove statics here
private JPanel centerPanel = new JPanel();
private CardLayout contentCardsLayout = new CardLayout();
private BasicDataPage basicPage;
public MainProgram() {
//other codes
OverviewPage overviewPage = new OverviewPage();
basicPage = new BasicDataPage();
centerPanel.setLayout(contentCardsLayout);
overviewPage.setName("overviewPage");
basicDataPage.setName("basicDataPage");
centerPanel.add(overviewPage, "overviewPage");
centerPanel.add(basicPage, "basicDataPage");
//oher codes
}
#Override
public void loadOrder(OrderObject order) {
basicPage.recieveOrderObject(orderObject);
contentCardsLayout.show(centerPanel, "basicDataPage");
}
}
public interface OrderView {
public void loadOrder(OrderObject order);
}
public class OverviewPage {
OrderView orderView;
public OverviewPage(OrderView orderView) {
this.orderView = orderView;
}
//in ActionPerformed
if (mouseEvent.getClickCount() == 2 && row != -1) {
String workNumberOfOrderObject = (String) table.getValueAt(row, 0);
OrderObject orderObject = GetOrderObject.getOrderObjectFromDatabase(workNumberOfOrderObject);
orderView.loadOrder(orderObject);
workNumberPanel.recieveOrderObject(orderObject);
workNumberPanel.setTxtWorkNumber(workNumberOfOrderObject);
}
}
As pointed already, Singleton is the way to go. I would just like to point out a mistake in the code provided in the answer before.
private static MainFrameinstance = null;
Rename MainFrameinstance to instance or vice-versa; because the same variable is checked by the getInstance() method.

How to: Make addition to class property within list

I have a List<Presenter> presenterList;
With
public class Presenter(){
String name;
String imageRef; // Filename to be downloaded
Bitmap image;
(etc...)
}
I'm working with AsyncTask & once the image has downloaded, I wish to go through the list and set Image value to the newly download image.
so far i have
Presenter pres = PresenterList.get(Position);
pres.Image = new (Bitmap) downloadedImageFromImageRef;
however i fear that this will not relate to the Image value of the presenter within the list.
How do i refer, or even assign to the specific Presenter attribute within the list?
From working with C (many years ago), i belive somthing like a pointer to the value in which to assign .Image would work
Thank you in advace
Well, if you have C experience, then the thing to know about Java is that it doesn't use pointers, but it does use references. So if I'm understanding your problem correctly, you are already using the Image attribute of a Presenter instance elsewhere and then you want to fill it in later. Assigning pres.Image = new (Bitmap) DownloadedImageFromImageRef; would not work in this case because other objects are looking at a different Bitmap object reference.
What you might need to do is use an observer pattern -- it depends on the details of your problem. Here's an example:
Somewhere in the code I have a class Foo that wants to use the Image property from a Presenter instance. But, since that property isn't set until later, this class wants to be notified when it is ready (it is an observer).
public class Presenter {
String Name;
String ImageRef; // Filename to be downloaded
private Bitmap Image;
private PresenterImageObserver observer;
public void setImageObeserver(PresenterImageObserver pio) {
this.observer = pio;
}
public void setImage(Bitmap b) {
this.Image = b;
this.observer.imageLoaded(b);
}
}
public interface PresenterImageObserver {
public void imageLoaded(Bitmap b);
}
public class Foo implements PresenterImageObserver {
//Foo's constructor. It wants the image from presenter p, when it is ready
public Foo(Presenter p) {
p.setImageObserver(this);
}
public void imageLoaded(Bitmap b) {
//b contains the loaded image and this Foo instance can use it now!
}
}
You'd need to set the image using pres.setImage(new (Bitmap) downloadedImageFromImageRef);.
So you have to find in your list the Presenter for which the correct imageref. You have basically two options.
First, you simply iterate through your list
for (Presenter presenter: presenterList) {
if (presenter.imageref.equals(imageName) {
Presenter.image = new Bitmap(downloadedImage);
break; // found : stop iterations
}
}
Secondly, you can create a HashMap for your presenters, with the imageref as the key :
HashMap<String, Presenter> map = new HashMap<>();
for (Presenter presenter: presenterList) {
map.put(presenter.imageref, presenter);
}
Then, you can directly find the right presenter through map.get(imageName)

Adding Objects to JFrame from another class?

I'm trying to create a blackjack program for my final project in Java. I'm still very new to Java and OOD so I apologize if my problem seems very trivial to you :(
How my program works: I have three classes so far.
main.java
This class builds my frame and runs all the other methods.
cards.java
This class creates an array that holds the card values and location to picture. I have a for loop in there that auto-populates it.
hits.java
This class is meant to "randomly" generate a number that will represent the chosen card. The way this works is by taking the randomly created int and pointing it to a matching index location on the array.
I assign the value to string objects that I then try to add to a jlabel and then add that jlabel to my main frame. The code is as follows:
hits.java
// Import necessary classes.
import java.util.Random;
public class hits {
// Create random object.
Random rand = new Random();
// Declare variables.
int card;
String cardVal, cardPic;
// Instantiate the needed classes.
main s = new main();
cards t = new cards();
// Constructor for the class.
public hits() {
// Randomly generate a number (0 - 9).
card = rand.nextInt(10);
// Populate the array.
t.runCards();
// Assign the cards according to the num. generated.
cardVal = t.deck[card][0];
cardPic = t.deck[card][1];
}
// Run Method
public void runHits() {
// Add the card chosen to the GUI.
s.a.setText("hello");
s.dealerCards.add(s.a);
}
}
I have "hello" as the text for the label because I wanted to see if perhaps my array was not populating, but even that doesn't work. If it helps here is my main.java as well (constructor and main method):
// Constructor for the main class.
public main() {
// Setup the MAIN container.
f1.getContentPane().setLayout(new GridLayout(0, 1));
f1.setSize(200, 200);
f1.add(dealerName);
f1.add(dealerCards);
f1.add(userCards);
f1.add(userName);
// Setup the inner panels.
dealerCards.setLayout(new GridLayout(1, 2));
dealerCards.add(b);
userCards.setLayout(new GridLayout(1, 6));
userCards.add(c);
userCards.add(d);
}
// Build the frame.
public void GUILaunch() {
// Display Frame
f1.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
f1.setVisible(true);
}
// Main method.
public static void main(String args[]) {
// Distribute the dealer's/player's starting hands.
hits deal = new hits();
deal.runHits();
// Launch the GUI
main gui = new main();
gui.GUILaunch();
}
Hopefully I have provided enough information to help you understand what's going on here. So to sum it all up: how can i add my jlabel(from another class) holding the randomly selected card to my main frame
Thanks in advance.
The deal.runHits() adds a label to the Main object that deal owns rather than the gui object.
I would suggest the following :
Make your main class have an instance of hits and hits have an instance of the cards object...
so you get something like this
public class main {
private hits hits_instance
//constructor
main(){ hits_instance = new hits(); }
//this method will add your cards
public void addCards(){
// frame = whatever frame you are using
frame.add(hits_instance.getCards());
}
}
public class hits {
private cards cards_instance;
hits(){ cards_instance= new cards();}
public JLabel getCards() {return cards_instance.getCard(randomNumber);}
}

Categories