Insubstantial / insubstantial

Swing look-and-feel library and assorted widgets
193 stars 58 forks source link

Huge CPU usage at JTable mouse events #78

Open laxika opened 12 years ago

laxika commented 12 years ago

When I do fast mouse events on JTable (especially dragging) the CPU usage jumps close to 50%. Here is an example code:

package sstabletest;

import java.awt.Dimension;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.*;
import org.pushingpixels.substance.api.skin.SubstanceTwilightLookAndFeel;

/**
 *
 * @author Laxika
 */
public class SSTableTest extends JFrame {

    private static SSTableTest test = null;
    String[] columnNames = {"First Name",
        "Last Name",
        "Sport",
        "# of Years",
        "Vegetarian"};
    Object[][] data = {
        {"Kathy", "Smith",
            "Snowboarding", new Integer(5), false},
        {"John", "Doe",
            "Rowing", new Integer(3), true},
        {"Sue", "Black",
            "Knitting", new Integer(2), false},
        {"Jane", "White",
            "Speed reading", new Integer(20), true},
        {"Joe", "Brown",
            "Pool", new Integer(10), false},
        {"Kathy", "Smith",
            "Snowboarding", new Integer(5), false},
        {"John", "Doe",
            "Rowing", new Integer(3), true},
        {"Sue", "Black",
            "Knitting", new Integer(2), false},
        {"Jane", "White",
            "Speed reading", new Integer(20), true},
        {"Joe", "Brown",
            "Pool", new Integer(10), false},
        {"Kathy", "Smith",
            "Snowboarding", new Integer(5), false},
        {"John", "Doe",
            "Rowing", new Integer(3), true},
        {"Sue", "Black",
            "Knitting", new Integer(2), false},
        {"Jane", "White",
            "Speed reading", new Integer(20), true},
        {"Joe", "Brown",
            "Pool", new Integer(10), false}
    };

    public SSTableTest() {
        setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);
        setMinimumSize(new Dimension(800, 600));
        setTitle("Bugtest");
        JTable table = new JTable(data, columnNames);
        add(table);

        pack();
    }

    public static void main(String[] args) {
        java.awt.EventQueue.invokeLater(new Runnable() {

            @Override
            public void run() {
                try {
                    JFrame.setDefaultLookAndFeelDecorated(true);
                    JDialog.setDefaultLookAndFeelDecorated(true);
                    UIManager.setLookAndFeel(new SubstanceTwilightLookAndFeel());
                    test = new SSTableTest();
                    test.setVisible(true);
                } catch (UnsupportedLookAndFeelException ex) {
                    Logger.getLogger(SSTableTest.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
        });
    }
}

Right click on the table and move your mouse fast on the table rows up and down.

I'm using the latest version from everything. It's a very annoying bug, took me 3 hours to track down that it's not in my code

Thanks ~ Laxi

disrvptor commented 12 years ago

What version of Java are you using and have you tried to duplicate the performance issues using a non-Substance LAF?

laxika commented 12 years ago

Tired with J6U25 and J7U5, the results are the same.

50%+ with left click, ~30% CPU with rightclick.

Using non-substance (default) LAF is ~7-11% left, 0-4% right.

shemnon commented 12 years ago

It appears in this case that Kirill wrote the animation to occur per cell in the table, so there are up to 20 separate cells being animated at one time. You will note that the CPU spike subsudes within less than a second. It appears to be alsomst entierly consumed by repaint calls, which makes sense for this amount of animation.

If there were a client property to tell the table not to animate, or to change the max cell animation threshold (currently hard coded to 20) would that provide the needed effect? I.e. is cutting out rollover animations what you need?

shemnon commented 12 years ago

Can you try turning off the animations?

   AnimationConfigurationManager.getInstance().disallowAnimations(
           AnimationFacet.ROLLOVER, JTable.class
   );
   AnimationConfigurationManager.getInstance().disallowAnimations(
           AnimationFacet.SELECTION, JTable.class
   );

You could also replace the JTable.class with the specific instance of the component as well.

laxika commented 12 years ago

I tired to disable the animation. After disabled i got these results: selecting: 30-50%, simply moving my mouse over the table is 30%.

When animations are enabled and I move the mouse over the table and start to moving it fast without cklicking, it eats 30-40% CPU, and i don't see any animation because I moving my mouse too fast and it not start the animation (not show that the animation is started because I'm moving the cursor too fast).

It's way too much in my opinion, even if I disable the animations. My problem is that I do expensive draws on the glasspane when the user is rightclicking on the rows. (Show pictures.) Even the user moving his/her mouse slowly, then the table eats up 15-20% cpu to animate just one or two row, plus my animation eats up 10-20% CPU too, it can be a huge spike. I noticed that something was wrong when listened music on youtube and tested the right clicking animation of my program, the music just stopped for seconds sometimes (because of the huge CPU spikes). I tired to optimize on my side but it still too much even with accelerated pictures. 30-40% cpu usage when moving the mouse fast on a 10 row JTable is way too much.

Even if its not fixing the root of the problem (at least in my opinion), but adding a method to change the max animation treshold is a good idea.