Calling drawing on JFrame from another class - java

I've got a class in which there is a method that draws rectangles on a JFrame. Furthermore I've got a few methods with different types of sorting. In those sorting methods I am calling the drawing method when a specified button is clicked. I would like my code to be cleaner, so I wanted to divide the class into one that is responsible for drawing things and the other one that does the sorting. I don't know how I can call the drawing method from outside the class. I wanted to use static, but I would have to make all the variables inside the method static. I also thought about making an inner class, but I will still have that one big class and it doesn't really help. What can I do?

You should only be drawing from within the paintComponents method of the container. So it doesn't make sense for some external code to initiate a call to draw stuff. If you want this external class to change what is drawn, it should pass a reference to an object implementing some understood interface that can be called by the paintComponents method.

Related

How to update a panel which shows details of an object

I have a panel, let's call it detailsPanel, which holds a Person reference and displays its field values in the following manner:
Name: person.getName ();
Surname: person.getSurname ();
Emain: person.getEmail ();
.... .......
.... .......
And so on. I will use JLabels (correctly aligned using a GridBagLayout) to show each (fieldName, fieldValue). I have a lot of fields to display.
The problem is that the panel which shows the details must be always visible, i.e it will not be shown in a modal JDialog, so that i could create the panel by simply reading my Person object fields at the panel creation.
The panel must always be visible, and its Person reference will change when the user selects a different row in a Person list. This means i will call a method to update its state, something like:
detailsPanel.setPerson (aPerson);
Now, i'm wondering how i should update all the fields. Should i keep a reference to all the JLabels which show the values, and use setText(value) on each of them when i update the panel, or would it be better to override getText() method for every label, returning the correct field value, so that in the update method i would only repaint the panel, and the text would automatically change when the getter method is used on a different Person object?
Any suggestion is appreciated!
Since this is UI stuff which is usually called almost never (relative to how often things are called in other computation) you don't need to worry about efficiency at all. Just do what you think is the most elegant solution. There are three options That quickly come to my mind. They are ordered from quick and static to elegant and reusable:
Quick and dirty: create your constructor and make everything look nice. Then move everything from the constructor to a separate init() method and every time the entities change, you just call removeAll(); and then init() again.
As you suggested, keep a reference to all labels and use the setPerson() method to update all panels. Then call this method in the constructor (this is arguably the most common solution).
As you suggested, build your own extension of JLabel. This new class should either have an update() method which is to be called when things change, or have it set its own listeners to ensure that it gets notified of any relevant change.
If you are planning to create a single panel which is supposed to display all kinds of objects, you could have those object implement an interface called Displayable which gives you generic access to all its values and maybe even listeners to each value. An alternative to the Displayable interface is to use reflection and use annotations to allow the panel to get its values for display.
Please note that the most elegant solution is - contrary to what some people may tell you - not always the best for any situation. How much maintenance do you expect there to be in the future? How big is the application? Will you ever hand off the code to someone else? All these and more need to be considered to decide how "nice" you want your solution to be.

How often to pass an object or variable through methods in Java?

I am new to stackoverflow and am sorry, if this question was already asked, but when I searched for one containing my problem, I could not find one.
Here is my question:
In Java I am creating a game (just for fun and am learning to code). You start my game with a launcher to log in. However, if you do not have an account, you can register. What I like more is to use one frame. I have a panel containing the launcher elements and one containing the register elements. I am trying to learn how to code, if another one is working on my project, he does not necessarily need to look all over the code to do some work. In other words, I am using packages to sort classes. Example: Classes for the launcher are in package Launcher. Classes for register are in package register.
In my code, I have a class called Display extending JFrame. Display is instanciated in the class with the main method. Display has 2 Methods for removing a panel and adding a panel, requiring you to pass a JPanel, if you use any of both methods. After Display is instantiated, it instantiates a jpanel inside the constructor. This has all the components to Display. The event listeners are in another class. So I am passing the buttons and Display to that class, because here is the eventlistener code for the button register. In my register class I have defined and instantiated all necessary components. I passed the display through all of the classes until it reached the register class which extends jpanel. I even passed the Launcher class. Now i can use the methods in display to remove the launcher panel and add my register panel.
My Question:
is this good code or overkill?
I never instantiated Display after the main method again. I always declared it and set it to the passed display. I did this, because instantiated a new Display would mean unnecessary use of memory and passing objects in java is actually a passing by references, meaning it is not passing the object but a pointer to the object. So this would mean less memory usage.

