清除 Swing GUI 中的 ImageIcon 和相关操作
我正在尝试向基本 SUN (Oracle) Java Swing ImageIcon 库演示添加 Web URL 启动功能: http://docs.oracle.com/javase/tutorial/uiswing /components/icon.html#example
要求 目的是创建一个 Swing GUI Web 链接启动器,该启动器能够使用 JRE 1.6+ 桌面 API 启动器功能通过用户的默认 Web 浏览器启动链接,并根据上次单击的图像打开不同的 URL。
问题 我似乎遇到的问题是,每次在 ThumbnailAction 构造函数中创建一个新的 ImageIcon 时,它似乎并没有破坏以前的图像,而是简单地在它上面绘制。不需要的副作用是旧图像的 MouseListeners 和元数据仍然处于活动状态,因此尝试单击启动 URL 实际上会加载先前加载的图像的 URL 以及当前焦点图像的 URL。如果您查看控制台打印日志,您还可以看到 MouseEntered 和 Exited 多次触发,对于到目前为止已交换的每个图像一次。因此,如果用户进行 3 或 4 次交换,他们将启动那么多 URL。达不到想要的效果。
如果有人知道问题是什么,我们将不胜感激,这是我对“IconDemoApp.java” 文件(2012 年 1 月 31 日更新):
/*
* Copyright (c) 1995, 2008, Oracle and/or its affiliates. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* - Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
*
* - Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* - Neither the name of Oracle or the names of its
* contributors may be used to endorse or promote products derived
* from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
* IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
* LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package components;
import java.awt.BasicStroke;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Component;
import java.awt.Desktop;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.RenderingHints;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.Box;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JToolBar;
import javax.swing.SwingUtilities;
import javax.swing.SwingWorker;
/**
* This application is intended to demonstrate the loading of image files into icons
* for use in a Swing user interface. It creates a toolbar with a thumbnail preview
* of each image. Clicking on the thumbnail will show the full image
* in the main display area.
*
* IconDemoApp.java requires the following files: <br>
* The following files are copyright 2006 spriggs.net and licensed under a
* Creative Commons License (http://creativecommons.org/licenses/by-sa/3.0/)
* <br>
* images/sunw01.jpg <br>
* images/sunw02.jpg <br>
* images/sunw03.jpg <br>
* images/sunw04.jpg <br>
* images/sunw05.jpg <br>
*
* @author Collin Fagan
* @date 7/25/2007
* @version 2.0
*/
public class IconDemoApp extends JFrame {
/**
* Main entry point to the demo. Loads the Swing elements on the "Event
* Dispatch Thread".
*
* @param args
*/
public static void main(String args[]) {
SwingUtilities.invokeLater(new Runnable() {
public void run() {
IconDemoApp app = new IconDemoApp();
app.setVisible(true);
}
});
}
/*
* MissingIcon
* Internal class for how to recover from missing icons.
* (displays empty image placeholder with red X and white background)
*/
class MissingIcon implements Icon {
private int width = 32;
private int height = 32;
private BasicStroke stroke = new BasicStroke(4);
public void paintIcon(Component c, Graphics g, int x, int y) {
Graphics2D g2d = (Graphics2D) g.create();
g2d.setColor(Color.WHITE);
g2d.fillRect(x +1 ,y + 1,width -2 ,height -2);
g2d.setColor(Color.BLACK);
g2d.drawRect(x +1 ,y + 1,width -2 ,height -2);
g2d.setColor(Color.RED);
g2d.setStroke(stroke);
g2d.drawLine(x +10, y + 10, x + width -10, y + height -10);
g2d.drawLine(x +10, y + height -10, x + width -10, y + 10);
g2d.dispose();
}
public int getIconWidth() {
return width;
}
public int getIconHeight() {
return height;
}
}
/**
* Default constructor for the demo.
*/
public IconDemoApp() {
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
setTitle("Icon Demo: Please Select an Image");
// A label for displaying the pictures
photographLabel.setVerticalTextPosition(JLabel.BOTTOM);
photographLabel.setHorizontalTextPosition(JLabel.CENTER);
photographLabel.setHorizontalAlignment(JLabel.CENTER);
photographLabel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
// We add two glue components. Later in process() we will add thumbnail buttons
// to the toolbar inbetween thease glue compoents. This will center the
// buttons in the toolbar.
buttonBar.add(Box.createGlue());
buttonBar.add(Box.createGlue());
add(buttonBar, BorderLayout.SOUTH);
add(photographLabel, BorderLayout.CENTER);
setSize(400, 300);
// this centers the frame on the screen
setLocationRelativeTo(null);
// start the image loading SwingWorker in a background thread
loadimages.execute();
}
/**
* SwingWorker class that loads the images a background thread and calls publish
* when a new one is ready to be displayed.
*
* We use Void as the first SwingWroker param as we do not need to return
* anything from doInBackground().
*/
private SwingWorker<Void, ThumbnailAction> loadimages = new SwingWorker<Void, ThumbnailAction>() {
/**
* Creates full size and thumbnail versions of the target image files.
*/
@Override
protected Void doInBackground() throws Exception {
for (int i = 0; i < titles.length; i++) {
ImageIcon icon;
icon = createImageIcon(imagedir + thumbs[i], titles[i]);
ThumbnailAction thumbAction;
if(icon != null){
ImageIcon thumbnailIcon = new ImageIcon(getScaledImage(icon.getImage(), 32, 32));
thumbAction = new ThumbnailAction(icon, thumbnailIcon, titles[i], descs[i], links[i]);
}else{
// the image failed to load for some reason
// so load a placeholder instead
thumbAction = new ThumbnailAction(placeholderIcon, placeholderIcon, titles[i], descs[i], links[i]);
}
publish(thumbAction);
}
// unfortunately we must return something, and only null is valid to
// return when the return type is void.
return null;
}
/**
* Process all loaded images.
*/
@Override
protected void process(List<ThumbnailAction> chunks) {
for (ThumbnailAction thumbAction : chunks) {
JButton thumbButton = new JButton(thumbAction);
// add the new button BEFORE the last glue
// this centers the buttons in the toolbar
buttonBar.add(thumbButton, buttonBar.getComponentCount() - 1);
}
}
};
/**
* Creates an ImageIcon if the path is valid.
* @param String - resource path
* @param String - description of the file
*/
protected ImageIcon createImageIcon(String path, String description) {
java.net.URL imgURL = getClass().getResource(path);
if (imgURL != null) {
return new ImageIcon(imgURL, description);
}
else {
System.err.println("Couldn't find file: " + path);
return null;
}
}
/**
* Resizes an image using a Graphics2D object backed by a BufferedImage.
* @param srcImg - source image to scale
* @param w - desired width
* @param h - desired height
* @return - the new resized image
*/
private Image getScaledImage(Image srcImg, int w, int h) {
BufferedImage resizedImg = new BufferedImage(w, h, BufferedImage.TYPE_INT_RGB);
Graphics2D g2 = resizedImg.createGraphics();
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2.drawImage(srcImg, 0, 0, w, h, null);
g2.dispose();
return resizedImg;
}
/**
* Action class that shows the image specified in it's constructor.
*/
private class ThumbnailAction extends AbstractAction implements MouseListener {
private Icon displayPhoto; // The icon if the full image we want to display.
/**
* @param Icon - The full size photo to show in the button.
* @param Icon - The thumbnail to show in the button.
* @param String - The descriptioon of the icon.
*/
public ThumbnailAction(Icon photo, Icon thumb, String title, String desc, String link) {
displayPhoto = photo;
// The short description becomes the title of the window.
putValue(SHORT_DESCRIPTION, title);
// The long description becomes the tooltip of a button.
putValue(LONG_DESCRIPTION, desc);
// The DEFAULT action on click is to launch this URL
putValue(DEFAULT, link);
// The LARGE_ICON_KEY is the key for setting the icon when an Action is applied to a button.
putValue(LARGE_ICON_KEY, thumb);
}
/**
* Shows the full image in the main area and sets the application title.
*/
public void actionPerformed(ActionEvent e) {
photographLabel.setIcon(displayPhoto);
setTitle("Icon Demo - " + getValue(SHORT_DESCRIPTION).toString());
photographLabel.setToolTipText("<html>" + getValue(LONG_DESCRIPTION) + "</html>");
photographLabel.validate();
photographLabel.updateUI();
photographLabel.repaint();
photographLabel.addMouseListener(this);
}
/**
* Listen for clicks to send user to a URL or launch an application
* @param e
*/
@Override
public void mouseClicked(MouseEvent e) {
int clicked = e.getClickCount();
if (clicked > 0) {
/*************************************/
/* Code for launching Browser BEGIN */
Desktop desktop = null;
if (Desktop.isDesktopSupported()) {
desktop = Desktop.getDesktop();
}
URI uri = null;
try {
uri = new URI((String)this.getValue(DEFAULT)); //pass the URL from ImageIcon to Browser
if (desktop.isSupported(Desktop.Action.BROWSE)) {
desktop.browse(uri); //url passed
}
else {
System.out.println("Unable to open default browser to: "+uri);
}
}
catch(IOException ioe) {
ioe.printStackTrace();
}
catch(URISyntaxException use) {
use.printStackTrace();
}
/* Code for launching Browser END */
/*************************************/
}
else {
System.out.println("Clicked: " + clicked);
}
}
@Override
public void mousePressed(MouseEvent e) {
System.out.println("Mouse pressed (# of clicks: " + e.getClickCount() + ") " + e);
}
@Override
public void mouseReleased(MouseEvent e) {
System.out.println("Mouse released (# of clicks: " + e.getClickCount() + ") " + e);
}
@Override
public void mouseEntered(MouseEvent e) {
System.out.println("Mouse entered: " + e);
}
@Override
public void mouseExited(MouseEvent e) {
System.out.println("Mouse exited: " + e);
}
}
private JLabel photographLabel = new JLabel();
private JToolBar buttonBar = new JToolBar();
private String imagedir = "images/";
private MissingIcon placeholderIcon = new MissingIcon();
// List of all the image files to load.
private String[] thumbs = { "sunw01.jpg", "sunw02.jpg", "sunw03.jpg", "sunw04.jpg", "sunw05.jpg"};
// List of all the descriptions of the image files. These correspond one to one with the image file names
private String[] titles = { "SunLogo", "Clocktower", "ClocktowerWest", "Mansion", "SunAuditorium" };
// List of all descriptions (descs) to use as tooltips.
private String[] descs = { "The Original SUNW Logo", "The Clocktower frontal view", "The Clocktower from the West", "The Mansion on the hill!", "The infamouse Sun campus auditorium"};
// List of all links to send a user to on click action.
private String[] links = { "http://example.com/#1", "http://example.com/#2", "http://example.com/#3", "http://example.com/#4", "http://example.com/#5"};
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
设置图像不是问题。但是,当执行操作时,您将一个 MouseListener 添加到在第 267 行中永远不会删除的 PhotographLabel。此示例的一个简单技巧是在添加新侦听器之前删除所有已注册的侦听器:
现在一切都按方面工作。
Setting the Image is not the problem. But when a Action is performed you add a MouseListener to the photographLabel that you never remove in line 267. A simple hack for this example is to remove all registered Listeners before adding the new one:
Now everything works as aspected.
1) 我无法生成您的问题,因为此描述可以讨论 un_healt GPU 驱动程序
2) 但您可以通过从最快的绘画中减少次要问题来测试它,使用缓冲区中的flush(),并且以下步骤可能会帮助您
创建图标
将
Icon
放到 JLabel1) I can't generating your issue, because this descriptions is can talking about un_healt GPU drivers
2) but you can test that by reducing secondary issue from quickiest painting use flush() from Buffer, and following steps may help you
create Icon
put
Icon
to the JLabel