1

I am working on Java the Application of Swing and which i am getting Data and i am using swing Jtable Render for render Image in that but when data is more its hanging all time so what can i do to prevent that?

example render that i am using.

public class DefaultTableCellRenderer extends javax.swing.table.DefaultTableCellRenderer {

    JLabel jLabel;

    public DefaultTableCellRenderer() {
        jLabel = new JLabel();

    }

    public Component getTableCellRendererComponent(
            JTable table, Object value, boolean selected, boolean focus, int row, int col) {

        try {
            if (row == 1) {
                jLabel.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("blank.png"))));
                jLabel.setText("Image Data");
                jLabel.setBackground(Color.LIGHT_GRAY);
            } else {
                jLabel.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("blank.png"))));
                jLabel.setText("Final");
            }

            //jLabel.setIcon(new ImageIcon(ImageIO.read(new File("blank"))));

            return jLabel;

        } catch (Exception e) {
            e.printStackTrace();
        }
        return jLabel;
    }

    @Override
    public boolean mouseEnter(Event evt, int x, int y) {
        System.out.println(jLabel.getText());
        return true;
    }
}
  • 3
    Consider providing a [runnable example](https://stackoverflow.com/help/mcve) which demonstrates your problem. This will result in less confusion and better responses – MadProgrammer Sep 04 '14 at 07:08
  • @MadProgrammer yes its working file but taking so much load i mean its taking too much cpu. while data is something more. – Kishan Bhimajiyani Sep 04 '14 at 07:10
  • Don't load images from within renderers. Place them in a cache of some kind that can looked up separately. – MadProgrammer Sep 04 '14 at 08:07
  • Will there **always** be the *same* image for all cells? Then the (simple) solution that MadProgrammer proposed in his answer will be sufficient. Otherwise (if there are different images for each row), you'll need some more sophisticated loading mechanism. – Marco13 Sep 04 '14 at 08:24
  • ya there is all time new image not same. – Kishan Bhimajiyani Sep 04 '14 at 08:39

2 Answers2

3

This...

jLabel.setIcon(new ImageIcon(ImageIO.read(getClass().getResource("blank.png"))));

Is an expensive call, each time it's called, a new ImageIcon class is created which is wrapping around the BufferedImage data been read. Unlike ImageIcon, ImageIO will not buffer images and re-use them, instead, it will read the resource a new.

This means, that each time the cell is rendered, the image is been fully reloaded.

Since, your loading the same image each time, simple load the image when you construct the class and make use of it when needed, for example...

public class DefaultTableCellRenderer extends javax.swing.table.DefaultTableCellRenderer {

    private Icon icon;

    public DefaultTableCellRenderer() throws IOException {
        icon = new ImageIcon(ImageIO.read(getClass().getResource("blank.png");
    }

    public Component getTableCellRendererComponent(
            JTable table, Object value, boolean selected, boolean focus, int row, int col) {
        super.getTableCellRendererComponent(table, value, selected, focus, row, col);
        setIcon(icon);
        if (row == 1) {
            setText("Image Data");
            setBackground(Color.LIGHT_GRAY); // You may need to set the opaque state for this to work...
        } else {
            setText("Final");
        }
        return this;
    }
}
MadProgrammer
  • 343,457
  • 22
  • 230
  • 366
  • Ahh, that's the nice way to do it. I normally use a SwingWorker, but that's generally for loading a set of images prior to GUI instantiation. – Gorbles Sep 04 '14 at 08:16
  • 1
    @Gorb It all depends, since the OP is only loading a single image, this would easier, had thought an image cache might be required, but it turns out to much simpler then I thought – MadProgrammer Sep 04 '14 at 08:17
  • but what if i need to upload all time other image ? – Kishan Bhimajiyani Sep 04 '14 at 08:39
  • As that's not in your example, I have no idea what you mean. Do you want to show a progress bar of the upload?? – MadProgrammer Sep 04 '14 at 09:29
2

Some suggestions for you:

  1. You can load the images at the start of application using multithreading. Use the class Executors to do it. Important is: you must load all the images before you show your UI.
  2. Another possibility is asynchronious loading of images. Use SwingWorker to load images. The loading must be implemented in the method doInBackground(). When some images are loaded you can use the methods publish()/process() to update your table model with new images.
  3. You can combine both and use Executors in doInBackground() method.

I think, your problem is not the CPU load. Your problem is IO. Reading from hard disk is very slow and should be performed in background when it's possible.

Sergiy Medvynskyy
  • 11,160
  • 1
  • 32
  • 48
  • okey so i need to add this Swingworker thread into the Render that i am using isnt it? – Kishan Bhimajiyani Sep 04 '14 at 07:34
  • @KishanBhimajiyani If you want to provide it in your renderer you will also need an image caching. Renderer is called too often to load the images each time. Save the images in your table model. – Sergiy Medvynskyy Sep 04 '14 at 07:37
  • okey then its better to call where its setting into the application isn't it? :) – Kishan Bhimajiyani Sep 04 '14 at 07:39
  • Simply implement your own table model which extends AbstracTableModel and can load the images asynchronously. Create an object which contains the file and loaded image. Image is null at start and must be loaded when getValueAt() method of TableModel is called at first time for the certain cell. The renderer uses the image to show it in a table cell. Don't forget to invoke fireTableDataChanged() in Swing thread (EDT) after loading of an image. – Sergiy Medvynskyy Sep 04 '14 at 07:49
  • so after loading image i need to use that and wait i am uploading some sample type thing. :) – Kishan Bhimajiyani Sep 04 '14 at 07:56
  • @SergiyMedvynskyy While I agree with the general recommendations that you gave, the images do not seem to be part of the *model* - but actually, this is not clear from the code that was provided so far... – Marco13 Sep 04 '14 at 08:22
  • @Marco13 why not? I think the image can be a part of a model, for example when I have a preview column. – Sergiy Medvynskyy Sep 04 '14 at 08:31
  • @SergiyMedvynskyy From the question it's not clear what is the most appropriate solution here. But usually, I consider the *model* as something that is agnostic and unaware (!) of its visual representation in the *view*. The border may be somewhat blurred *if* the model contains *images*, and the images in the renderer should be smaller previews, but even then, I'd consider them as part of the view. (Not to mention odd cases, where the *same* model is displayed in *several* tables, with different preview sizes...) – Marco13 Sep 04 '14 at 08:36