JFrame点击滤镜按钮无效果,需拖动/缩放窗口才生效的问题求助
Swing滤镜应用后图片不即时更新问题
我正在开发一个Swing GUI程序,点击对应按钮调用滤镜类,将效果应用到面板中央的图片上。但点击滤镜按钮后,图片标签(image)不会即时显示滤镜效果,只有拖动或缩放JFrame窗口后,效果才会显现。
相关代码
ActionListener核心代码
public void actionPerformed(final ActionEvent e) { if (e.getSource() == mybutton) { final EdgeDetectFilter myfilter = new EdgeDetectFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton2) { final EdgeHighlightFilter myfilter = new EdgeHighlightFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton3) { final FlipHorizontalFilter myfilter = new FlipHorizontalFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton3) { final FlipHorizontalFilter myfilter = new FlipHorizontalFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton4) { final FlipVerticalFilter myfilter = new FlipVerticalFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton5) { final GrayscaleFilter myfilter = new GrayscaleFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton6) { final SharpenFilter myfilter = new SharpenFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton7) { final SoftenFilter myfilter = new SoftenFilter(); myfilter.filter(thePic); } else if (e.getSource() == mybutton8) { final int response = this.fileChooser.showOpenDialog(null); //select file to open if (response == JFileChooser.APPROVE_OPTION) { final File file = new File(fileChooser.getSelectedFile().getPath()); try { thePic = PixelImage.load(file); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); }
打开文件按钮ActionListener补充代码
else if (e.getSource() == mybutton8) { final int response = this.fileChooser.showOpenDialog(null); //select file to open if (response == JFileChooser.APPROVE_OPTION) { final File file = new File(fileChooser.getSelectedFile().getPath()); try { thePic = PixelImage.load(file); } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } image.setIcon(new ImageIcon(thePic)); image.repaint(); myJFrame.pack(); } }
面板与图片标签初始化代码
this.centerpanel = new JPanel(); centerpanel.setLayout(new GridLayout(1,2)); image.setHorizontalAlignment(SwingConstants.CENTER); image.setVerticalAlignment(SwingConstants.CENTER); centerpanel.add(image, BorderLayout.CENTER); myJFrame.add(centerpanel, BorderLayout.CENTER); centerpanel.setPreferredSize(new Dimension(700,700));
问题原因与修复方案
问题本质是:滤镜只修改了thePic对象的像素数据,但没有通知image标签更新显示内容。打开文件时你做了image.setIcon(new ImageIcon(thePic))和image.repaint()来触发更新,但滤镜按钮的逻辑里漏掉了这一步,只有窗口重绘(拖动/缩放)时Swing才会重新渲染组件。
具体修复方法
在每个滤镜分支添加更新逻辑
给每个应用滤镜的代码块末尾加上更新图片标签的代码,比如:if (e.getSource() == mybutton) { final EdgeDetectFilter myfilter = new EdgeDetectFilter(); myfilter.filter(thePic); // 添加以下两行 image.setIcon(new ImageIcon(thePic)); image.repaint(); }所有滤镜按钮的分支都需要加上这两行代码。
抽离重复代码(可选但推荐)
为了避免代码冗余,可以把更新逻辑封装成一个方法:private void refreshImage() { image.setIcon(new ImageIcon(thePic)); image.repaint(); }之后在每个滤镜分支和打开文件成功后调用
refreshImage()即可。修正冗余代码
注意到你代码里mybutton3的判断重复了两次,建议删除其中一个重复分支,避免逻辑混乱。
内容的提问来源于stack exchange,提问作者Maliha Hossain
相关产品推荐
相关产品推荐

