1

i have a problem with the "speed" of setting up a border. i have a display with multiple JTextPane´s (around 450, what is required) which are updated quite often(depending on user input). here is the setting border function:

    private void setBorder(int top, int left, int bottom, int right, Color color)
    {
        Args.checkForNull(color);
        this.setBorder(BorderFactory.createMatteBorder(top, left, bottom, right, color));
    }

can you give me some tipps on, how to improve the speed of the border changing?? i mean this part:

this.setBorder(BorderFactory.createMatteBorder(top, left, bottom, right, color));

something like:

tmp = this.getStyledDocument();
        this.setDocument(blank);
        if(onOff){
            tmp.setParagraphAttributes(0, tmp.getLength(), underlinedAttr, false);
        }
        else{
            tmp.setParagraphAttributes(0, tmp.getLength(), notUnderlinedAttr, false);
        }

        this.setDocument(tmp);

thanks!

  • 2
    What do you mean by updating text fields (and borders) quite often? Normally it's enough to set the borders just once for each GUI component (usually at construction time). – Adam Dyga Oct 08 '12 at 08:59
  • 1
    For better help sooner, post an [SSCCE](http://sscce.org/). ..and how do you manage to cram 450 text panes into one GUI? Sounds very 'crowded'. – Andrew Thompson Oct 08 '12 at 09:03
  • that means i have to change the borders often. diffrent stuff is displayed on this areas and its needed to change the borders for a diffrent look. the changing depends on the user input. so it can happen quite often XD –  Oct 08 '12 at 09:03
  • 1
    Make sure you making a call to invalidate and repaint to encourage the UI to update – MadProgrammer Oct 08 '12 at 09:04
  • *"the changing depends on the user input. so it can happen quite often XD"* What, one change by the user changes all 450 panes, or actions by the user change each pane as the change happens to them. Now would be a good time to describe what this GUI does in non-abstract terms. E.G. 'different stuff' might be 'user chooses a new font size'. – Andrew Thompson Oct 08 '12 at 09:06
  • i have a display made out of the jtextpanes. lines(borders of the jtextpanes) seperate displayed texts. if the user changes a page or make other inputs -> the lines (borders of the jtextpanes) are getting changed. i dunno why this should be important. all i need to know is how to speed up the setborder function for rapid calls! –  Oct 08 '12 at 09:10
  • 2
    *"i dunno why this should be important."* I don't know why you can't find your shift key and a spell checker. As to why I ask these questions, it is in order to try and provide best help. Stop focusing on what you want to do and be a little more forthcoming about the 'why?' for best help. – Andrew Thompson Oct 08 '12 at 09:18
  • _i need to know is how to speed up the setborder_ that's most probably an incorrect assumption (setting border is lightning fast, normally) .. Never-ever **assume** anything performance-related, always **measure** to find a bottleneck – kleopatra Oct 08 '12 at 09:18
  • It's important, because since the code you have shown is so simple, it's hard to believe that it is a performance bottleneck in this entire "procedure". Did you make any profiling or time measurements? Are you sure that setBorder(BorderFactory.createMatteBorder() is really the bottleneck? I think the real cause of performance loss may be somewhere else. – Adam Dyga Oct 08 '12 at 09:24
  • i did. thats the reason why i say: setBorder is the problem. –  Oct 08 '12 at 09:27
  • 1
    Find out if every your `setBorder()` call leads to invoking `paint()` and for what component. Maybe all your 450 components are being repainted each time you set the border for only exact one. – Yegoshin Maxim Oct 08 '12 at 09:28
  • finally somebody who can give an advice... i´ll check this, thx –  Oct 08 '12 at 09:40
  • Unfortunately setBorder() itself calls repaint() and sometimes revalidate() so the solution may be not that simple. Maybe making the parent container invisible for the time when borders are updated could help somehow. – Adam Dyga Oct 08 '12 at 09:48
  • believe it or not, i think disabling/reanabling the pane before/after the change, helps... –  Oct 08 '12 at 09:59
  • 1
    See [my question](http://stackoverflow.com/questions/12123976/gradient-textfields-in-panel-with-titledborder-performance-issue) where I thought that the TitledBorder was causing a performance issue (and I was completely wrong) – Rempelos Oct 08 '12 at 11:31

1 Answers1

2

This runs acceptable fast for me, so your problem is unlikely to be in setBorder(). Better measure again, possible problem is you are updating the border in separate events or have a really complex layout. It might be you have a bad video card (driver), you could try to see if running with -Dsun.java2d.d3d=false works better.

import java.awt.*;
import java.awt.event.ActionEvent;
import java.util.Random;
import javax.swing.*;

public class TestBorderSpeed {
    public static void main(String[] args) {
        EventQueue.invokeLater(new Runnable() {
            @Override
            public void run() {
                int amount = 22;

                final JPanel panel = new JPanel(new GridLayout(amount, amount));
                for (int row = 0; row < amount; row++) {
                    for (int column = 0; column < amount; column++) {
                        JTextPane pane = new JTextPane();
                        pane.setText("Row " + row + "; Column " + column);
                        panel.add(pane);
                    }
                }

                JFrame frame = new JFrame("Test");
                frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
                frame.getContentPane().add(panel);
                frame.getContentPane().add(new JButton(
                  new AbstractAction("Change borders") {

                    private final Random random = new Random();
                    private final Color[] colors =
                      { Color.RED, Color.GREEN, Color.BLUE };

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        for (Component component : panel.getComponents()) {
                            ((JComponent) component).setBorder(
                              BorderFactory.createMatteBorder(
                                    random.nextInt(3) + 1, random.nextInt(3) + 1,
                                    random.nextInt(3) + 1, random.nextInt(3) + 1,
                                    colors[random.nextInt(colors.length)]));
                        }
                    }
                }), BorderLayout.PAGE_END);
                frame.pack();
                frame.setLocationRelativeTo(null);
                frame.setVisible(true);
            }
        });
    }
}
Walter Laan
  • 2,956
  • 17
  • 15
  • lol. nicely done. but i doesn´t improve the performance :( it is fast. around 0.6 sec. or so, but if the user executes the action, which changes the borders, more action are executed, also. and so the overall time is around a second in my application. all the other stuff is pretty much optimized. the last thing, is this border stuff. and i do not beleive that my grapic card is the prob, because i tested it on another pc, also. and the performance is even worth on this linux pc. thats the reason why i try to optimize that stuff, because executing it on linux takes forever –  Oct 08 '12 at 11:32
  • 2
    It takes less than 50ms on my computer. Can you show a snapshot from the VisualVM CPU sampler or profiler? – Walter Laan Oct 08 '12 at 12:36
  • i got an email, that the project got canceled -__- but thanks. –  Oct 08 '12 at 13:53