Browse Source

(Almost) Generic background image painter

Change-Id: I5daa7330e62f3d3c04d2c3250ecf3ac2ca9320b3
Reviewed-on: http://gerrit.dmdirc.com/2461
Reviewed-by: Chris Smith <chris@dmdirc.com>
Automatic-Compile: DMDirc Build Manager
tags/0.7rc1
Greg Holmes 12 years ago
parent
commit
b1fb7f5ef8

+ 1
- 0
src/com/dmdirc/addons/ui_swing/components/frames/TextFrame.java View File

@@ -544,6 +544,7 @@ public abstract class TextFrame extends JPanel implements Window,
544 544
     @Override
545 545
     public void windowClosing(final FrameContainer window) {
546 546
         setVisible(false);
547
+        getTextPane().close();
547 548
     }
548 549
 
549 550
     /** {@inheritDoc} */

+ 0
- 86
src/com/dmdirc/addons/ui_swing/textpane/BackgroundImageLoader.java View File

@@ -1,86 +0,0 @@
1
-/*
2
- * Copyright (c) 2006-2012 DMDirc Developers
3
- *
4
- * Permission is hereby granted, free of charge, to any person obtaining a copy
5
- * of this software and associated documentation files (the "Software"), to deal
6
- * in the Software without restriction, including without limitation the rights
7
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
- * copies of the Software, and to permit persons to whom the Software is
9
- * furnished to do so, subject to the following conditions:
10
- *
11
- * The above copyright notice and this permission notice shall be included in
12
- * all copies or substantial portions of the Software.
13
- *
14
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
20
- * SOFTWARE.
21
- */
22
-
23
-package com.dmdirc.addons.ui_swing.textpane;
24
-
25
-import com.dmdirc.addons.ui_swing.components.LoggingSwingWorker;
26
-import com.dmdirc.logger.ErrorLevel;
27
-import com.dmdirc.logger.Logger;
28
-
29
-import java.awt.Image;
30
-import java.io.IOException;
31
-import java.net.URL;
32
-import java.util.concurrent.ExecutionException;
33
-
34
-import javax.imageio.ImageIO;
35
-
36
-/**
37
- * Loads a background image in the background.
38
- */
39
-class BackgroundImageLoader extends LoggingSwingWorker<Image, Void> {
40
-
41
-    /** URL of image file to load. */
42
-    private final URL imageURL;
43
-    /** Textpane canvas to load image for. */
44
-    private final TextPaneCanvas canvas;
45
-
46
-    /**
47
-     * Creates a new background image loader.
48
-     *
49
-     * @param canvas Canvas we're loading image for
50
-     * @param url URL of image to load
51
-     */
52
-    protected BackgroundImageLoader(final TextPaneCanvas canvas,
53
-            final URL url) {
54
-        super();
55
-        imageURL = url;
56
-        this.canvas = canvas;
57
-    }
58
-
59
-    /** {@inheritDoc} */
60
-    @Override
61
-    protected Image doInBackground() {
62
-        try {
63
-            if (imageURL != null) {
64
-                return ImageIO.read(imageURL);
65
-            }
66
-            return null;
67
-        } catch (IOException ex) {
68
-            return null;
69
-        }
70
-    }
71
-
72
-    /** {@inheritDoc} */
73
-    @Override
74
-    protected void done() {
75
-        if (isCancelled()) {
76
-            return;
77
-        }
78
-        try {
79
-            canvas.setBackgroundImage(get());
80
-        } catch (InterruptedException ex) {
81
-            canvas.setBackgroundImage(null);
82
-        } catch (ExecutionException ex) {
83
-            Logger.appError(ErrorLevel.MEDIUM, ex.getMessage(), ex);
84
-        }
85
-    }
86
-}

+ 208
- 0
src/com/dmdirc/addons/ui_swing/textpane/BackgroundPainter.java View File

