2

SEE THIS link for the solution to the problem

I am doing a project where I have a drop down list, which when an option is selected on the list, it loads an applet with custom settings. The name of the main class of the applet is SteadyStateFusionDemo. I don't why I'm having so much trouble with this because I know that I have to use a ClassLoader, but quite frankly I don't know how to do this.

Here is the code for my dropdown list. I want to link from the option on the list to the other class.

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
import java.lang.ClassLoader;
import ssfd.SteadyStateFusionDemo;

//**Creates Drop down Menu where choices show up in the box next to it//
//After one of these is selected, it loads the SteadyStateFusionDemo class//
//It also transmits a variable to the VariableStorage class, so that those//
//values can be used in operating the Tokamak.**//
public class ComboBox{
   JComboBox combo;
   JTextField txt;
   public static void main(String[] args) {
      ComboBox b = new ComboBox();
   }

   public ComboBox(){
        String course[] = {"NSTX","LTX","ITER"};
        JFrame frame = new JFrame("Creating a JComboBox Component");
        JPanel panel = new JPanel();
        combo = new JComboBox(course);
        combo.setBackground(Color.gray);
        combo.setForeground(Color.red);
        txt = new JTextField(10);
        panel.add(combo);
        panel.add(txt);
        frame.add(panel);
        combo.addItemListener(new ItemListener(){
        public void itemStateChanged(ItemEvent ie){
          String str = (String)combo.getSelectedItem();

     //Where the ItemListener interprets the choice, and then loads the SteadyStateFusionDemo class.

              if (str == "NSTX") {
                txt.setText("A");
          //loads SteadyStateFusionDemo, NSTX version

      }
              if (str == "ITER") {
              txt.setText("B");
             //loadsSteadyStateFusionDemo, ITER version




      }
              if (str == "LTX") {
              txt.setText("C");
              //loads SteadyStateFusionDemo, LTX version

      }

There is more after this but it isn't relevant to the question.

Can someone help me figure out how to link the two classes? The second class is in a different package and it doesn't use a static method. I have practically looked all over the Internet to find the solution, but alas no luck. :(

Community
  • 1
  • 1
awwerk1
  • 23
  • 4
  • DO NOT USE == ON STRINGS!! Use `.equals()` – fge May 31 '13 at 19:05
  • DO NOT USE `.equals()`, use `.equalsIgnoreCase()` !!!!!!!!!!! always! It's safer, and the microscopic performance impact is not significant. – SnakeDoc May 31 '13 at 19:11
  • Instead of loading the class into Java, you can use a local system call and execute the class naively. This will spawn a new JVM, which may or may not be a big deal, and you can embed that sys call in it's own thread to ensure it's not blocking. – SnakeDoc May 31 '13 at 19:12
  • @SnakeDoc disagree on `.equalsIgnoreCase()`, it is not always safer, far from it. – fge May 31 '13 at 19:13
  • Here's how to call native commands: http://stackoverflow.com/questions/2693740/how-to-call-system-commands-from-a-java-program So just do a "java someClass" from that System.exec() call. – SnakeDoc May 31 '13 at 19:14
  • @fge you're kidding right? can you show your reasoning? `.equalsIgnoreCase()` compares the string ignoring case, which is generally what people are after. If case matters, then explicitly use `.equals()` otherwise it should always be `.equalsIgnoreCase()`. – SnakeDoc May 31 '13 at 19:15
  • to explain, if you are dealing with user input, always use `.equalsIgnoreCase()` unless you have a very good reason. User's can't be trusted, and you don't want your program to blow up because they entered "sOmestring" instead of "somestring" or "SOMESTRING". If it's only internal data from your program you are checking, then `.equals()` could be used, however I'd argue that is not safe. What happens when the next dev. comes through and makes a change without realizing it was case sensitive? Bugs galore. – SnakeDoc May 31 '13 at 19:18
  • @SnakeDoc simple: most string tests are case sensitive. – fge May 31 '13 at 19:19
  • @SnakeDoc I don't really understand how the native commands work. I understand that the Runtime.exe is part of it? – awwerk1 Jun 03 '13 at 17:21
  • @awwerk1 it's rather simple: You specify ur command to run natively such as: `Runtime.getRuntime().exec("command line here");`... so in your case: `Runtime.getRuntime().exec("java SomeClassFile");` or `Runtime.getRuntime().exec("java -jar SomeJar.jar");` etc... Do this in a new thread so that this command does not block execution of hte rest of your program (or freeze your gui). In the link I provided, they go into how to specify path parameters such as the Java path, etc,, in the event ur target OS does not have them specified already. – SnakeDoc Jun 03 '13 at 18:11
  • @awwerk1 just a word of caution with this approach, it will be target OS dependent due to the native commands you will be using. This may not be an issue if you're targeting all the same OS (like all windows boxes, or all mac boxes, etc), but if you are targeting anyone and everyone, you'll want to do some OS detection using some means. For that, check out JUtils System.class - http://pastebin.com/VVar3eZD – SnakeDoc Jun 03 '13 at 18:27
  • so then you'd do something like: if windows - then execute this command, if mac, do this, etc. If all you are doing is executing some Java classes, then this is pretty platform agnostic already. Just wanted to mention this for "completeness". – SnakeDoc Jun 03 '13 at 18:29

1 Answers1

0

You can dynamically load classes by using Class.forName as in the following example, would this solve your problem?

Class<?> clazz = Class.forName("ssfd.SteadyStateFusionDemo");
SteadyStateFusionDemo ssfd = clazz.newInstance();
Elmer
  • 317
  • 1
  • 13
  • hmmm... it still doesn't load the other class. Is there any other approach I could possibly take? – awwerk1 May 31 '13 at 19:29
  • @awwerk1 look into calling a native system call: http://stackoverflow.com/questions/2693740/how-to-call-system-commands-from-a-java-program – SnakeDoc May 31 '13 at 19:34
  • It says that SteadyStateFusionDemo cannot be resolved to a variable – awwerk1 Jun 03 '13 at 13:45
  • I added a fix to the code it should be SteadyStateFusionDemo ssfd = clazz.newInstance(); Let me know how it works. – Elmer Jun 03 '13 at 13:52
  • I'm now getting an error that says "Type mismatch; cannot convert from capture #2- of ? to SteadyStateFusionDemo – awwerk1 Jun 03 '13 at 14:16
  • Do your dynamic classes extend a generic interface? Otherwise try adding a cast SteadyStateFusionDemo ssfd = (SteadyStateFusionDemo) clazz.newInstance(); – Elmer Jun 03 '13 at 14:26
  • instead of using `class.newInstance();` try explicit casting such as: `SteadyStateFusionDemo ssfd = (SteadyStateFusionDemo) clazz;` What you have here is a class that the JVM has no idea what it is, so you have to tell the JVM what it is, so that you can "re-align" the class and get access to all it's methods and stuff. – SnakeDoc Jun 03 '13 at 18:14
  • In fact clazz is not of type SteadyStateFusionDemo, clazz is of type Class so you cannot cast it to SteadyStateFusionDemo. The instance you created with clazz.newInstance() is what can be actually cast to SteadyStateFusionDemo. See http://stackoverflow.com/questions/4433247/how-to-use-reflection-package-to-create-an-object-from-a-classpath/4433325#4433325 – Elmer Jun 03 '13 at 19:21