Updating a GUI component from a runnable class that doesn't know that GUI

Hi. I have a problem that I think isn't solvable in an elegant way, but I'd like to get confirmation before I do it the dirty way.
My application allows the user to save (and load) his work in sessions files. I implemented this by a serializable class "Session" that basically stores all the information that the user created or the settings he made in its member variables.
Now, I obviously want the session files created by this to be as small as possible and therefore I made sure that no GUI components are stored in this class.
When the user has made all his settings, he can basically "run" his project, which may last for a long time (minutes, hours or days, depending on what the user wants to do....). Therefore I need to update the GUI with information on the progress/outcome of the running project. This is not just a matter of updating one single GUI component, but of a dynamic number of different internal frames and panels. So I'd need a reference to a GUI component that knows all these subcomponents to run a method that does the update work.
How do I do that? I cannot pass the reference to that component through the method's argument that "runs" the project, because that needs to be a seperate thread, meaning that the method is just the run() method of that thread which has no arguments (which I cannot modify if I'm not mistaken).
So the only thing I can think of is passing the reference through the constructor of the runnable class (which in turn must be stored in the session because it contains critical information on the user's work). As a result, all components that need to be incorporated in that updating process would be part of the session and go into the exported file, which is exactly what I wanted to avoid.
I hope this description makes sense...
Thanks in advance!

Thanks for the quick answer! Though to be honest I am not sure how it relates to my question. Which is probably my fault rather than yours :-)
But sometimes all it takes me to solve my problem is posting it to a forum and reading it through again :)
Now I wrote a seperate class "Runner" that extends thread and has the gui components as members (passed through its constructor). I create and start() that object in the run method of the original runnable class (which isn't runnable anymore) so I can pass the gui component reference through that run method's argument.
Not sure if this is elegant, but at least it allows me to avoid saving gui components to the session file :-)
I am realizing that probably this post shouldn't have gone into the swing forum...

