Search code examples
javamultithreadingribbonrunnableradiance-flamingo

Java Ribbon - Flamingo won't run() a Runnable JPanel


I'm trying to make a JPanel in a JInternalFrame refresh it graphics after I call the JInternalFrame from a JRibbonFrame by "while looping" the repaint() method. the problem occurs whenever and wherever I call the JPanel run() method. Here are the three ways I tried:

Method 1: calling the run() method right after I added the internalFrame to the contentPane

Method 2: creating another button [that calls the run()] method in the Ribbon and wait until the image (in the Jpanel) is loaded before I click the "run thread" button

Method 3: Making the JRibbonFrame runnable. then in the JRibbonFrame run() method "while looping" the call of JPanel's run() method and finally calling JRibbonFrame run() in the main(String args[]) method.

None of the aforementioned methods works (the application simply freeze!!!)

I beg you please help!

DocumentClass.java

import java.awt.*;
import java.awt.event.*;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;
import javax.swing.JPanel;

public class DocumentClass extends JPanel implements Runnable {


private BufferedImage image;
    public int imgx = 20, imgy= 20;

    public DocumentClass(File newImage){

        try {                
           image = ImageIO.read(newImage);
        } catch (IOException ex) {
             System.out.print("image not found");
        }
    }

    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        g.drawImage(image, imgx, imgy, this);
    }

    public void run() {
        while(true){
            try {
                Thread.sleep(75);
            } catch (InterruptedException ex) {}
            repaint();
        }
    }


}

WindowClass.java

import java.awt.event.*;
import java.io.*;
import javax.swing.*;
import org.jvnet.flamingo.common.*;
import org.jvnet.flamingo.ribbon.*;
import test.svg.transcoded.*;

public class WindowClass extends  JRibbonFrame {
    private final JDesktopPane desktopPane;

    public WindowClass(){
            super("Whatever");
            this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
            this.setVisible(true);

            desktopPane = new JDesktopPane();
            add(desktopPane);
    }


    protected void configureApplicationMenu() {
        RibbonApplicationMenuEntryPrimary amEntryNew = new RibbonApplicationMenuEntryPrimary(
        new document_new(), "New", new ActionListener() {
        @Override
            public void actionPerformed(ActionEvent e) {

                JFileChooser fc = new JFileChooser();
                int returnVal = fc.showOpenDialog(null);

                if (returnVal == JFileChooser.APPROVE_OPTION) {
                    File newImage = fc.getSelectedFile();

                    JInternalFrame internalFrame = new JInternalFrame(
                    "New Project", true, true, true, true);


                    DocumentClass document  = new DocumentClass(newImage);
                    internalFrame.setContentPane(document);


                    // Add the internal frame to the desktopPane
                    desktopPane.add(internalFrame);
                    // Set the window size of the internal frame
                    internalFrame.setSize(400, 400);

                    // Display it.
                    internalFrame.setVisible(true);

                }

            ((DocumentClass)(desktopPane.getAllFrames()[0]).getContentPane()).run(); //this is Method 1. comment this and it will work but not refresh graphics
            }
        }, JCommandButton.CommandButtonKind.ACTION_ONLY);
        amEntryNew.setActionKeyTip("N");


        RibbonApplicationMenu applicationMenu = new RibbonApplicationMenu();
        applicationMenu.addMenuEntry(amEntryNew);

        this.getRibbon().setApplicationMenu(applicationMenu);

        RichTooltip appMenuRichTooltip = new RichTooltip();
        this.getRibbon().setApplicationMenuRichTooltip(appMenuRichTooltip);
        this.getRibbon().setApplicationMenuKeyTip("F");
    }

}

Main.java

import java.awt.*;
import javax.swing.*;

public class Main {
    public static void main(String[] args) {

            final WindowClass mainWindow = new WindowClass();
            mainWindow.configureApplicationMenu();
            mainWindow.setSize(500, 500);
            mainWindow.setVisible(true);
            mainWindow.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
    }
}

thanks in advance!


Solution

  • Calling run does not create a new thread, and the thread which is running actionPerformed also does several important tasks such as refreshing the graphics after repaint. You should use a swing timer:

    private Timer timer;
    
    public DocumentClass(File newImage) {
        ...
        timer = new Timer(75, new ActionListener() {
            public void actionPerformed(ActionEvent e) {
                repaint();
            }
        });
    }
    public void start() {
        timer.start();
    }
    

    Then use my method 4: call the start method instead of the run method. You don't need to implement Runnable anymore, as a nice plus.