How do I run this 3D Java Application?

I'm quite new at this stuff so sorry by my noob question
So, I'm trying to run this code on netbeans https://github.com/rukayam/Cube but it doesn't have an main class, so I created one but the problem is, the class that contains the panel and the paint method is abstract (the Canvas.java) and I can't instantiate an abstract class... What should I do?
(from what I know about painting in Java, one should call/instantiate the class/object that contains the Panel/JPanel and the paint or paintComponent methods)
Thanks in advance!
What Stephen C says is true: You could instantiate Lec04 which has all properties and every method except void render() inherited, and void render() implemented inside of it.

How to access local variables in anonymous inner actionListener class and actionPerformed method?

I am working on a project for a CS class, so I cannot post any code, but I will try my best to describe what setup I have. The program is supposed to have 3 separate JPanels, each with an image and buttons to rotate and reset the image. A Driver class was provided that sets up the JFrame, creates a single Project object to pass around to other classes (this Project class contains the methods for rotating and combining the images), and has the main method.
What I've done is create a class that extends JPanel to setup a JPanel with the image, file name, and rotate/reset buttons. I have the constructor for this class taking in the number of the panel (to keep up with writing the image number in the panel), the image file to display, and the Project object that was created in the Driver class (to be able to access the methods for manipulating the images). I immediately call super(); and then set up the file name and image (as a JLabel) and buttons as (JButtons).
This is where my problem comes in though. I'm trying to set up the Rotate button, so I created an anonymous inner class action listener and actionPerformed method. What I planned on doing was using the Project object reference to call the rotate method on the image object, having it return a BufferedImage into a modifiedImage BufferedImage. Then remove the JLabel with the original image, add the modifiedImage as a JLabel, revalidate, and repaint. However, I cannot use the this reference or the reference to the Project object within the inner actionPerformed class.
How do I gain access to these references within the actionperformed inner class? or is my setup completely awful? Please bear with me- it's my first time working with any kind of GUI.
Make your reference to Project object final. It will solve the problem and does not make any harm as you are not going to assign it again.

JFrame cannot find 'pack' method

I'm taking a beginning Java class and an assignment requires that I write a class to represent a JPanel with buttons to increment and decrement a value and a label to display the value. Then, I have to create a separate class which instantiates the panel and adds it to a frame. I'm trying to have the frame resize to fit the size of the panel by running the pack method. I try to call the frame's pack method by using:
SwingUtilities.getAncestorOfClass(JFrame.class, this).pack()
I get a "cannot find symbol - method pack()" error. The getAncestorOfClass is definitely returning a JFrame, and it is the correct JFrame. When I run the pack method from inside the driver class where the JFrame is created, there are no problems. Any ideas why it can't find the pack method? Is it because I'm trying to run this from a separate class file? I also can't access some other JFrame methods such as getContentPane, but I am able to access some others such as add. Huh?
The method SwingUtilities.getAncestorOfClass returns a Container. Now, you know that Container is really gonna be a JFrame, but the compiler doesn't. And Java is a static language, not a dynamic one that'll just try to call the method regardless of whether the class declares it or not.
Since Container doesn't have pack method, the compiler's gonna complain. You'll need to cast to JFrame to make it work:
((JFrame)SwingUtilities.getAncestorOfClass(JFrame.class, this)).pack();
Careful, though... The method can return null if no suitable ancestor was found. You might want to check that first.
You need to cast it to JFrame:
((JFrame) SwingUtilities.getAncestorOfClass(JFrame.class, this)).pack();
The SwingUtilities.getAncestorOfClass(Class, Component) method return a component, and not a JFrame.

Categories