@@ -0,0 +1,208 @@
1
+/*
2
+ * Copyright (c) 2006-2012 DMDirc Developers
3
+ *
4
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ * of this software and associated documentation files (the "Software"), to deal
6
+ * in the Software without restriction, including without limitation the rights
7
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ * copies of the Software, and to permit persons to whom the Software is
9
+ * furnished to do so, subject to the following conditions:
10
+ *
11
+ * The above copyright notice and this permission notice shall be included in
12
+ * all copies or substantial portions of the Software.
13
+ *
14
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ * THE SOFTWARE.
21
+ */
22
+
23
+package com.dmdirc.addons.ui_swing.textpane;
24
+
25
+import com.dmdirc.addons.ui_swing.BackgroundOption;
26
+import com.dmdirc.addons.ui_swing.UIUtilities;
27
+import com.dmdirc.addons.ui_swing.components.LoggingSwingWorker;
28
+import com.dmdirc.config.ConfigBinding;
29
+import com.dmdirc.config.ConfigManager;
30
+import com.dmdirc.util.URLBuilder;
31
+
32
+import java.awt.Graphics;
33
+import java.awt.Graphics2D;
34
+import java.awt.Image;
35
+import java.io.IOException;
36
+import java.net.URL;
37
+import java.util.concurrent.ExecutionException;
38
+
39
+import javax.imageio.ImageIO;
40
+import javax.swing.JComponent;
41
+
42
+import lombok.AccessLevel;
43
+import lombok.AllArgsConstructor;
44
+import lombok.Getter;
45
+import lombok.NonNull;
46
+import lombok.extern.slf4j.Slf4j;
47
+
48
+import org.jdesktop.jxlayer.plaf.LayerUI;
49
+
50
+/**
51
+ * Background painting layer UI. Paints a opaque background then paints the
52
+ * specified image onto the background layer.
53
+ */
54
+@Slf4j
55
+@SuppressWarnings("unused")
56
+public class BackgroundPainter extends LayerUI<JComponent> {
57
+
58
+    /**
59
+     * Domain to retrieve settings from.
60
+     */
61
+    @Getter(value = AccessLevel.PROTECTED)
62
+    @NonNull
63
+    private final String domain;
64
+
65
+    /**
66
+     * Key in domain to get image URL from.
67
+     */
68
+    @NonNull
69
+    @Getter(value = AccessLevel.PROTECTED)
70
+    private final String imageKey;
71
+
72
+    /**
73
+     * Key in domain to get image background type from.
74
+     */
75
+    @NonNull
76
+    @Getter(value = AccessLevel.PROTECTED)
77
+    private final String optionKey;
78
+
79
+    /**
80
+     * Config manager to bind to and retrieve settings from.
81
+     */
82
+    private final ConfigManager configManager;
83
+
84
+    /**
85
+     * Background image.
86
+     */
87
+    private Image backgroundImage;
88
+
89
+    /**
90
+     * Background option type.
91
+     */
92
+    private BackgroundOption backgroundOption;
93
+
94
+    /**
95
+     * Creates a new background painter.
96
+     *
97
+     * @param configManager Config manager to retrieve settings from
98
+     * @param domain Domain to retrieve settings from
99
+     * @param imageKey Key for background image
100
+     * @param optionKey Key for background type
101
+     */
102
+    public BackgroundPainter(final ConfigManager configManager,
103
+            final String domain, final String imageKey,
104
+            final String optionKey) {
105
+        this.configManager = configManager;
106
+        this.domain = domain;
107
+        this.imageKey = imageKey;
108
+        this.optionKey = optionKey;
109
+        configManager.getBinder().bind(this, BackgroundPainter.class);
110
+    }
111
+
112
+    /**
113
+     * Called to update the value of the image URL.
114
+     *
115
+     * @param value New image URL
116
+     */
117
+    @ConfigBinding(domain = "plugin-ui_swing", key = "textpanebackground")
118
+    public void updateImage(final String value) {
119
+        if (value == null || value.isEmpty()) {
120
+            backgroundImage = null;
121
+        } else {
122
+            new ImageLoader(URLBuilder.buildURL(value)).executeInExecutor();
123
+        }
124
+    }
125
+
126
+    /**
127
+     * Called to update the value of the background type
128
+     *
129
+     * @param value New background type
130
+     */
131
+    @ConfigBinding(domain = "plugin-ui_swing", key = "textpanebackgroundoption")
132
+    public void updateOption(final String value) {
133
+        try {
134
+            backgroundOption = BackgroundOption.valueOf(value);
135
+        } catch (IllegalArgumentException ex) {
136
+            backgroundOption = BackgroundOption.CENTER;
137
+        }
138
+    }
139
+
140
+    /**
141
+     * {@inheritDoc}
142
+     */
143
+    @Override
144
+    public void paint(final Graphics graphics, final JComponent component) {
145
+        final Graphics2D g2 = (Graphics2D) graphics;
146
+        g2.setColor(component.getBackground());
147
+        g2.fill(g2.getClipBounds());
148
+        UIUtilities.paintBackground(g2, component.getBounds(),
149
+                backgroundImage, backgroundOption);
150
+        super.paint(graphics, component);
151
+    }
152
+
153
+    /**
154
+     * Called to unbind this painter from its config binder.
155
+     */
156
+    public void unbind() {
157
+        configManager.getBinder().unbind(this);
158
+    }
159
+
160
+    /**
161
+     * Loads image URLs in the background.
162
+     */
163
+    @AllArgsConstructor
164
+    private class ImageLoader extends LoggingSwingWorker<Image, Void> {
165
+
166
+        /**
167
+         * URL of image file to load.
168
+         */
169
+        private final URL imageURL;
170
+
171
+        /**
172
+         * {@inheritDoc}
173
+         */
174
+        @Override
175
+        protected Image doInBackground() {
176
+            try {
177
+                log.trace("Loading image: {}", imageURL);
178
+                if (imageURL != null) {
179
+                    return ImageIO.read(imageURL);
180
+                }
181
+                return null;
182
+            } catch (IOException ex) {
183
+                log.trace("Background loading IOException: {}", ex.getMessage());
184
+                return null;
185
+            }
186
+        }
187
+
188
+        /**
189
+         * {@inheritDoc}
190
+         */
191
+        @Override
192
+        protected void done() {
193
+            try {
194
+                if (isCancelled()) {
195
+                    log.trace("Background loading cancelled.");
196
+                    return;
197
+                }
198
+                log.trace("Background loading complete: {}", get());
199
+                backgroundImage = get();
200
+            } catch (InterruptedException ex) {
201
+                log.debug("Interrupted whilst loading image: {}", imageURL);
202
+            } catch (ExecutionException ex) {
203
+                log.debug("Exception whilst loading image: {}. "
204
+                        + "Exception message:", imageURL, ex.getMessage());
205
+            }
206
+        }
207
+    }
208
+}