Similar Messages

  • How to get change a GUI component from another class?

    Hi there,
    I'm currently trying to change a GUI component in my 'Application' class from my 'Dice' class.
    So the Application class sets up some GUI including a JLabel that initially displays "Change".
    The 'Dice' class contains the ActionPerformed() method for when the 'Change' button (made from Application class) is clicked.
    And it returns an 'int' between 1 and 6.
    Now I want to set this number back int he JLabel from the Application class.
    APPLICATION CLASS
    import javax.swing.*;
    import java.awt.*;
    import java.util.Random;
    import java.awt.event.*;
    public class Application extends JFrame implements ActionListener{
         public JPanel rollDicePanel = new JPanel();
         public JLabel dice = new JLabel("Loser");
         public Container contentPane = getContentPane();
         public JButton button = new JButton("Change");
         public Dice diceClass = new Dice();
         public Application() {}
         public static void main(String[] args)
              Application application = new Application();
              application.addGUIComponents();
         public void addGUIComponents()
              contentPane.setLayout(new BorderLayout());
              rollDicePanel.add(dice);
            button.addActionListener(diceClass);
            contentPane.add(rollDicePanel, BorderLayout.SOUTH);
            contentPane.add(button,BorderLayout.NORTH);
              this.setSize(460, 655);
              this.setVisible(true);
              this.setResizable(false);
         public void changeDice()
              dice.setText("Hello");
         public void actionPerformed(ActionEvent e) {}
    }DICE
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    public class Dice implements ActionListener
         public Dice() {}
         public void actionPerformed(ActionEvent e)
              //super.actionPerformed(e);
              String event = e.getActionCommand();
              if(event.equals("Change"))
                   System.out.println("Will be about to change the 'dice' label");
                   Application application = new Application();
                   application.dice.setText("Hello");
    }

    It's all about references, baby. The Dice object needs a way to communicate with the Application object, and so Dice needs a reference to Application. There are many ways to pass this. In my example I pass the application object directly to Dice, but a better way would use interfaces and some indirection. Look up the Observer pattern for a better way to do this that scales much better than my brute-force approach.
    import javax.swing.*;
    import java.awt.*;
    public class Application extends JFrame // *** implements ActionListener
        // *** make all of these fields private ***
        private JPanel rollDicePanel = new JPanel();
        private JLabel dice = new JLabel("Loser");
        private Container contentPane = getContentPane();
        private JButton button = new JButton("Change");
        // *** pass a reference to your application ("this")
        // *** to your Dice object:
        private Dice diceClass = new Dice(this);
        public Application()
        public static void main(String[] args)
            Application application = new Application();
            application.addGUIComponents();
        public void addGUIComponents()
            contentPane.setLayout(new BorderLayout());
            rollDicePanel.add(dice);
            button.addActionListener(diceClass);
            contentPane.add(rollDicePanel, BorderLayout.SOUTH);
            contentPane.add(button, BorderLayout.NORTH);
            setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            setPreferredSize(new Dimension(460, 655));
            pack();
            setLocationRelativeTo(null);
            setVisible(true);
            setResizable(false);
        // *** I'm not sure what this is supposed to be doing, so I commented it out.
        //public void changeDice()
            //dice.setText("Hello");
        // *** ditto.  I strongly dislike making a GUI class implement ActionListeenr
        //public void actionPerformed(ActionEvent e)
        // *** here's the public method that the Dice object calls
        public void setTextDiceLabel(String text)
            dice.setText(text);
    import java.awt.event.ActionEvent;
    import java.awt.event.ActionListener;
    public class Dice implements ActionListener
        // *** have a variable that holds a reference to your application object
        private Application application;
        private boolean hello = true;
        public Dice(Application application)
            // *** get that reference via a constructor parameter (one way to do this)
            this.application = application;
        public void actionPerformed(ActionEvent e)
            String event = e.getActionCommand();
            if (event.equals("Change"))
                System.out.println("Will be about to change the 'dice' label");
                if (hello)
                    // *** call the application's public method
                    application.setTextDiceLabel("Hello");
                else
                    application.setTextDiceLabel("Goodbye");
                hello = !hello;
                //Application application = new Application();
                //application.dice.setText("Hello");
    }

  • How to interact with a COM component from a Java class

    Hi, could someone give a hint on what API I should explore in order to interact with a COM component from a Java class?
    Thanks in advance
    Luis

    jacob sounds nice...http://danadler.com/jacob/

  • Updating JPanel with buttons from a different class

    I have a JPanel in a class that has a gridlayout with buttons in it for a game board. And my problem is that when I want to update a button using setIcon() the button doesn't change in the GUI because the buttons are in a different class. The JPanel is in a Client class and the buttons are in a GamePlugin class. I've tried a bunch of different things but none of them worked or it was way too slow. I'm sure theres an easy way to do it that I'm not seeing. Any suggestions? Heres part of my code for updating the GUI.
    private JPanel boardPanel = new JPanel(); 
    Container cP = getContentPane();
    cP.add(boardPanel, BorderLayout.WEST);
    boardPanel.setPreferredSize(new Dimension(400, 400));
    boardPanel.setLayout(new GridLayout(8, 8));
    cP.add(optionsPanel, BorderLayout.CENTER);
          * Gets the board panel from the selected plugin.
         public void drawGameBoard(GamePlugin plugin) {
              board = (OthelloPlugin)plugin;
              boardPanel = board.getBoardPanel();
              for (int i = 0; i < GamePlugin.BOARD_SIZE; i++)
                   for (int j = 0; j < GamePlugin.BOARD_SIZE; j++) {
                        board.boardButtons[i][j].setActionCommand("" + i + "" + j);
                        board.boardButtons[i][j].addActionListener(this);
          * This method takes a GameBoard and uses it to update this class' data
          * and GUI representation of the board.
         public void updateBoard(GamePlugin updatedBoard) {
              board = (OthelloPlugin)updatedBoard;
              for (int i = 0; i < GamePlugin.BOARD_SIZE; i++) {
                   for (int j = 0; j < GamePlugin.BOARD_SIZE; j++) {
                        int cell = board.getCell(i,j);
                        if (cell == OthelloPlugin.PLAYER1){
                             board.boardButtons[i][j].setIcon(black);
                        else if (cell == OthelloPlugin.PLAYER2)
                             board.boardButtons[i][j].setIcon(white);
                        else
                             board.boardButtons[i][j].setText("");
         }

    txp200:
    I agree that a call to validate() , possibly repaint(), should fix your problem. In the class with the panel that the buttons are on, i would create a static repaint method that call panel.repaint(). You can then call that method in your other class. Just make sure u only use methods to change the properties of the button, never make a make a new one, as then you will lose the association with the panel. Hope this helps.
    -- Brady E

  • How to get the message from a Runnable class

    The Schedule class is actually a JFrame, what I want to do is to "get" the message from Scheduler Class and display it in a JTextField, to let user know what is doing.
    How can I approach this?
    public class Schedule {
        @SuppressWarnings("static-access")
        public static void main(String args[]) throws InterruptedException {
            final Scheduler s = new Scheduler();
            Thread t = new Thread(s);
            t.start();
    public class Scheduler implements Runnable{
    private static int actionType;
    private static String msg;
        public static void setMsg(String msg) {
            Scheduler.msg = msg;
        public static String getMsg() {
            return msg;
        public void run() {
            //System.out.println((int)(Math.random() * 1000));
            actionType = 1;
            while(true){
                try {
                    switch(actionType){
                        case 1:
                            setMsg("Process actionType: "+actionType);
                            break;
                            case 2:
                            Thread.sleep(2000L);
                            setMsg("Process actionType: "+actionType);
                            break;
                            case 3:
                            Thread.sleep(2000L);
                            setMsg("Process actionType: "+actionType);
                            break;
                            case 4:
                            Thread.sleep(2000L);
                            setMsg("Process actionType: "+actionType);
                            break;
                    actionType++;
                    if(actionType>4){
                        actionType = 1;
                } catch (InterruptedException ex) {
                    System.out.println("Scheduler.run:"+ex.toString());
    }

    Or with only one loop:
            int actionType = 0;
            while (true)
                actionType = (actionType % 4) + 1;
                msg = "Process actionType: " + actionType;
                try
                    Thread.sleep(2000L);
                catch (InterruptedException ex)
                    System.out.println("Scheduler.run:" + ex.toString());
            }

  • How do I access a gui component in a different class?

    I have a jpanel (mainwindow) in a japplet. mainwindow loads and displays a jpanel form (content1). How do I code a button on conent1 so that mainwindow loads and displays a different jpanel form(content2)? mainwindow, content1, and content2 are all in different classes/packages. Thanks in advance!

    Let your JPanel content1 forward its ActionEvents to its parent. For instance, you could define your content1 as follows:
    public class Content1 extends JPanel
        private ArrayList<ActionListener> actionListeners;
        private JButton myButton;
              public Content1()
             actionListeners = new ArrayList<ActionListener>();
             myButton = new JButton("Test");
             myButton.addActionListener(new ActionListener() {
                        public void actionPerformed(ActionEvent e) {
                             forwardAction(e);
              public void addActionListener(ActionListener listener) {
             actionListeners.add(listener);
        protected void forwardAction(ActionEvent e) {
          for (ActionListener l: actionListeners) {
               l.actionPerformed(e);
    }Then you could let your mainWindow listen to content1:
    // in your main windows' code:
    Content1 content1 = new Content1();
    content1.addActionListener(new ActionListener() {
         public void actionPerformed(ActionEvent e) {
              swapPane(e);    // create a method swapPane in your mainwindow that handles the switch to content2.
    });

  • Firefox doesn't know that I updated a plug-in.

    Firefox was crashing whenever I closed a window. Mozilla Support directed me to the Plugin Check page. It told me to update Java(TN) Platform SE6U37 (among other things). I downloaded jre-7u11-windows-x64.exe. I ran it. The last window said "You have successfully installed Java". I closed everything and restarted windows 7. Then I opened Firefox and followed the same path to the Plugin Check page. It told me to do the same update.

    According to this bug on the Oracle site http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=8005410 , the problem occurs because their installer did not properly recognize prior Java versions and is compounded by a problem with systems having the JavaFX stand-alone application installed.
    So, if you see JavaFX in your list of installed programs (Windows: Control Panel), remove it. It might also be best to remove all Java from your system before installing the new Java.
    I would have recommended JavaRa to uninstall all previous Java from your system, but, sadly, it has not been updated since October 2012 and does not include and will not find more recent versions of Java files and/or registry keys. Hopefully the built-in Windows uninstall will remove all of the files and registry entries
    Oracle has released Java 7 update 11 to address the vulnerability recently recognized in Java 7 update 10 and some prior versions. Java 6 update 38 was not updated; support for the Java 6 versions ends in February 2013.

  • Thunderbird keeps returning an error "no such user" when I try to send from some email addresses even though I know that is false.

    emails will not send from @protranscript.net domain addresses, even though they receive just fine. The program keeps saying that the server says there is no such user, even when I try and email myself!

    "An error occurred while sending mail. The mail server responded: <[email protected]> No such user here. Please check the message recipient [email protected] and try again." I know for a fact that email exists because it is the one your reply came to, lol.

  • Trying to create Netbeans Swing/GUI component

    Hello,
    I'm trying to create a GUI component from the following code. The main idea is to create a component consisting of a checkbox and a panel. The panel can contain several other swing components. By checking or unchecking the checkbox I want all by components in the panel to be enabled or disabled.
    The important thing is that this component should work in the Netbeans GUI designer. I'm using Netbeans 5.5.
    My problem is the following:
    When adding my swing component to the Netbeans swing component palette and dragging onto a new form, I cannot assign other components to the main panel of my component. Even if I use the Inspector tree to drag components to be children of my component, the mouse icon shows a denying icon.
    If I add swing components programmatically, it works.
    Can somebody give me an advice what I should change in my code to make it work with the Netbeans GUI designer?
    Below you can find the current code of my standalone component. It includes a main() method so one can give it a try.
    Many thanks in advance!
    package test.swing;
    import java.awt.*;
    import java.awt.event.*;
    import javax.swing.*;
    public class JEnabler extends JPanel {
        private JCheckBox checkEnabler = new JCheckBox();
        private JPanel contentPane = new JPanel();
        public JEnabler() {
            super.setLayout(new BorderLayout());
            checkEnabler.setSelected(true);
            checkEnabler.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
            checkEnabler.setMargin(new Insets(0, 0, 0, 0));
            checkEnabler.setVerticalAlignment(SwingConstants.TOP);
            checkEnabler.addActionListener(new ActionListener() {
                public void actionPerformed(ActionEvent evt) {
                    checkEnablerActionPerformed(evt);
            super.addImpl(checkEnabler, BorderLayout.WEST, -1);
            super.addImpl(contentPane, BorderLayout.CENTER, -1);
        private void checkEnablerActionPerformed(ActionEvent evt) {
            Component[] list = contentPane.getComponents();
            for (int i=0; i<list.length; i++)
                list.setEnabled(checkEnabler.isSelected());
    protected void addImpl(Component comp, Object constraints, int index) {
    contentPane.add(comp, constraints, index);
    public LayoutManager getLayout() {
    return contentPane.getLayout();
    public void setLayout(LayoutManager mgr) {
    if (contentPane!=null)
    contentPane.setLayout(mgr);
    public void remove(Component comp) {
    contentPane.remove(comp);
    public void remove(int index) {
    contentPane.remove(index);
    public void removeAll() {
    contentPane.removeAll();
    public static void main(String args[]) {
    SwingUtilities.invokeLater(new Runnable() {
    public void run() {
    JFrame frame = new JFrame();
    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    JEnabler enabler = new JEnabler();
    JTextField tf = new JTextField("Test");
    enabler.add(tf);
    JButton test = new JButton("Click");
    enabler.add(test);
    frame.getContentPane().add(enabler);
    frame.pack();
    frame.setVisible(true);

    Can anyone tell me what I am missing?
    public void paintComponents(Graphics g)you're not 'missing' anything, in fact you've gained an 's'

  • Executing one system command from one java class. ERROR. Please help me

    Hello i am trying to add users into one linux machine using one jaav program but when i execute the java class the system doesn't show me any error and dont make anything.
    The linux command, in the main of the class, is correct; from thelinux shell it runs well, but from the java class it doesn't run.
    Can you help me please?
    thanks
    import java.io.*;
    public class ejecutaUsuario {
    /** Creates a new instance of ejecutaUsuario */
    public ejecutaUsuario(String cmdline) {
    try {
    String line;
    Process p = Runtime.getRuntime().exec(cmdline);
    BufferedReader input =
    new BufferedReader
    (new InputStreamReader(p.getInputStream()));
    while ((line = input.readLine()) != null) {
    System.out.println(line);
    input.close();
    catch (Exception err) {
    err.printStackTrace();
    System.out.println(err);
    public static void main(String argv[]) {
    String passwd="hola";
    String usuarioInterno="xxxxxx";
    new ejecutaUsuario("/bin/sh useradd -p `openssl passwd -1 -salt 12345678 " + passwd + "` -d /home/" + usuarioInterno + " -m -s /bin/bash " + usuarioInterno);

    Try gettting the error input stream as well (getErrorStream()). Maybe you are getting output there.
    You might want to try just executing the 'useradd' part, getting the output stream of that process, and then put the parameters of useradd into the outputstream.
    Later
    Cardwell

  • 2009-001 Security Update Has Broken Printing From VMWare

    Are Apple aware that their latest security patch has affected the ability to print from a guest OS in VMWare Fusion?
    I've installed Adobe Reader 8 since the update, and that won't print too, though I can still print PDF's from Preview, perhaps the update has affected CUPS.
    Since Apple recommend VMWare (quite rightly) in their online store, I hope that they feel an obligation to help solve this!
    Message was edited by: Punter1

    Dave Sawyer wrote:
    It seems like you VMWare people have more problems than people using Parallels.
    I have both
    Me too!
    in my experience Parallels is a lot more twitchy and problematic than VMWare.
    I'm not sure about the definition of "twitchy" in this (or any) context.
    That doesn't mean that VMWare is perfect; it's not by any means.
    I've never seen any software that is prefect and without bugs. I want to sound fair and unbiased, but I can honestly say that I have never experienced any problem, of any kind, in Parallels. It has never failed me.
    I cannot say the same for VMWare. I tried it, found numerous problems immediately. The 2.0 version seems better. It doesn't appear to make the Mac itself unstable, even when VMWare isn't running.
    But I've found it to be much more stable than Parallels (either v. 3.x or v 4.x).
    For all tasks where printing isn't required I assume
    It is not my intention to turn this thread into yet another Parallels vs. VMWare flame war. I have seen a great deal of disinformation targeted at Parallels over the past couple of years. I have made it a personal goal to do my part to fight it whenever I get the chance. So that is why I seem a bit testy and defensive - because I am
    Neither you nor the original poster have said anything derogatory towards Parallels. Both Parallels and VMWare are fine products. In this case, VMWare has a bug. That is unfortunate for them. I haven't installed the security update myself to see if Parallels is immune. But I'm guessing it is unaffected considering the level of trashing that Parallels gets even when they don't have bugs.
    It is unfortunate that the original poster was misinformed about Apple recommending VMWare. Apple will help market just about any Mac software, but I don't think Apple would ever recommend any 3rd party product over another 3rd party product. They sell both VMWare and Parallels in the Apple Store.
    I am sure that VMWare will find and fix this bug fairly shortly. I'm sure Apple will help them if they ask.
    I am sure that Adobe Reader 8 will not be updated to fix its bug. Adobe Reader 8 is already obsolete. Adobe Reader 9 may not have the same issue. I can't say myself because I don't use Adobe software to read PDFs. I prefer Preview, Skim, or PDFClerkPro.

  • Executing another exe from a java class

    Hi All,
    I want to execute another executable from a java class. I am doing that with the help of Runtime.getRuntime().exec(String) function.
    My executable runs for quite sometime and it keeps printing something to stdout consistently.
    I want to read whatever this exe is putting out to stdout as and when it is put out, not after the whole process has finished.
    Now, Runtime.getRuntime().exec(String) just spawns the exe in another process space and I am not able to get its handle, maybe I have missed something.
    Is there any other method/way to do what I want to?
    TIA
    -Satish

    Now, Runtime.getRuntime().exec(String) just spawns the
    exe in another process space and I am not able to get
    its handle, maybe I have missed something.
    Is there any other method/way to do what I want to?Acutally, Runtime.getRuntime().exec(String) returns a Process object. Use this process to "talk" to the program you just launched. For your needs, try Process.getOutputStream(). Take a look at the API for Process at http://java.sun.com/j2se/1.3/docs/api/java/lang/Process.html
    Hope this helps.

  • Call a portal component from a Command IU Java Class

    Hello,
    Please, how can I do to call a portal component from my Command IU Java Class?
    Thanks & Regards,
    Hassan

    Hi Hassan,
    a portal component can be called directly through URL.
    The general syntax to call the portal component (iView, page) is as follows:
    <http/https>://<server>:<port>/irj/servlet/prt/portal/prtroot/<pcd_path_of_iview_or_page>
    Replace all ":" in the pcd path by "!3a". Also replace all "/" by "!2f" in the pcd path in the URL.
    Hope this helps.
    Best regards,
    Denis

  • Updating Jlabel from a different class?

    Hi,
    Im in the middle of developing a program but swing is making it very hard for me to structure my code. The problem is I want to update the text of a Jlable from a different class when a button is pressed. THe event handling is done by a different class than the where the Jlabel is initiated which is why i think it doesnt work. But when the button is pressed it does execute a method from the main class that has the .setText() in it. Why wont the Jlabel update? Thank you

    Thanks for your help but i am still having trouble.
    This is the code from the button handler class
    public void actionPerformed(ActionEvent e)
           if ("btn3_sender".equals(e.getActionCommand()))
                JLabel j = temp2.getlblQuestion();
               j.setText("NEW TEXT");
           This is the code from the main class where the JLabel is created:
    public JLabel getlblQuestion()
        return lblQuestion;
    }How come this does not work??

  • Update Phase Component From Project Component

    Morning all.
    I'm looking at options we might have open to us for the following scenario. Any ideas? Previous experiences,  etc most welcome ...
    We have a custom field in DPR_DET_DATA_PROJECT_O that we transfer to PS, but want to use the same field value to force PPM to think the same field change has occurred in DPR_DET_DATA_PHASE_O without us actually needing to access the component via the UI. We have an active subsystem that we write the value to,  but don't want to have to a have to start the phase component from the ui to pass the change before saving.
    The idea being that we only need this field value at PS Replication time on the phase .... As we want to effectively cascade this value onto all our WBS Elements (DPO & PPO objects) in PS (only 2 level controlling scenario) ... We don't even really need to save the data at the phase level .... Just make the change manager think that the phase had changed ... hopefully we'll then get the PPO objects through the DPR_FIN_GECCO_ATTR Badi during replication .... without having physically made s chessmen at phase level. Make sense?
    Is setting the phase data (and triggering a change to be recorded) from the project component a possibility?
    Many Thanks

    Hello David,
    If I understood correctly, you want to change a custom field existing both in the project definition and at phase level, without accessing the Phase in the UI? Is that right?
    If so, than it's simple. In your subsystem, I suppose you have an instance of your loaded project (cl_dpr_project_o). When you change the value of the particular field and "trigger" the updating, you just use the project instance (let's call it lo_project) to get all the child phases in an object table (type CL_DPR_PHASE). Loop through this table and use the method lo_phase->set_data( ). I'm not sure in which of the three structure you can find the custom fields, but it's definitely either _INT/_CHG/_EXT. Also, I recommend you encapsulate this code inside a method, as you'll need to call it from the beginning (if you decide not to save the value).
    Hope this helps!
    Tudor

Maybe you are looking for