combobox selection won't load/initialize class in a new window - java

SEE UPDATE AT THE BOTTOM!!
I've tried to figured out how to do this for a couple of days but so far I have had no luck.
Basically what I want to do is have a combobox, which when an option is selected loads an applet, and passes a value to the applet.
Here is the code for the ComboBox class, which is supposed to open the other class in a new window. The other class is the main class for an applet. They are both in the same project but in different packages. I know that there aren't any errors with the rest of the code.
//where I evaluate the selection and then open SteadyStateFusionDemo
// more selections just showing one code block
combo.addItemListener(new ItemListener(){
public void itemStateChanged(ItemEvent ie){
String str = (String)combo.getSelectedItem();
if (str.equals("NSTX")) {
machine = "A";
JFrame frame = new JFrame ("MyPanel2");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
SteadyStateFusionDemo d = new SteadyStateFusionDemo();
frame.getContentPane().add (new SteadyStateFusionDemo());
d.init();
frame.pack();
frame.setVisible (true);
And just to cover everything here is the beginning of the init() method of SteadyStateFusionDemo as well as the main method in the class. Too much code to post otherwise. There are several different privates before the init method.
//method that initializes Applet or SteadyStateFusionDemo class
public void init() {
//main method of the SteadyStateFusionDemo class
public static void main (String[] args) {
JFrame frame = new JFrame ("MyPanel");
frame.setDefaultCloseOperation (JFrame.EXIT_ON_CLOSE);
frame.getContentPane().add (new SteadyStateFusionDemo());
frame.pack();
frame.setVisible (true);
What am I doing wrong? Why doesn't my class load?
UPDATED: Changed the code so that a JFrame opens and then the JApplet loads inside. I have successfully done this in a test Java applet but for some odd reason it won't work with this Applet. I even set up the test in a similar way (The code for this is virtually the same, except with different class names, and of course a much, much shorter init() method). Can someone help me figure out why this isn't working? Also, a JFrame will open if I delete the lines referring to SteadyStateFusionDemo, but once I reference it won't work. Why does this happen?

UPDATE:
Based on your feedback, it seems you are trying to achieve the following:
Use the code of an existing Applet (found here) in a Desktop application (i.e. in a JFrame).
Converting an Applet to a Desktop application is an "undertakable" task, the complexity of which depends on how much "Applet-specific" stuff is used by the Applet. It can be as simple as creating a JFrame and adding myFrame.setContentPane(new myApplet().getContentPane()); or as complex as...hell.
This tutorial might be a good place to start.
After taking a look at the Applet at hand, it seems to be fairly easy to convert it. The only complicating factor is the use Applet's methods getCodeBase() and getImage(URL) (somewhere in the code). These two methods result in a NullPointerException if the Applet is not deployed as...an Applet.
So, what you can do is override those two methods in order to return the intended values (without the exception). The code could look like this:
/* Import the necessary Applet entry-point */
import ssfd.SteadyStateFusionDemo;
/* Subclass SSFD to override "problematic" methods */
SteadyStateFusionDemo ssfd = new SteadyStateFusionDemo() {
#Override
public URL getCodeBase() {
/* We don't care about the code-base any more */
return null;
}
#Override
public Image getImage(URL codeBase, String imgPath) {
/* Load and return the specified image */
return Toolkit.getDefaultToolkit().getImage(
this.getClass().getResource("/" + imgPath));
}
};
ssfd.init();
/* Create a JFrame and set the Applet as its ContentPane */
JFrame frame = new JFrame();
frame.setContentPane(ssfd);
/* Configure and show the JFrame */
...
The complete code for an example JFrame Class can be found here.
Of course, you need to have all Classes from the original Applet accessible to your new Class (e.g. put the original Applet in your classpath).

Related

jMenuItem doesn't appear

I've just starting using Java Swing and I have a issue.
I tried to do a simple menuBar and a menuItem 'Exit', but before linking the button to the action the menuItem appeared, now that I've linked the button to a System.exit(0) action it disappeared. Help?
The code is the following:
in MainPanel (the autogenerated code from swing is excluded):
public void init() {
initComponents();
initActions();
setLocationRelativeTo(null);
pack();
setVisible(true);
}
private void initActions() {
this.menuItemExit.setAction(Application.getInstance().getPanelControl().getActionExit());
}
In PanelControl:
public class PanelControl {
private Action actionExit;
public Action getActionExit() {
return actionExit;
}
public class ActionExit extends AbstractAction{
public ActionExit(){
putValue(Action.NAME, "Exit");
putValue(Action.SHORT_DESCRIPTION, "Exit from the application");
putValue(Action.ACCELERATOR_KEY, KeyStroke.getKeyStroke("ctrl e"));
putValue(Action.MNEMONIC_KEY, KeyEvent.VK_E);
}
#Override
public void actionPerformed(ActionEvent e) {
System.exit(0);
}
}
In Application:
private void init() {
viewMainPanel = new MainPanel();
controlPanel = new ControlPanel();
viewMainPanel.init();
}
i think the problem is somewhere in here but i can't figure out where. any help?
(there's other code but i just put the more relevant part, also i translated the code from italian so i'm sorry if there are any problems or a few names dont match up)
private Action actionExit;
public Action getActionExit() {
return actionExit;
}
Your actionExit variable is null.
Nowhere in your code do you create an instance of your ActionExit class.
Somewhere you need:
actionExit = new ActionExit();
Your design seems a bit complicated, I have no idea why you have a panel just to create an instance of the ActionExit class.
I would suggest you just create the ActionExit instance in your main class and get rid of the PanelControl class.
Instead of using an IDE to generate confusing code you should consider learning how to write the code yourself so you can better structure your classes. Read the section from the Swing tutorial on How to Use Menus for a working example to get you started.
A menu item has to be added to a Native Java Swing component. You have to add it to a JFrame. You can't add a MenuItem to a Panel. The Parent 'root' container in any Java Swing application is 'native' and a JFrame. Everything else in that container is 'drawn' into the rectangle using the look and feel of your choosing.
Then you CREATE a MenuItem using your TAbstractAction item. That object CAN be used to create a JButton, JMenuItem or ToolBar button. Keeping a reference to your TAbstractAction in your code, you can enable/disable the object and it implements an 'observable' pattern where it will enable/disable ALL UI controls you used to build with it. I actually wrote a Java Swing framework for doing Java Applications. It used to be on the Sun Open Source web site. If you wish I can put it up on GitLab for you to play with. Java Swing is nice but JavaFX should be the long term goal for UI on a JVM.
In your JFrame object you need to do this:
_menuBar = new JMenuBar();
// add controls to the frame
setJMenuBar(_menuBar);
Then you need to add your 'exitMenuItem' to your _MenuBar control.
Cheers

How can I create and dispose of my forms created with IntelliJ's GUI builder

I have created a form with IntelliJ's GUI builder, it has a working main() method, the form works properly and has some listeners attached.
In addition to that I have a custom class where I want to call that GUI I created with IntelliJ's GUI builder. I can accomplish this by copying the code within the "main" method in the GUI's class and placing it in my custom class and if I run my custom class the form is indeed displayed.
But thats about all I can do with the created GUI, I can only call it. I can't do other things like dispose that GUI form instance (frame.dispose()) and open another form because I don't know how to get access to the frame instance from my custom class.
Can someone please assist me with this? I thought it would save me a lot of time if I used the GUI builder as opposed to writing the GUI code from scratch for several forms.
I solved the problem by creating a method in the GUI form class called load() which contains the JFrame setup
GUI Form Class
public void load()
{
JFrame frame = new JFrame( "Login Form" );
frame.setContentPane( new LoginForm().mainPanel );
frame.setDefaultCloseOperation( WindowConstants.DISPOSE_ON_CLOSE );
frame.pack();
frame.setLocationRelativeTo( null );
frame.setVisible( true );
}
and then in my main class I called it with new LoginForm().load();.
In order to dispose of the initial GUI form and open another one I created a helper method inside the GUI form class called getMainFrame()
private JFrame getMainFrame()
{
return (JFrame) SwingUtilities.getWindowAncestor( this.mainPanel );
}
after that inside the GUI form class constructor there is logic to dispose of the frame when a condition is met
if (age.equals("42"))
{
//load the appropriate form
new MainForm().load();
//dispose of this current form
this.getMainFrame().dispose();
}
First, give a name to your root panel:
Then create a getter for it, and you can use it in a JFrame by
JFrame f = new JFrame();
f.add(new YourGuiClass().getMainPanel());
f.setVisible(true);
When you want to dispose it, dispose the JFrame instance should work.
Edit
You said you want to dispose the JFrame in your GUI form class logic, try this:
class YourGuiClass {
private JFrame f = new JFrame();
private JPanel mainPanel;
public void load() {
f.add(mainPanel);
f.setVisible(true);
}
public void dispose() {
f.dispose();
}
}
By this you can operate the GUI form class without knowing anything related to Swing in the main function:
public static void main(String... args) {
YourGuiClass myGuiClass = new YourGuiClass();
myGuiClass.load(); // it now shows itself
if (someLogic()) myGuiClass.dispose(); // you can
// also call this elsewhere as you like
}

Embed PApplet intp JApplet

How can I embed a PApplet into a JApplet ?
I wanted to add it to a JPanel inside the applet, but I couldn't.
If any of you know how I can do this. ??
As of Processing 3, you can no longer do this. PApplet no longer extends Applet, so it can't be treated as a component.
For 95% of users, this is okay. Applets are dead anyway, so you really shouldn't be using them. If at all possible, you should try deploying with Processing.js.
If you need to execute a Processing sketch from Java code, then you should use the PApplet.main("YourSketchNameHere"); function to launch it. Processing will take care of the window for you.
If you really need to treat a PApplet as a component, then you're going to have to go through its PSurface. The PSurface class contains a getNative() function that returns an object that can be treated as a component. But that's overkill for most Processing users.
Prior to Processing 3, this code should have worked for you as #Kevin has explained. So, if your question is directed towards understanding a legacy code here is what you will need to know:
import javax.swing.JFrame;
import javax.swing.JPanel;
class MyPApplet extends PApplet implements ActionListener{
#Override
public void setup() {
super.setup();
// setup
}
#Override
public void draw() {
// my draw code
}
}
public class PAppletDemo {
public static void main(String[] args) {
final JFrame frame = new JFrame("PApplet in Java Application");
JPanel panel = new JPanel();
//create an instance of your processing applet
final MyPApplet applet = new MyPApplet();
applet.init();
panel.add(applet); // From processing 3, this will give you error that applet is not a Component
frame.add(panel);
frame.setSize(applet.getSize().width, applet.getSize().height +200);
frame.setVisible(true);
}
}
To circumvent this, you will need to use PSurface getNative() function. Please refer to the example and discussion given on this link.

Best practise regarding static context

When writing a standalone java application, I see a lot of beginners code in the static context.
I used to get around this problem by creating an instance of the class in main, and working from the constructor.
I've added a few examples of a very simple standalone program, and would like to know if there are best practises for "leaving" the static context.
I would also like to know if there are things a standalone java program should be doing in the static context or specifically in the main method, what it's function is besides being the entry point of every standalone java program.
Any reading material is also welcome!
import javax.swing.JFrame;
import javax.swing.JLabel;
public class ExampleStatic
{
JLabel label;
public static void main(String[] args)
{
//Option 1 - Work from static context:
JFrame frame = new JFrame();
frame.setBounds(10,10,100,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
JLabel staticlabel = new JLabel("static");
frame.add(staticlabel);
frame.setVisible(true);
//Option 2 - Create instance, call initialisation function
ExampleStatic e = new ExampleStatic();
e.initialise();
//Option 3 - Create instance, handle initialisation in constructor
new ExampleStatic(true);
}
public ExampleStatic(){}
public ExampleStatic(boolean init)
{
JFrame frame = new JFrame();
frame.setBounds(10,10,100,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label = new JLabel("constructor");
frame.add(label);
frame.setVisible(true);
}
public void initialise()
{
JFrame frame = new JFrame();
frame.setBounds(10,10,100,100);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
label = new JLabel("init function");
frame.add(label);
frame.setVisible(true);
}
}
Option 2 and Option 3 both are fine, as both provide the loose coupling as well if you want to use your instance somewhere else in other classes you can use it easily. But if everything you will write in Main method you are going to loose the scope and its reusability.
The JVM needs main to be static, after that you're free to do what you want. I would call a non-static "second main" that would handle initialization and then any further processing in different methods (or classes).
I would avoid putting things in the constructor, unless you really feel it's the right place for them.

Is there a difference between calling a method from within a class' method code or on an instance of the class?

I have a piece of code here and I'm not sure what a couple of commands do:
//this bit is the body of the main method
//lots of stuff omitted
project frame = new project();
frame.createGUI();
private void createGUI() {
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new JPanel();
}
So when frame.createGUI(); is called, what happens with the two commands in createGUI();?
Are they
setDefaultCloseOperation(EXIT_ON_CLOSE);
panel = new JPanel();
or
frame.setDefaultCloseOperation(EXIT_ON_CLOSE);
frame.panel = new JPanel();
or is it something else entirely?
I'm quite new at Java, started year 12 Computer Science this year, but am a bit ahead of class.
Thanks for your time!
Every non static method in Java has an hidden parameter called this. It's value is the object in front of the dot in the invocation. Inside the body of methods, invocations of other methods implicitly have this. in front of them. So does the use of variables, if they cannot be resolved locally. If the this reference was explicit, your method would look like this:
private void createGUI(project this) {
this.setDefaultCloseOperation(this, EXIT_ON_CLOSE);
this.panel = new JPanel();
}
In the invocation of createGUI in your main method, what is really happening is something like this:
frame.createGUI(frame);
When running createGUI the this reference is a reference to frame.
setDefaultCloseOperation(EXIT_ON_CLOSE);
Sets the operation that happens when the user closed the Window (JFrame). The method is for JFrame. If the class extends JFrame then setDefaultCloseOperation(EXIT_ON_CLOSE); is fine since it will call the method of JFrame if not then it should be frame.setDefaultCloseOperation(EXIT_ON_CLOSE); but this will work if project extends JFrame
panel = new JPanel();
This creates a new panel.
frame.createGUI(); means that your object frame which u defined a line above calls the method createGUI()
setDefaultCloseOperation(EXIT_ON_CLOSE); this means that when the user click X button in the left top corner of the window will close the that window.
you can experiment a bit and delete setDefaultCloseOperation(EXIT_ON_CLOSE); from the createGUI() method and see what happens
if u want to learn more, look here
Your two alternatives are really one and the same. In both cases, you are calling methods of the frame object you created. From within a method of the class, you don't have to specifically say: this.doSomethimg() or this.myField = 123, you can just write doSomething() or myField = 123. From methods outside the class, you have to indicate for which instance you want the method called.

Categories