+ 17
- 1
src/com/dmdirc/addons/ui_swing/textpane/TextPane.java View File

@@ -52,6 +52,8 @@ import javax.swing.SwingConstants;
52 52
 
53 53
 import net.miginfocom.swing.MigLayout;
54 54
 
55
+import org.jdesktop.jxlayer.JXLayer;
56
+
55 57
 /**
56 58
  * Styled, scrollable text pane.
57 59
  */
@@ -74,6 +76,8 @@ public final class TextPane extends JComponent implements MouseWheelListener,
74 76
     private final Window frame;
75 77
     /** Indicator to show whether new lines have been added. */
76 78
     private final JLabel newLineIndicator;
79
+    /** Background painter. */
80
+    private final BackgroundPainter backgroundPainter;
77 81
     /** Last seen line. */
78 82
     private int lastSeenLine = 0;
79 83
     /** Show new line notifications. */
@@ -98,8 +102,13 @@ public final class TextPane extends JComponent implements MouseWheelListener,
98 102
         newLineIndicator.setVisible(false);
99 103
 
100 104
         setLayout(new MigLayout("fill, hidemode 3"));
105
+        backgroundPainter = new BackgroundPainter(frame.getContainer()
106
+                .getConfigManager(), "plugin-ui_swing", "textpanebackground",
107
+                "textpanebackgroundoption");
101 108
         canvas = new TextPaneCanvas(this, document);
102
-        add(canvas, "dock center");
109
+        final JXLayer<JComponent> layer = new JXLayer<JComponent>(canvas);
110
+        layer.setUI(backgroundPainter);
111
+        add(layer, "dock center");
103 112
         add(newLineIndicator, "dock south, center, grow");
104 113
         scrollModel = new TextPaneBoundedRangeModel();
105 114
         scrollModel.setExtent(0);
@@ -574,4 +583,11 @@ public final class TextPane extends JComponent implements MouseWheelListener,
574 583
             });
575 584
         }
576 585
     }
586
+
587
+    /**
588
+     * Called to close this textpane and any associated resources.
589
+     */
590
+    public void close() {
591
+        backgroundPainter.unbind();
592
+    }
577 593
 }

+ 0
- 42
src/com/dmdirc/addons/ui_swing/textpane/TextPaneCanvas.java View File

@@ -22,21 +22,17 @@
22 22
 
23 23
 package com.dmdirc.addons.ui_swing.textpane;
24 24
 
25
-import com.dmdirc.addons.ui_swing.BackgroundOption;
26 25
 import com.dmdirc.addons.ui_swing.UIUtilities;
27
-import com.dmdirc.addons.ui_swing.components.frames.TextFrame;
28 26
 import com.dmdirc.config.ConfigManager;
29 27
 import com.dmdirc.interfaces.ConfigChangeListener;
30 28
 import com.dmdirc.ui.messages.IRCDocument;
31 29
 import com.dmdirc.ui.messages.IRCTextAttribute;
32 30
 import com.dmdirc.ui.messages.LinePosition;
33 31
 import com.dmdirc.util.collections.ListenerList;
34
-import com.dmdirc.util.URLBuilder;
35 32
 
36 33
 import java.awt.Cursor;
37 34
 import java.awt.Graphics;
38 35
 import java.awt.Graphics2D;
39
-import java.awt.Image;
40 36
 import java.awt.Point;
41 37
 import java.awt.Rectangle;
42 38
 import java.awt.Shape;
@@ -94,14 +90,8 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
94 90
     private int firstVisibleLine;
95 91
     /** Last visible line (from the top). */
96 92
     private int lastVisibleLine;
97
-    /** Background image. */
98
-    private Image backgroundImage;
99 93
     /** Config Manager. */
100 94
     private final ConfigManager manager;
101
-    /** Config domain. */
102
-    private final String domain;
103
-    /** Background image option. */
104
-    private BackgroundOption backgroundOption;
105 95
     /** Quick copy? */
106 96
     private boolean quickCopy;
107 97
     /** Mouse click listeners. */
@@ -118,8 +108,6 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
118 108
         this.document = document;
119 109
         textPane = parent;
120 110
         this.manager = parent.getWindow().getContainer().getConfigManager();
121
-        this.domain = ((TextFrame) parent.getWindow()).getController().
122
-                getDomain();
123 111
         startLine = 0;
124 112
         setDoubleBuffered(true);
125 113
         setOpaque(true);
@@ -129,8 +117,6 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
129 117
         addMouseListener(this);
130 118
         addMouseMotionListener(this);
131 119
         addComponentListener(this);
132
-        manager.addChangeListener(domain, "textpanebackground", this);
133
-        manager.addChangeListener(domain, "textpanebackgroundoption", this);
134 120
         manager.addChangeListener("ui", "quickCopy", this);
135 121
 
136 122
         updateCachedSettings();
@@ -150,10 +136,6 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
150 136
         if (desktopHints != null) {
151 137
             g.addRenderingHints(desktopHints);
152 138
         }
153
-        g.setColor(textPane.getBackground());
154
-        g.fill(g.getClipBounds());
155
-        UIUtilities.paintBackground(g, getBounds(), backgroundImage,
156
-                backgroundOption);
157 139
         paintOntoGraphics(g);
158 140
     }
159 141
 
@@ -170,20 +152,6 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
170 152
      * Updates cached config settings.
171 153
      */
172 154
     private void updateCachedSettings() {
173
-        final String backgroundPath = manager.getOption(domain,
174
-                "textpanebackground");
175
-        if (backgroundPath.isEmpty()) {
176
-            backgroundImage = null;
177
-        } else {
178
-            new BackgroundImageLoader(TextPaneCanvas.this,
179
-                    URLBuilder.buildURL(backgroundPath)).executeInExecutor();
180
-        }
181
-        try {
182
-            backgroundOption = BackgroundOption.valueOf(manager.getOption(
183
-                    domain, "textpanebackgroundoption"));
184
-        } catch (IllegalArgumentException ex) {
185
-            backgroundOption = BackgroundOption.CENTER;
186
-        }
187 155
         quickCopy = manager.getOptionBool("ui", "quickCopy");
188 156
         UIUtilities.invokeLater(new Runnable() {
189 157
 
@@ -1092,14 +1060,4 @@ class TextPaneCanvas extends JPanel implements MouseInputListener,
1092 1060
     public void removeTextPaneListener(final TextPaneListener listener) {
1093 1061
         listeners.remove(TextPaneListener.class, listener);
1094 1062
     }
1095
-
1096
-    /**
1097
-     * Sets the background image for this canvas.
1098
-     *
1099
-     * @param image Background image
1100
-     */
1101
-    protected void setBackgroundImage(final Image image) {
1102
-        backgroundImage = image;
1103
-        recalc();
1104
-    }
1105 1063
 }

Loading…
Cancel
Save